Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles

KaiClavier

185
Posts
6
Topics
229
Followers
38
Following
A member registered Jul 23, 2014 · View creator page →

Creator of

Recent community posts

Got it, I changed the code to work for 2017.1.4.

And it doesn't throw errors in 5.3.4, it simply doesn't work like how the current code wouldn't work in 2018. Good idea leaving both options in, I'll give that a go, then I wouldn't have to worry about the unity version.

(2 edits)

Okay yeah trying this out further, this works fine in newer version of Unity, but in 5.3.4 this method doesn't work. If I could pinpoint the exact version of Unity where this breaks, I could use platform-dependent compilation to fix this, but right now that's not really good.


From that bug report, I guess I can assume it's 2018.1? I'll try implementing this, and see if it ends up cropping up in different versions. This wouldn't be the first "by design" bug to hit STM

Oh my god, I never realized this method would work. I figured those toggles were just material inspector shorthands, I didn't think changing the value via code would actually change the keywords! Thank you so much, I'll get this implemented ASAP.

Huh, I never see SDFs turn out that wiggly... then again, the SDF font I mainly test with (itim) doesn't have many straight edges, so the default settings I suggest might not be optimal for all fonts. Is it possible to use an SDF font generated by TMP with STM? I've never actually bothered to see if the systems are compatible, but now that TMP is included with Unity, that's an option to consider. 


The SDF generator I suggest, from what I gather, should be the same code base as what TMP uses anyway? You might have to try upping the font quality even further, or making the inside/outside be larger or smaller (I can't think of which one would produce a sharper image)


I *do* see a small amount of that same "wobbliness" on the TMP text, so it's gotta just be the SDF generation, that's what I'm thinking anyway?

That's my best guess for now! Please give these ideas a shot!

Okay, I think this one has me completely stumped. At the moment, I have no idea why this editor code in "STMCustomInspectorTools.cs" isn't working in newer versions of Unity. The workaround of toggling SDF mode & pixel snap works fine in a material's own inspector, so that might have to be used for just a bit. I'll add this to the official bug list, and hopefully figure out a solution soon.

Hey!


I'm not too sure what you mean by smallcaps... do you mean text Lɪᴋᴇ ᴛʜɪs?


If you want to just have small capital letters, you can use the tag <s=0.5> to have certain text be smaller than others. (The <size=5> will set the text's exact size, not relative size like <s=0.5> does) Besides that, you'd have to make your own pre-parsing script to generate these special smallcaps characters from the normal ASCII data. This method can be done with a standard text mesh too, so it actually falls outside of my jurisdiction, but if you need help getting started, check out the other preparsing examples included with STM to see how to do custom text modifiers!

Alright, I've narrowed it down to being a bug with my inspector. If you go into your material's inspector (the material being used by your STM object), you can toggle SDF mode and pixel snap just fine from there! SO that's the quickfix, I'll see what I can do about getting the inspector to play nice.

(1 edit)

Just replying here to let you know I'm tackling this in the main thread, not sure if you'll get notifications for that

Okay, was able to reproduce the SDF mode toggle thing in 2018.2! (I develop in 5.3.4) I'll see if I can solve this r/n

Hey!


The underline code is handled a custom event - please check out the underline/strikethrough example scene to see how that works! (It's done this way so underlines can be drawn in any way without needing to be rigidly built-in. This method would let someone make a zigzag underline with little modification, for instance)

Basically, a custom event like <e2=underline>This text is underlined!</e2> is used to draw an underline under your text. The code I included lets you change colour per-mesh, so you should already be able to change the colour this way! Check out the components atached to the STM object in that scene, and that should explain it well!


-Kai

Yes, there are some hidden values in STM that should give you these values, but you can do some tricks with string.Split, too!

"stm.lineBreaks.Count" should give the amount of lines. "stm.hyphenedText.Split('\n').Length" should also return the same value.


"stm.hyphenedText.Split(' ').Length" should give the amount of words, by counting the amount of spaces in the final text shown.


Words in a line is a bit trickier, but you can use the info from the lineBreaks list (this list contains the indexes of line breaks in hyphenedText) to do this.

This is some really rough untested code, but something like this will give the amount of words in the first line of text:

string line1string = stm.hyphenedText.Split('\n')[0]; //get all text before first linebreak
int line1wordCount = line1string.Split(' ').Length;

I hope this helps!

I think <pause> would be your best bet! You can call Continue() in your code to have STM continue reading past this point.

Also, your request about fading in/out text is totally valid. I added the "All At Once" read order option for this case, but it seems a bit hacky in practice. A friend asked me recently if you can control STM's colour with unity's animator, and I'd like to make it work that way, sometime. (Right now, Rebuild() would need to be called every frame the color is set) This wouldn't work with gradients anyway though, I'd have to add additive/multiplicative gradients, another feature I was debating on for a bit. (Would require a re-write of STM's colour system)


If you haven't figured it out, you can use the Unread() function to make text use a draw animation in reverse, too! Under "functionality" in STM's inspector, you can customize which animation is used.

Hey!


Yeah, the outline shader takes on the texture of the text at the moment, it's honestly a feature I haven't used myself so I might change it to what you want, or make it a toggle-able option for the uber shaders. If you go into "STMoutline.cginc" and change the lines


col.rgb = mask.rgb * i.color.rgb; 
col.a = text.a * mask.a * i.color.a;


to


col.rgb = i.color.rgb; 
col.a = text.a * i.color.a;


That should do it, I think! You might have to right click STMoutline.cginc within unity and select "ReImport" to see the change take effect.


Hey!


That's awesome, thank you so much for finding this... Unity UI has so many specifics to it, I probably wouldn't have found this myself. I'll make is so that always gets called when Rebuild() gets called. It seems to solve it!


Thank you!

Hey! I'm halfway through solving the problem.

When autoWrap is defined, instead of setting the UI Autowrap value to be "(float)tr.rect.width" I'm setting it to be "preferredWidth" (a value set by Unity UI) and it seems to make the text appear on one line as expected.


That said, text still has an offset applied to it until it's updated. (Even turning on reading and setting the mesh to read all at once didn't fix this) but strangely enough, the text bounds are *half* correct. The blue box that's supposed to be the bounds are set incorrectly, but the yellow box defining the text mesh's actual size is accurate to where the text *should* be.


I've got to head out right now, but hopefully I can use that info to track this down asap!

Hey,


Make sure on your material settings that the Unity UI default shader has its mask mode set to "Outside". I accidentally shipped a build where that value was set to "Inside" which doesn't render text.


Try not importing the legacy shaders - those all used surface functions, and all the new shaders use fragment functions. These will be excluded from the next 1.x patch.


Finally, try right-clicking on the .cginc files in the "Shaders" folder, and click "Reimport".


Please let me know if any of these work! That last one is strange, but Unity doesn't automatically recompile .cginc files when they change, and I just realized that they new .cginc files wouldn't line up with the new shaders after an update. Hopefully that's the one that fixes this?

Ok awesome, I'm able to repro it. I'll see what I can do!

Would it be possible to get a screenshot of the scene view? I'm curious how STM's bounding boxes are set up with Unity UI. I'm currently still unable to reproduce this, would it be possible to set me a sample project that recreates the bug?

Does it make a difference when you put that function under Start() instead of Awake()?

Just an update as this was solved through email. The above solution I had ended up working.

Hey!


The text isn't rendering because I accidentally set the mask mode to be "Inside" by default. Set it to "outside" and it should render fine! I'll change this in the next patch, sorry about that.


That's odd that the SDF mode box can't be checked... as long as it's visible there, I can't think of what wouldn't make it toggle-able. I'm able to toggle it in the exact same shader, maybe try it after solving the above issue? It should make some additional settings appear in the inspector immediately. Let me know if that leads to anything?


Finally,  the legacy SDF shader wasn't meant for Unity UI text, only normal text. Using any legacy normal text shaders on unity UI results in it rending all-black.


-Kai

Hey!


These are all files I updated in the very latest update to fix a big where text wouldn't cast a shadow, and to add more masking options to UI text.


Please do a back up before updating just in case, but have you tried setting Unity's asset serialization mode to "Force Text"? Or have you tried deleting the original files before importing the new ones? If the GUIs are different, it might just be that you have to re-apply the shaders in STM's inspector. (Changing any value will tell the mesh to Rebuild, which might be why it's not showing?


Also, if you moved STM's files to a different folder, this might also cause the issue as Unity will always place new files in the original folder, so that would create a double instead of replacing the original.


There's a bunch of things that could be causing this, but these are the first solutions I can think of off the top of my head! Please let me know what works for you.


-Kai

Are any events after <pause> being called? Audio clips and events are called during the same part of code, so this will help me narrow down the issue. Would it be possible for you to email me a sample project?

Hey!


Looking through my code now, I can't believe I made it so Continue() relies on the autoRead variable, so I've changed that. Doesn't really make any sense in practice... So now within the "Continue()" function, I've changed the line of code reading "Rebuild(totalReadTime, autoRead);" to "Rebuild(totalReadTime, true);".

That said, you should be able to use "Read(stm.currentReadTime)" so you don't have to cache the time using an event! (currentReadTime gets set to where the mesh last left off when Continue() is called)


There was a bug related to <e> tags being right next to <pause> tags that got fixed in v1.8.2, maybe it could be related to that?


Besides that, I can't seem to be able to reproduce the bug. Hopefully this is enough to get it fixed? If this doesn't work, I'll take a closer look!

Patch should be up now (v1.8.5) as long as nothing goes wrong!

No problem! If you want the build right now, drop me an email and I'll give you the .unitypackage. It'll be at least another 2 days before the patch goes up, as the asset store is giving me some strange issues with the automatic vetting process.

(1 edit)

Hey,


The above preparsing code only searches for <transcribe> once in a mesh, since I figured you'd have a single character talking this way and wouldn't need it to happen multiple times. Here's a modified Parse function that loops until all <transcribe> tags are cleared:


public void Parse(STMTextContainer x)
    {
        string startTag = "<" + textTag + ">";
        string endTag = "</" + textTag + ">";
        int startingPoint;
        int endingPoint;
        do
        {
            startingPoint = x.text.IndexOf(startTag);
            endingPoint = startingPoint > -1 ? x.text.IndexOf(endTag,startingPoint) : -1; //get tag after starting tag point
            //optional, where this tag ends
            if(endingPoint == -1)
            {
                endingPoint = x.text.Length;
            }
            else
            {
                //remove tag
                x.text = x.text.Remove(endingPoint, endTag.Length);
                //ending point is already accurate
            }
            //if this tag exists in STM's string...
            if(startingPoint > -1)
            {
                //remove tag
                x.text = x.text.Remove(startingPoint, startTag.Length);
                //push backwards
                endingPoint -= startTag.Length;
                //actually modify text
                Replace(x, startingPoint, endingPoint);
            }
        }
        while(startingPoint > -1);
    }

Hey,


Yes, in the current build on the asset store, </v> causes an error, but I'm currently waiting on the asset store to upload my fix to that. The change I made was that I changed line 1884 in SuperTextMesh.cs to "myInfo = new STMTextInfo(this);"


Here's a modified Replace() function for the above code that will work together with other tags:


void Replace(STMTextContainer x, int startingPoint, int endingPoint)
    {
        //int originalLength = x.text.Length;
        int skippedChars = startingPoint;
        bool parsingOn = true;
        //go thru string
        for(int i=startingPoint; i<endingPoint; i++) //for each letter in the original string...
        {
            
            string replaceValue = x.text[skippedChars].ToString(); //default value             if(replaceValue == "<")
            {
                //turn off parsing
                parsingOn = false;
            }
            else if(replaceValue == ">")
            {
                //turn back on
                parsingOn = true;
            }
            //is this a letter that should be replaced?
            if(parsingOn)
            {
                //replace specific characters with sequences
                //for this example, compare all letters as uppercase letters
                switch(x.text[skippedChars].ToString().ToUpper())
                {
                    case "A": replaceValue = "aaa"; break;
                    case "B": replaceValue = "bbb"; break;
                    //etc etc...
                }
                //remove original character
                x.text = x.text.Remove(skippedChars, 1);
                //replace with sequence
                x.text = x.text.Insert(skippedChars, replaceValue);
            }             //1 by default, but adds up if more characters are inserted
            skippedChars += replaceValue.Length;
        }
    }

Hey, this is a known bug. Patch is already up on itch.io, but the asset store is having issues with automatic asset reviewing so the patch hasn't gone up there yet.

Each of those lines has a commented line above it, if you swap those lines out, it should work.


Sorry for the trouble!

(1 edit)

Found a bug with it, but the tag </v> should cancel all tags already. I'll publish another update that fixes this.


I thought about using custom events for this, but the usage of events is very different than what we're after. I really think it'll be better to use preparsing.


I wrote up some working code that does what you need:


using UnityEngine;
using System.Collections;
public class STMPreparse3 : MonoBehaviour {
    public string textTag = "transcribe";
    public void Parse(STMTextContainer x)
    {
        string startTag = "<" + textTag + ">";
        string endTag = "</" + textTag + ">";
        int startingPoint = x.text.IndexOf(startTag);
        int endingPoint = startingPoint > -1 ? x.text.IndexOf(endTag, startingPoint) : -1; //get tag after starting tag point
        //optional, where this tag ends
        if(endingPoint == -1)
        {
            endingPoint = x.text.Length;
        }
        else
        {
            //remove tag
            x.text = x.text.Remove(endingPoint, endTag.Length);
            //ending point is already accurate
        }
        //if this tag exists in STM's string...
        if(startingPoint > -1)
        {
            //remove tag
            x.text = x.text.Remove(startingPoint, startTag.Length);
            //push backwards
            endingPoint -= startTag.Length;
            //actually modify text
            Replace(x, startingPoint, endingPoint);
        }
    }
    void Replace(STMTextContainer x, int startingPoint, int endingPoint)
    {
        //int originalLength = x.text.Length;
        int skippedChars = startingPoint;
        //go thru string
        for(int i=startingPoint; i<endingPoint; i++) //for each letter in the original string...
        {
            string replaceValue = x.text[skippedChars].ToString(); //default value
            //replace specific characters with sequences
            //for this example, compare all letters as uppercase letters
            switch(x.text[skippedChars].ToString().ToUpper())
            {
                case "A": replaceValue = "aaa"; break;
                case "B": replaceValue = "bbb"; break;
                //etc etc...
            }
            //remove original character
            x.text = x.text.Remove(skippedChars, 1);
            //replace with sequence
            x.text = x.text.Insert(skippedChars, replaceValue);
            //1 by default, but adds up if more characters are inserted
            skippedChars += replaceValue.Length;
        }
    }
}

This code ignores other tags (which shouldn't overlap with this edge case anyway), but you can define a starting and ending point using <transcribe> and </transcribe> or whatever you change the textTag value to.

Hey,


A tag that uses a custom parser isn't the worst idea, but preparsing already allows for full text customization with custom tags. I'll see what I can do, though.


Yeah, the voices are just a collection of multiple tags. <v=myVoice> just puts <c=myColor><w=myWave><etc> into a string. I can't believe I don't have some type of <clearAllTags> tag, yet. That would solve that, so I'll get on it.


Also yeah, I just wrote that sample code as pseudo code right in browser, I didn't test it.

Managed to code it in, auto delays, auto clips, and sound clips all work together with quads, now. If that means everything is solved, I'll publish this update and I can email you a build.

(4 edits)

Now that I see it laid out this way, I think Pre-parsing might be the way to go for your solution.

You'd have to set up a script that interprets your text, maybe something like this:

public void Parse(STMTextContainer(x))
{
    //go thru entire string
    for(int i=0; i<x.text.Length; i++)
    {
        string replaceValue = x.text[i]; //default value
        //replace specific characters with sequences
        switch(x.text[i])
        {
            case "A": replaceValue = "<c=cyan><q=CIRCLE>"; break;
            case "B": replaceValue = "<c=cyan><q=CROSS>"; break;
            etc etc...
        }
        //remove original character
        x.text = x.text.Remove(i);
        //replace with sequence
        x.text = x.text.Insert(i, replaceValue);
    }
}


That way, when you send the text "HELLO WORLD" to a mesh, it'll just convert it to quads, itself! If you need help writing this code for this, just let me know.



Also oops, looks like that's a typo... On line 8 of STMAutoClipData.cs, I call it "Sound Clip Data" instead of auto clip data. I'll make sure this is changed in the next update! That said, you can create new Auto Clips thru the text data inspector. (The menu that shows up when you click the [T] in the top right of any super text mesh inspector. It'll be under "Inline > Sound Clips" or "Automatic > Auto Clips"

Hey!


STM audio clips and STM sound clips are actually different things. Sound clips are the same as auto clips, but you can call them with a tag, so I thing that's what you're looking for. (There's a typewriter example in there that puts a "ding" sound when return is pressed)


Would it be possible to tell me the exact effect you want your text to do? Even before I add quads to auto clips/sound clips character list, the effect you're after might already be possible.

Hey!



Quads can already be multiplied by a colour set in the inspector! Just make sure to check "silhouette" in the quad's settings. This makes it so the quad is treated like any other character in the mesh, so it gets coloured in the same way regular characters do. Works with animated quads, gradients, textures, everything.


***


Good point about quads not having a character in place for custom sound clips. The way internal sound clips works is pretty limited in this regard, so it might be better to get this working through an extension. I was planning on making the audio system more open-ended in a future update, so I think this will be the solution:

I'm going to be adding a unity event that gets invoked every time a sound clip is supposed to play, and that event can be extended in any way, either for support with other middleware like FMOD, or for specific instances like this. I'm imagining for quad output it could work as follows...

Every time a sound is supposed to play, check if the character is "\u2000" (This is a unicode character assigned to quads), and if so, check the data attached to this letter to figure out what the original tag was. (<q=myQuad1> vs <q=myQuad2>) Then using this infor, you can play the appropriate sound.


That said, I'll see if I can extend the sound clips class a bit. It's already got support for typed-out characters like "line break" and "space", so I think I'll be able to have it also check for matches with quads.


***

I think you might be confusing STM's voice system with something else? It's sorta just a renamed text macro system because <m> was already used for materials and <v> was free.

The whole idea behind STM's voices is that they get replaced with other text, even other tags. So if you have a voice named "small" defined as "<s=0.1><c=yellow>" then typing <v=small> will essentially place both of those tags there at once, and you'll get small, yellow text.

I could expand the sound clips class to include colour/effects, as one way to do it. So... it would be like a per-character tag for voices. You might also be able to solve this with Preparsing! I can send some sample code, but with preparsing, you can set up custom tags that get parsed before STM even attempts to parse text. So... you could set up a <mySpecialTag> thing and have it automatically put a colour tag before every character so you don't have to.



This one's a bit tricky to think about, but per-character voices are a neat idea and I don't think they'd be that hard to implement. I'd just have to put them in the same place as my current code for sound clips, I think. It could pair together with the above sound clip idea.


***


STM currently uses the resources folder to queue up effects. The way unity works with Resources, if an asset is in *any* folder named "Resources", unity considers it to be within resources. My default wave effect is stored at "Assets/Clavian/SuperTextMesh/Resources/STMWaves/default.asset", but if you were to store it at "Assets/MyAssets/Resources/STMWaves/default.asset", Unity doesn't see the difference. Just make sure to put it in a folder called "STMWaves" or whatever the appropriate class is. This division is here because... when Unity tosses everything into one Resources folder, it would be really annoying to tell the different classes apart without the subfolders. I also don't want this interfering with other assets that might use the Resources folder.

You're free to delete the sample effect files, by the way! All of them except the "default" ones aren't needed.


***


Anyway, I hope that helps. For now, you might be able to extend STM using  preparsing or the OnPrintEvent() for image effects and audio, respectively.

Last-minute thought about randomized colours tho: Try using a rainbow gradient, had try turning off "smooth gradient" and setting it to repeat often. That should give a randomized colour effect pretty quickly.

Hey! I published the new shaders in v1.8.2. That's up on itch already, and should be on the asset store shortly.

(1 edit)

Update for transparency's sake: This should be solved in 1.8.2!

Essentially, <e><pause><e> actually ends up sticking two events on the same character, and both were being skipped. So now, as STM already does when an event is alone at the end of a string, it adds a zero-width space to hold the event on.

Hey! Got an update on this.

In an empty scene with just a single STM object in it:


Old UI shader: 4 batches

Unity's GUI/Text Shader: 2 batches

New UI Shader: 2 batches


So, that's that! The new shaders are in v1.8.2, and that's out on itch already and will be on the asset store when it gets approved.

Awesome, already published this update!