Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags

Scarlet String Studios

231
Posts
30
Topics
365
Followers
77
Following
A member registered Oct 13, 2015 · View creator page →

Creator of

Recent community posts

Hey! Sure, that works.

Yeah, I switched it back to <d=99999> and it was working correctly, so I'll probably just leave it as-is instead of risking other bugs by changing things. So I guess this is more of a heads up that the string conversion for Infinity doesn't seem to be working.

Hey, does this still work in 1.13.2? I'm getting the following error when the game tries to read a line with a <t=Infinity>:

Converting invalid MinMaxAABB
UnityEngine.Mesh:SetTriangles (System.Collections.Generic.List`1<int>,int)
SuperTextMesh:SetMesh (single,bool) (at Assets/Plugins/Clavian/SuperTextMesh/Scripts/SuperTextMesh.cs:5424)
SuperTextMesh:SetMesh (single) (at Assets/Plugins/Clavian/SuperTextMesh/Scripts/SuperTextMesh.cs:5362)
SuperTextMesh/<ReadOutText>d__283:MoveNext () (at Assets/Plugins/Clavian/SuperTextMesh/Scripts/SuperTextMesh.cs:2074)
UnityEngine.MonoBehaviour:StartCoroutine (System.Collections.IEnumerator)
SuperTextMesh:Read (single) (at Assets/Plugins/Clavian/SuperTextMesh/Scripts/SuperTextMesh.cs:1858)
SuperTextMesh:Rebuild (single,bool,bool) (at Assets/Plugins/Clavian/SuperTextMesh/Scripts/SuperTextMesh.cs:1723)
SuperTextMesh:SpecialRebuild () (at Assets/Plugins/Clavian/SuperTextMesh/Scripts/SuperTextMesh.cs:1417)
SuperTextMesh:Update () (at Assets/Plugins/Clavian/SuperTextMesh/Scripts/SuperTextMesh.cs:1780)

I won't be able to update to a new version of STM at this point, so I'll have to just use <d=99999> for now. But, let me know if this is a known bug and/or if it's something that can be fixed without changing the whole rebuild process (I worry that the latter would introduce unexpected bugs).

Sure, let me know when you take a look at it. For now, our hacky solution is to just add manual linebreaks for certain situations. Not sure how many of these are in the game, but this is the first one I've found so far, so it might be possible for us to just manually avoid this situation in the meantime.

Hmm... I had a look at that part of the code, but the solution might be more complex. Here's how it looks for me:



We can see that the problem is at the 「愛の力」 line, but it's unclear why the line didn't break at the end of the sentence, at the しかし、愛 part. Even if there's a rule saying that a linebreak can't occur at a 「 or 」, the end of the line should be unaffected by that, if I'm not mistaken.

Hey - all right, thanks for the update.

Yeah, the phone interface works okay in English (the most that it can spill over is just one char). It's a bigger problem in Japanese though, because the 「 chars seem to be unpredictably breaking the word-wrapping. It still renders okay in this specific situation (the text is center-aligned, and I guess there's more padding than normal), but it sometimes spills over by more than a char, so it isn't necessarily fixable by adding more padding.

Just checking in - do you think you can look at it this week?

I might have to copy-paste the solution into the scripts rather than installing the update, just to avoid introducing other bugs. I'm getting close to wrapping things up with this game, so I'm trying to be extra-careful with updating things now.

Hmm, interesting. I can see why you might want to count the event as a character, since it's technically something else that has to execute after the string is completed. The </w> itself probably shouldn't count as a character, but as you said, it was a workaround anyway.

Actually, another workaround would probably be to just omit the </w>, because it's unnecessary if the string is ending there anyway. I'll do that manually on my end (this situation only occurs once); not sure if this would be doable within STM itself. But yeah, event execution can be finnicky, and that does sound like it would be a hard change to make without testing some things first.

(1 edit)

Hey - just found a very obscure bug while trying to sync two STMs.

Try creating a STM with a read delay of 0.1 and with the following text:

This is a <w>test

I'm getting a totalReadTime of 1.4 for this line. (The specific number might vary based on auto-delays).

Now try again with this:

This is a <w>test</w>

I'm getting a totalReadTime of 1.5 for this one, even though the rendered text hasn't changed.

(2 edits)

Actually, I'm not sure if this is the same issue, but it looks like word wrapping in Japanese doesn't work too well when Break Text is turned off. You can try it with the following block:

この世界のゲームマスターである我でさえ、<c=binary><w=superglitch>彼を止める力はない。<c=binary><w=superglitch>彼は、憎しみで成長し、愛をも糧とする、不正なAIだ。

<c=binary><w=superglitch>彼を止められる唯一の武器は無関心だ。しかし、現時点では、己が彼に無関心になることは不可能だと……本物のカメロンに対しては。

<c=binary><w=superglitch>カメロンは、<c=highsatrgb>gekka_senninの最も野心的な夢をもはるかに超える存在に成長した。「パンドラの砂場」には、<c=binary><w=superglitch>彼を倒すのに役立つ秘密兵器やアイテムはない。<c=binary><w=superglitch>彼は存在するはずのなかったボスであり、ゲームにプログラムされることのなかった存在で、ゲームそのものよりも強力になってしまった。

いざという時、主人公はいつも「愛の力」に頼って形勢を逆転してきた。しかし、愛そのものが<c=binary><w=superglitch>彼の動力源であるとき、どうやって倒すことができるのだろうか? <q=clicktocont>

(It should be possible to test this without all of the <c> tags).

Basically, if you attach a Content Size Fitter with Vertical Fit: Preferred Size, and then drag the width around, the wrapping will eventually get messed up. It might be related to the 「 chars.

Hey! Actually, I was able to reproduce this in a testing project, so I'll go ahead and email that to you. I just copied over some prefabs and scripts from the main project. Near the end of the convo, you'll see the word <w=glitch>and</w> — it gets animated in the editor, but not in build for me.

Sounds good, thanks!

Actually, this reminded me of a similar problem that I had in the past with a different <w> effect, and I just noticed that I'm still getting this problem in build (not in editor). The problem occurs the first time the menu is shown, but it gets fixed if I close the menu and reopen it, so it probably has something to do with Rebuild().

This other one would be easier to reproduce, so I can try and copy some prefabs over to a demo project later. But either way, it looks like there's something that can situationally cause an animation to stop, which (as far as I know) isn't intended.

Yeah, Rebuild() is being called. I can't remember how the whole process works, but it's probably being rebuilt at least once when the text is set, but possibly more than once if the vertical layout group or some other code changes the rect transform's size or the font's size.

I just tried again with force animation, and it's still not working. Makes sense that perhaps a timer is being stopped somehow, though.

(1 edit)

I have a project-specific bug that I'm trying to untangle, and I'm not totally sure if the issue is in my own code or if it's in STM.

I have a piece of text that's animated with a custom wave, like <w=myWave>. It displays properly when it's first shown to the player and in the editor. But, when I load that same text from the player's save file in build, the text isn't animated — and it looks like it got frozen mid-animation.

You can see how the name "kameleon1c" appears to be frozen at different stages of the wave.

Anyway, is there any situation where this would be intended behavior? At first I was thinking that perhaps the <w> tag got removed or renamed when loading the string from the save file. But, according to my testing in the editor, it looks like removing the <w> causes the string to render normally, even if it was mid-animation. Also, it's worth noting that this works correctly in the editor — I'm only getting the problem in the build.

I haven't been able to reproduce this elsewhere, so it might have something to do with the whole setup that it's part of, which involves a vertical layout group and probably multiple rebuilds. So, I'm trying to figure out what situation could cause this in the first place.

Hey, good to know. Yeah, I think it makes sense to treat auto-hyphens and manual hyphens differently (or you could set it to take manual hyphens into account if the insertHyphens bool is turned off, because in that case it wouldn't matter).

It can be an issue for any situation where there isn't much whitespace around the RectTransform, because the hyphen ends up sticking out (especially with a monospaced font). And, as mentioned, it can be a problem when working with masks — this one is within a ScrollRect, and the Viewport has a mask. If the content and viewport are the same size, the hyphen ends up getting skipped entirely, because the whole char is outside the bounds of the viewport. I sort of worked around this by changing how the padding is set up, but you get the idea.

Hey, just encountered an obscure problem involving word wrap (1.13.2). If the final character of a line is a hyphen, it looks like the wrapping doesn't occur until afterward. This seems to happen regardless of whether Insert Hyphens is enabled. This causes the text to expand outside of the RectTransform's bounds, which probably isn't intended behavior (and it can be a problem if the STM is inside a mask, which is what happened to me just now).


I was able to reproduce this quickly in a blank project, so I think you'll be able to do the same, but let me know if it looks different on your end.

Btw, looks like 1.13.1 is giving build errors in STMCurveGenerator.cs due to the #if UNITY_EDITOR removing the "using UnityEditor" statement at the top. Build seems to work without that, because the rest of the class still has the directive applied like normal.

Ah, there we go! Seems to be working now in 1.13.1. Thanks!

Hey, just reporting some unusual behavior that I came across. I've noticed that some STMs with the Super Text Mesh/Universal/Default shader fail to render when they're masked by something, regardless of what Mask Mode is set to.

I haven't been able to reproduce this in a blank project, because it probably relates to some finnicky stencil shaders in my main project. But, I can "fix" it by switching to the Super Text Mesh/UI/Default shader.

Looking at the code, it appears that Mask Mode: Ignore is doing something a bit more complex than ignoring the mask. On line 6205 of SuperTextMesh.cs, there's some stuff about MaskDepthToID() that calculates the value used for the stencil ref.

Anyway, perhaps there should be a way to just ignore masking altogether? The stencil stuff is pretty finnicky and I never fully understood it myself, but I think you can ignore the masking by setting the Stencil's Ref to 0, or Comp to Disabled or Never. Not sure why this works in the other shader and not in the Universal one, but since masking isn't required for some objects, I'm trying to just simplify things by ignoring the stencil altogether.

Ohh, I see — yeah, you're correct, I just made a mistake with the import. Thanks! This new system looks great.

What happens if you have two STMAutoDelayDatas pointing to the same char? I've always wondered how best to manage this. If I edit the delay values in the files in the STM folder, they'll get overwritten when I update the asset, so it seems better to duplicate them and keep my own copies — but in that case, should I delete the originals in Resources/STMAutoDelays?

Hey, coming back to this — how does the current auto delay system work? I see the note in the changelog for 1.13.0 that mentions auto delays having their own class now, but I think the objects in the STMAutoDelays folder look the same as before, unless I'm misremembering.

Basically, the goal is to modify the delay rules for Chinese characters (like the ',' comma) so that they activate regardless of whether they're surrounded by spaces (because Chinese text wouldn't have spaces regardless).

Hmm, yeah, it's a strange problem... googling it brings up a wide variety of results.

The other asset is Water2D Tool, and the file is water2D_Icon.png (another icon, strangely enough). Not sure where the icon is used, but it's probably one of the gizmos.

Were you able to reproduce the bug when the other person reported it? Looking at this thread, it might be affected by the project's folder layout in some way (like Editor vs non-Editor folders) https://forum.unity.com/threads/an-asset-is-marked-with-hideflags-dontsave-but-i...

I'll delete the meta files for the icons and see if that helps. Wish there was an easier way to reproduce it, but it seems very sporadic for me.

I've been getting an off-and-on build error that points to an STM asset:

An asset is marked with HideFlags.DontSave but is included in the build: Asset: 'Assets/Plugins/Clavian/SuperTextMesh/Scripts/Icons/SuperTextMeshDataIcon.png' Asset name: SuperTextMeshDataIcon (You are probably referencing internal Unity data in your build.)

Unfortunately, I haven't figured out how to reproduce it consistently; it just happens randomly after creating a few builds, and maybe after switching build targets (unsure if the Reload Domain/Reload Scene project settings are related to this). I had this problem with an icon from another asset, too, so I don't think it's specific to STM.

Anyway, I can fix this with an editor script that just sets the object's hide flags to HideFlags.None. However, this specific STM icon keeps resetting itself, so I have to reapply my fix whenever I launch the editor. Do you know if you're setting this icon's hide flags from an editor script somewhere in STM?

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.

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.

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.

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.

Thank you! I'll try it out once the update is live.

That's probably what I'll end up doing, yeah. It's something that TextMeshPro seems to handle better, but I'm not sure how it works.

Yeah, the results in build seem to be the same as in editor.

Auto quality (40)



Manual quality (60)



Logically, it seems reasonable to decrease the quality to 40 for 1080p, but in practice I find that it looks blurry compared to 80 quality at 2160p. It's a bit hard to compare because one screenshot would be way larger than the other, but I'd say it looks closer to my second screenshot here (60 quality at 1080p).

Yeah, I suppose so! The old project page is still available here: https://scarletstring.itch.io/monospaced-lovers

There are no public builds right now, but I might as well ship the full game to itch alongside other storefronts.

Interesting — the canvas is set to Screen Space - Camera. And the Canvas Scaler is set to Scale With Screen Size with a reference resolution of 3840x2160.

I never quite figured out how canvas scaling works, so I can see why it's a little confusing. To clarify my original post, those screenshots were taken in the editor with the Game view set to 1080p. I've noticed similar behavior in builds, but I figured I'd point that out, because I think some screen-related properties return different values in the editor (like Screen.width or one of those).

Here's something I've wondered about for a while — how does the Auto Quality setting determine the appropriate quality for a mesh? I've often found that the result is blurry compared to setting the quality myself.

Here's an example at 1080p, with a Canvas that's configured for 2160p.

Quality: 80 (manual)



Quality: 40 (auto) (top only)

In the second pic, the top text box is set to Auto Quality while the bottom is manually set to 80. The top gets auto-set to 40 quality, and if you view it at 100% resolution, you can see that it's a little blurry.


Here's TMP for comparison:

Now, TMP might not be a good point of reference, because the whole system seems to be different (there's no quality setting). But I think it looks like the best of the three (it might be similar to 70-ish quality).

Anyway, I could probably work around this by having a script set the quality to "auto * 1.5" or something like that, but I'm wondering if I'm setting this up incorrectly, or if I should be using some other method to determine quality.

Makes sense, sounds like that would solve it.

Yeah, I noticed that there was a built-in ScriptableObject called "comma", and I know there's a note somewhere in the documentation about using special names for certain chars. I was actually able to create a ScriptableObject named ",", so I guess it's not an invalid filename? But either way, I think the second issue about the spaces would have prevented it from working regardless.

Hope you can get it fixed, because I think this problem would apply to any language that doesn't have spaces (so at least Chinese and Japanese).

I'm testing our Chinese localization, and I'm trying to figure out if the auto-delays are working. I created one for the "," character and set it to 10 just to test, but it seems like it's still being read like a normal char.

Thinking about it now, maybe this is because there aren't any spaces in Chinese? An example sentence would be something like 星星都离我们很远,冥王星已经算近的了。 As you can see, there are no spaces between the comma character and the letters.

Do you think there can be an option to allow delays to work regardless of spaces? This would be useful for punctuation because you'd typically want to pause after any comma, period, etc., as long as it isn't the last char of the whole string.

Hey, thanks for the detailed reply. I guess that makes sense — yeah, with a quick test, I can see that CreateMesh is called when I have an STM component with a <j> tag, and it stops if I remove the tag. I think the reason the non-animated text was taking 1ms for me was because I still had a custom <w> somewhere in there (so it was still calling SetMesh).

Anyway, I guess I'll leave this be for now. Those optimizations would be great, if you're able to figure it out. So far, because this is just UI text, the frame drops don't seem to be a huge deal, but I'll see if it becomes an issue in other situations later on.

I'm working on a Switch port of my game, so I've been paying more attention to the profiler recently. I noticed that SetMesh gets called every frame, and there's a comment at like 1761 saying "TODO: make this only get called if something changed, or it's animating".

Figured I might as well ask: were you able to make progress on this? It seems like it would have a big impact on performance in some situations.

In this case, I have an ASCII art with a custom <c> gradient that's using a lot of CPU. In the editor, STM's Update method is eating up 2.5ms (sounds like a small number, but it drops the framerate on the Switch to 30 fps). Even with the ASCII disabled, the rest of the (non-animated) text is still taking 1ms on my desktop computer.

Now, the rest of the screen is static while this is happening, so the frame drops aren't super noticeable. But, it would be great if there were some optimization that could be done here, especially if calling SetMesh in Update is not really needed.

Hey - yep, what's up?

Actually, thanks! That's a good suggestion with <t=Infinity> — seems to do the same thing that I was trying to do with the <d=999>, except it's actually infinite and not just effectively infinite. I just tested it, and it's working for me.

Thanks for the suggestion. Yeah, it's a player-controlled situation (waiting for input).

I can see how that would work, but... it's quite a bit of a hack to add/remove those tags and rebuild the mesh, especially with multiple other tags in the way, and multiple pauses.

That said, it seems to work well enough if I just add a <d=99999>, and then remove it when the player presses a button (using an event to detect when we've reached this pause, of course).

What's the max value for a delay? This seems like it would work for my purposes - even if the text auto-advanced after a minute or so, it wouldn't be game-breaking; the pause is only there for drama anyway.