Skip to main content

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

Set outline color in code?

A topic by bioroid created 57 days ago Views: 429 Replies: 4
Viewing posts 1 to 4

Hi,

On Unity 2022.3.60f1 here and trying to set the outline color in code using the Ultra shader.

What is the best way to do this?  I created different materials and assign them and see them updated in the inspector, but not on screen.

Last resort will be to have multiple instances of SuperTextMesh and toggle their visibility but that is less than ideal.

Developer

Hello,

At the moment, changing materials is the correct way to set outline color with code, and that was working the last time I checked... but maybe it's possible I missed something with serialization on an update.

Does your text look anything like "<m=blackOutline>Hello, <m=redOutline>world!"? The tags should be case-sensitive.

One thing that might be happening is... if you are creating the material tags through Unity's project window instead of STM's Text Data Editor, you'll have to click "Refresh Database" at the bottom of the Text Data Editor for STM to become properly aware that the material exists. (I should probably put a note on the inspector about this or change how this works to not be required at this point...)

Got it working.  I wasn't using the inline tags because I wanted to leave the text field alone.

Had to make ApplyMaterials() public.

Also made a copy of the material on Start() -> targetText.textMaterial = new Material(targetText.textMaterial);

and just called

 targetText.textMaterial.SetColor("_OutlineColor", stateData.textOutlineColor);

targetText.ApplyMaterials()

Are the inline tags more efficient?  

Developer (4 edits)

Oh sorry I had a bit of a misunderstanding here, I thought you were talking about switching materials mid-string specifically.


The intended way to change materials at runtime is... set superTextMesh.textMaterial like that, and then call Rebuild() or update .text. (At runtime, STM makes internal copies of materials so multiple meshes can share, which is why updating the field in the inspector doesn't seem to work then until something forces Rebuild()) But good point, I could just make ApplyMaterials be public for this use-case where *only* material is changing and not text. I don't think there's a harm in changing that...?


Honestly I could probably implement an <outlineColor> tag that does exactly the code you just showed me since STM creates copies at runtime. I haven't done this yet because the material would have to have a compatible shader from the get-go (Ultra or Universal Outline variant) and the material caching system right now just checks if the entire material matches... so if two different meshes had runtime materials with red outlines but otherwise the same properties, they wouldn't be counted as the same material at the moment, and they might get confused with the base material too. That said, I might try to add this and worry about optimization later, it sounds useful to have! But at this moment, the suggested way is to make different materials with different outline colours before the fact. So I think creating it on Start like that is fine for now!


So... I think what you're doing there is completely fine to do! If you're not also updating text together with changing the textMaterial, I'll expose ApplyMaterials() in the next update, and also start looking into outlineColor tags so code wouldn't have to be written for this. (I've also thought of making it so the outlineColor and other properties are linked to STM rather than the applied material, but it introduces a few more downsides than upsides, so I just left it as-is.)


So to sum it up... using tags to switch pre-made materials or just assigning a pre-made material and making text rebuild will only be more efficient than creating and assigning a new material at runtime if more than 1 mesh is displaying your modified material, by saving draw calls.

Excellent!  Thank you!