Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics


A member registered Jul 23, 2014 · View creator page →

Creator of

Recent community posts

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.

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!

(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?

Next updates gonna support this directly!! Got a new type just for auto delays, and they've got rule types that can be set!

Yeah it's something I'm going to keep thinking about for sure... I'll have to mess around with different methods and resolutions and just see what happens/looks best.

Hmm, could you give me a string of sample text to try? I think I was messaged about this before, but it's been so long I forget the answer!

If I had to guess though, it's probably similar to the problem with Arabic text in Unity, where joined characters get broken by the input field itself, and the text has to be routed through another script to be re-corrected. This kind of script can be set up to function automatically with Super Text Mesh, so if one is required for Indian languages it should be *possible*.

Another way to test this without buying the asset is... Unity's "Text Mesh" component handles text similarly, so if text looks fine with that, even after being processed by a script to correct Unity-caused errors, it *should* look fine with STM.

Hmm... well all that auto-quality does is try to match the font point size to the size of the text on a canvas... if it's doing that successfully but doesn't look good, it's probably better to set that value manually at this point? I'm not sure what else I should do...

(1 edit)

Yeah, I noticed that when resizing the editor, things like the scale factor didn't actually seem to change... do you get different results in a build?

I may have to revisit how auto-quality is calculated. If the canvas were to be 2160p tall and the text size were to be 80, ideally, the quality should be set to 80 if there's no scaling going on. So if it were rendering at 1080p with the same settings, the text ideally should go down to 40 quality, to match the actual screen resolution. So maybe it should be a comparison between the canvas reference height and Screen.height...? We could give that a shot and see if it produces a result in-editor

Hmm this is the second report I've gotten about auto-quality in a short time, so I may have to look into this.

AutoQuality's code is just this:

(int)Mathf.Ceil(size * parentCanvas.scaleFactor);

Turns out, parentCanvas.scaleFactor doesn't work when the canvas isn't rendering in screen space. Are you using a screen space canvas?

If that doesn't change anything, what I think is happening is... the canvas is targeting 1080p, but the game is targeting 2160p. AutoQuality only cares about the parent canvas's scale factor, not the game's target resolution.... so maybe the scaleFactor is getting confused somewhere else along the way and I'll have to do a manual comparison somewhere? 

First, just let me know if you're using a world space canvas or not, and if so... I'll either have to write a manual scale check, or just say to set the quality manually.

Oh, great point!! The actual comma character you want to use *isn't* one that's blocked by file systems, so the current system will actually work for that step.

...But yeah I need to add a new class for autodelays so they can be given unique rulesets on a per-character basis, anyway... So hopefully I'll be able to add that soon. Really sorry for the delays!

Ah, this would be because I haven't added "," as a character that gets an auto-delay by default... This system has two caveats that I need to reprogram so hopefully I get time to do that soon...

Basically, for autodelays, it's using the standard delay data scriptableobject to determine what characters are getting delays. These delay datas have special names used by the "SpecialKeyToName()" method inside of SuperTextMesh.cs. So... the ones that don't have names there won't work as it stands. 

The second issue is what you pointed out, the autodelay system will only care about what it calls "free" characters, characters with a space afterwards. A friend had some concerns about this system too, so what I want to do is...

1) Make a new, separate type of data for autodelays that instead of relying on the scriptableobject name, has a field for a char, and uses that.

2) This new type can also determine the behaviour. So "." might only come into effect if the next character is a space, while "," will always cause a delay no matter what.

Different options: Always Delay, Only if followed by space, Only if followed by different character, Only if followed by same character or a space

Hopefully I can have this implemented soon, I think this will solve the issue...?

When I go to and search the page for "Playmaker Actions", the link still seems to be working for me? It should want to download a .unitypackage. If this doesn't work, I'll just upload the sourcecode to pastebin for you.


So that note to myself has a bit of a long story...

Basically, SetMesh() is called every frame when there's an animated effect going on. If it's working as intended, it only gets enabled when an effect actually needs movement, so <c=rainbow> won't invoke it if the animation speed of the gradient is set to 0. This could be optimized further though, currently every time it calls SetMesh(), it rebuilds the mesh from stored data entirely. So it doesn't re-parse the entire string like Rebuild() does, but it does re-create the mesh with the appropriate time data. I *think* this could be improved if it checked which vertices actually needed to update position/color, and then only changed those. But ultimately, I didn't go with this because SetMesh() is already called every frame as STM reads out... so you'd end up with variable CPU load for a given string, and I thought it'd be better to just keep it consistent.

The actual end goal of this note is... someday I really want to make it so that all of STM's time-based effects are handled GPU-side instead of CPU-side. So the timing data would just be fed to STM's shader , and it'd just do it's thing automatically every frame, instead of STM needing to update anything. I'm still just waiting on the shader update I commissioned that will handle new dropshadows and outlines before I look further into this route, so I have something to build on. There's still a lot of things to consider with this method, too.

But also, for the current method there probably is way more that can be optimized, even while still updating every frame on CPU. I may have to take another deep-dive into that shortly to see if there's anything I missed that I'd know how to handle better today.

So until then, all I can really say is... cut down on animated effects or text box size, if possible. The animated effects are really just meant for text boxes about the size of the Paper Mario games at largest, so uuuuuusually a mesh of that size updating every frame isn't too bad, so it's been left as-is for the time being.

I've had this page open in a pinned tab for a long long time now, and I still haven't been able to reproduce this at all... I'm pushing a new version of STM so hooopefully this is resolved with it...? If the issue is still persistent please let me know, and I'll look into it again!

Thank you for the bug report! I believe I've fixed the issue, so please email be with the email address near the bottom of my website so that I can send you a file to replace:

I have no idea how I didn't encounter this bug before... so thank you very much for reporting it!! I want to upload this fix immediately!

Not yet, but the new shaders are still being worked on by a 3rd party I'm commissioning. From what I understand, the new shaders will allow outlines to exist in the same pass as text, somehow.

You could make a copy of the shader and remove a few of the passes if that works better for the time being! It'd be effective to use 4 passes for drawing a pixel outline, for example.

(1 edit)

One option is to make all those tags I mentioned into one of the voice tags, so instead of typing a long tag, it could be... <v=fakepause>, <v=fakepausecontinue>, <v=fakepauseresume> or something like that.

There shouldn't be a limit on delays! If you make a preset delay in the save data editor, you can save room typing a long number, too.

But there's an even better, kinda hidden option if you're okay with just pausing the text forever... try using <t=Infinity>! That'll use the timing tag (which tells text after that point to start reading after X seconds), but give the following text an infinite value for it's designated read time, so it'll just never read. It works since that tag just uses string-to-float conversion, so make sure "Infinity" is exactly like that, with an uppercase "I"!

Really sorry about this though, it's such a strange edge-case...

Oh! Good point here, the way the <pause> tag works is that it just stops all text rendering up to a point, then upon Continue() is rebuilds everything until either the next pause tag or the end. So on center-aligned text, that would cause a misalignment... So as it reads out, it's center-aligned at its current point in time, but not relative to the final mesh... 

I think if I were to implement this, I'd have to change a lot about how the pause tags work, pagination, and alignment... I think it might be possible, but I don't see an easy path to it at this moment. I'm going to have to think about it for a while... (Maybe I could have it like... still cut off the text, but only after parsing for line size, and it could insert any linebreak characters at the right position, still...?)

If your pause is just something automatic, rather than controlled by the player, you could try the delay tag? <d=numberHere>

You could also try this... instead of a pause, do this:

First half of string! <drawOrder=allAtOnce><c=clear><e=somethingToDisableAudio>Second half of string!

and then when the player hits the continue button, print this...

<e=somethingToDisableAudio><t=-10000>First half of string! <e=somethingToEnableAudio><t=0>Second half of string!

So... the dialogue would advance like normal, but the text would be disguised like it was just one box.

Thank you! I'm still developing games and use my assets every day, so rest assured it's still useful. But I've already put in just about every text feature that I've seen done in a game before, so there's not much left to add to it, anyway!

I really do need to publish those bugfixes, though... sorry about that! I have a bad habit of wanting to publish big updates all at once. All the bugs were very edge-case things anyway, so most users wouldn't run into them, and if they did, I'd toss over the fix I made immediately.


I've got a few bugfixes I still haven't published that I really should get around to (sorry), but there's still no breakthrough on the shaders from my subcontractor just yet, but I'm told that it's being worked on...


I got and replied to your email, but I'll reply here too with a short answer: the camera gameobjects in this scene have a component that's no longer included in Unity. (GUI Layer) If you remove the component the scene should build fine. (Other sample scenes probably have this component that needs to be removed, too) STM doesn't use this component at all, and I'll make sure to remove it in the next build I upload.

Thank you!


Okay yeah, URP/HDRP is a different beast entirely... shaders meant to support URP are currently being worked on, but just unlit for the time being. I'll as the contractor about lit text

Hey! Does this work for you?

It's a surface emission shader for STM that hooopefully still works... but I know it's possible to edit the current shader to use albedo instead of emission if that would be better, I could try an edit of that tomorrow.

The included shaders are just unlit so modifying it will be required

Super Text Mesh uses submeshes to render, so it's possible the mesh data will be inside of that data block.

This should be what you need to get a single mesh out of a mesh that uses submeshes. STM will make a new submesh every time the material changes.

Then, see what texture is on the corresponding mesh with STM's meshrenderer, and getting the material at the same index as the submesh. Hooopefully this works, and it was just the submeshes causing the issue.

Okay, I've got a solution!!

I'm going to just email you an updated SuperTextMesh.cs since I ended up introducing a new variable and that'd be a bit annoying to manually replace. Lemme know if it works!

Okay yes, I'm now messing with this myself in Unity (sorry, I really thought it was just a font texture thing...) and I can now see it has something to do with the cutoff point... dragging the bounds causes the "de" right before the font change to disappear with certain line widths... going to be looking for the fix now, it may be some of the code I wrote that specifically handles linebreaks for japanese characters.

Replying immediately, because I think that you may get the result you want right away by using the monospace numerals from japanese without any problems (0123...) but I want to solve this for the way you're doing it, too. It looks like I haven't included these monospace numbers in the japanese linebreak rules either, so I'll make sure to add those, too

Hmm okay, then if it's not that, please try...

Inside of "OnFontTextureRebuilt()", change this line:

if(textMesh != null && hyphenedText.Length > 0 && allFonts.Contains(changedFont))

to this:

if(textMesh != null && hyphenedText.Length > 0)

This is a bit more inefficient, as it'll cause every Super Text Mesh object in a scene to rebuild when any font texture rebuilds, but it should force a rebuild no matter what and let us know for sure if that's causing the issue or not.

Also, I'm curious about the import settings of the Japanese font. Is it marked as dynamic or static? (unicode)

I think that OnFontTextureRebuilt() is being invoked before the new font is actually added to the list of fonts being used by the mesh. Please help me test this by doing the following...

Go to the method "RebuildTextInfo()" in SuperTextMesh.cs and move this code...


to be directly below this line, earlier in the same for loop:

Rebuild_font = Rebuild_info.fontData != null ? Rebuild_info.fontData.font : font;

I think this should fix it, now STM will be aware of the new font before the first character in it is actually called, so it should be able to rebuild at the right time. If this works, I'll be sure the next update includes this!

This is the Super Text Mesh support forum, so if something is wrong with your game's background music and it's unrelated to Super Text Mesh, I've become a bit too busy to be able to help, sorry!

Are you talking about the background music in your game, or something related to Super Text Mesh...?

Does this have to do with Super Text Mesh...? I'm confused... Did the "ignore time scale" and "remember read position" booleans work for you?

(1 edit)

When your mesh's "read delay" is set to a value higher than 0, the timing-related options will appear in STM's inspector. So a boolean option for remember read position and ignore time scale will appear. (If you don't want the mesh to actually read-out, despite following these options, set the read mode to "all at once" and the animation to "Appear")

Also, what do you mean by "music"...? The text reading sound made by STM, or your game's background music...?

...Okay, I must have made a mistake when copy/pasting, so here it is again:

Sorry about that!

Ah, I completely forgot to code this exception, sorry!

I can see what it's doing here, for the outline of the quad, it's using the UV data of the quad correctly, but grabbing the font texture, rather than the quad texture.

Here, I've coded an update that gets the right submesh data for quads:

Unfortunately, the outline generator script effects the whole mesh at the moment, unlike the text shaders. I might look into changing this if the shaders don't get finished shortly, though. (I think I can store the data in a UV channel, future Kai reading this...)

(1 edit)

I see... right, a few things to keep in mind are... Super Text Mesh will only update its mesh every frame if it uses an animated text effect, or has the "force animation" boolean checked.

But I think in your unique case, mesh instancing per gameobject type might be something worth looking into. So... for each type of object, you can have a single STM object generate a mesh as a type of generator, instance the mesh produced by STM, and that object type would then know to just use that mesh. If it's low poly assets, you can probably go a step further and bake the text mesh into the lowpoly model's mesh to save on object count, too. If this works, having a script that updates the one shared mesh for a lowpoly object should be pretty efficient if text needs to be updated (localization, different messages, etc) vs having 36k live STM objects that need to be updated. If you're using a font that's marked as dynamic though, baked meshes would have to be rebuilt when OnFontTextureRebuilt() gets invoked by STM, though. So I'd recommend starting with a font with import settings set to something non-dynamic.

In this instance, animated effects would be much better to handle using a custom shader if needed.

The Update method does have a lot of editor-only code. One thing to watch out for is that Unity's inspector itself is pretty inefficient. You can sometimes get an editor performance hit by having an inspector open for an object with a lot of fields. (The TextArea field is especially inefficient (and lacking in features!)... I've actually told Unity about this pretty recently, but there's really no way for me to work around it)

Super Text Mesh was originally made before I was familiar with many good coding practices, but sometimes I get thanked for leaving some out... (Lots of users seem to like that I don't use a namespace, for instance) But if I ever get the time to do a huge update, there would be a lot of backend stuff that gets cleaned up. For the time being though, I'm comfortable enough with it to edit and fix whatever needs to be done. In the end, all that matters is that it works as you need it to, and that our games get completed!


1) What are you programming that requires 36k instances of Super Text Mesh on screen at the same time? Knowing this might help me come up with a specific solution for your use-case.

2) Have you looked into object pooling as a solution to this?

3) Super Text Mesh was originally designed to just work as a single text box, then was optimized to function efficiently as UI elements, so for something like requiring 36k active instances at once, some manual optimization may be required... For instance, are all the meshes going to display the exact same text? If that's the case, you could write some code that causes the mesh generated by one Super Text Mesh object to be shared with a bunch of mesh filters & renderers, instead.

4) SuperTextMesh.cs's whole script is long, but it's all exposed and I tried to keep it as organized as I could. Only SuperTextMesh.cs needs access to all those methods inside of it, so it's all in the one script... maybe in the future I could divide it up, but it might end up having a reverse effect of making it harder for me to edit. (Unity doesn't like partial monobehaviour classes, so I would properly divide STM into multiple components...) I'd recommend expanding and closing parenthesis within a code editor should help with making things navigable. (Some code editors also have a "Structure" view that's very handy for this, too)


Yeah, the outline shaders currently aren't supported in-editor for URP/HDRP. I've heard reports of them rendering fine in built games, but that'd still make development hard. I wrote this script that emulates the outline effect and works in URP: So try placing this on the STM object you want to have an outline.

A new outline shader that looks better than the current one and works in URP is (still!) in the works by a third party. I ask for a bit more patience on the completion of that.


Text lining up with the bounding box is what the "baseOffset" feature is meant for! So you can tweak that offset per-mesh to centre text. I'd do it automatically, but the bounding box is already created based on font bounds, so there's no real way for me to figure out how to nicely space stuff, so I think the baseOffset feature is a good solution.

Regarding this, I actually wrote a script for applying settings like this to multiple STM objects at the same time, called "STMPresets". So... you just have to change the data on one scriptableObject, and all STM objects referencing that SO will update automatically to match the new settings. So you can say... "Font: arial BaseOffset: x=0, y=0.4", and that will just be applied to all meshes listening to that preset. It's been working well in a personal project of mine, so I might include it as a utility script in the next version of STM? If you think this would help with having to manually adjust text, I could upload an early version to pastebin for you!

(1 edit)

Yes, that shader is just for the default render pipeline. (Unity's surface shaders don't work in URP/HDRP, and that's a surface shader I made in the previous post) Super Text Mesh's shaders only fully work properly with the default render pipeline (but I'm currently working with a friend to get a proper URP/HDRP shader made...)

I'm glad! Hopefully I can get a proper patch for this out soon. I'm glad the info is out there now, though!

(1 edit)


I think I've run into this exact bug myself and have been meaning to put out a patch that fixes it... I believe to fix it, go to the inspector for your story, and click the "Gather all Nodes" button. Let me know if that works! If not, check the list of passages and see if one of them is blank. (I also have to fix a bug related to that)

Sorry about that! I've been a bit swamped with contract work, but really want to push a proper fix for this...