Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

Request - option to disable SpecialRebuild in OnEnable

A topic by Scarlet String Studios created Dec 04, 2023 Views: 222 Replies: 8
Viewing posts 1 to 9

Hey - still continuing my optimization journey for consoles. I've noticed that I'm getting a lot of redundant calls to Rebuild, some of which can probably be avoided with a bool to determine whether Rebuild should be called in SuperTextMesh's OnEnable.

For example, I have a localization helper script that disables the "allow hyphens" tick box for Chinese/Japanese and re-enables it for other languages. It also applies changes like per-language font sizes (to help with sizing UI text). My localization helper performs those checks in OnEnable, and then it calls Rebuild at the end of that. But, oftentimes STM will have already called Rebuild in its own OnEnable, resulting in an extra call.

Do you think it's possible/reasonable to add a toggle for this? It seems like it could work as a simple bool, so you could toggle it by code if you're planning to manually call Rebuild that frame. However, I didn't look too closely at what SpecialRebuild does, so let me know if this is a bad idea.

Developer (1 edit)

Yeah that's reasonable! I think SpecialRebuild was just an extra call I did to differentiate it from Rebuild in certain circumstances recently.

But... Would it be possible for you to do your own code, then enable SuperTextMesh after so it just naturally calls rebuild anyway? Would that work in this scenario?

All right, good to hear. Yeah, looking at SpecialRebuild, I think it just called the main Rebuild in certain situations.

But... Would it be possible for you to do your own code, then enable SuperTextMesh after so it just naturally calls rebuild anyway? Would that work in this scenario?

Well... sort of, but it wouldn't work too well. E.g. in the scenario in my first post, the localization helper is actually on the STM object. So, my own code would be executing in OnEnable alongside STM's OnEnable, and the only workaround would be to fiddle with Script Execution Order. In this example, it would make more sense to just tick a box in the editor to say "don't auto-rebuild on enable," kinda like how there's a bool for remember read position and auto-read.

Developer

Would it be possible to run your localization help through STM's OnPreParse() event? I can still add this as a bool but things like localization tools are great for the preparse event, imo!

Ah, that's a good idea. Haven't experimented with PreParse before, so I'll take a look at that.

There could be other problems - e.g. in one situation, I was enabling and modifying an STM and rebuilding it at read position 0 and without autoread, so I could manually read it at a later frame.

I was able to work around that by not calling Rebuild myself, setting currentReadTime and autoRead separately, and allowing it to rebuild on enable. It worked in this case, but the downside is that I would be committing to setting autoRead to false, which may or may not be what I intended.

Generally, I think I was able to work around the situations that came up for this specific scene, but it feels like it could become awkward quite easily.

Poking around a bit more, I noticed a couple of related issues:

  • In Unity's built-in Localization package, the LocalizeStringEvent component updates its target string in OnEnable. That's another case where we're expecting the string to be rebuilt by an external source anyway, so we wouldn't need to double-rebuild it in STM's OnEnable.
  • If you use STMs in a vertical/horizontal layout group and check with the deep profiler, there are actually several calls to Rebuild whenever the layout group updates (e.g. LayoutGroup.SetChildAlongAxisWithScale will update the RectTransform's sizeDelta, anchorMin, and anchorMax, all of which are causing STM to rebuild).
    • Perhaps there's some way to delay the rebuild until after the canvases have updated? Not sure if that would affect some canvas calculations.
  • This might be more relevant to the other thread about SetMesh, but do you think it would be efficient to have UpdateMesh take masking into account? I think all of the active STMs with a gradient effect are being updated every frame, even when some are hidden by a parent's Mask component.
Developer

I'll see what I can do! I guess I can see some use for disabling the automatic rebuild, now.

Hmm that's probably being called by OnRectTransformChanged()... I think Unity UI tends to call that a lot, but I'll see if something can be done...?

I just pushed an update to STM last night that adds natural masking support with a "Universal" shader, and added it to the UI shaders, too. But I'm not sure if it's possible to tell when a certain effect is hidden by a mask? My rule with STM is... I don't want it to become more or less efficient as text is reading out. So instead of disabling code that updates gradients when those gradients are hidden... the gradients should just be more efficient in the first place.

Developer

Hey, going through my checklist, did I ever fix this? It looks like STM calls Rebuild with OnRectTransformDimensionsChange() instead of Update() and a manual check now, so is the event still being fired constantly? I could probably add another check to make sure STM *actually* needs to update at this point...?

Hmm, I actually can't remember, to be honest. I know that I'm not having performance issues right now, but I can't remember how exactly I worked around it (or if the workaround was really necessary in the end).