Jump to content

How to programmatically add an outline to a text object?


Recommended Posts

I have heard it rumored (thanks, @DMagic!) that it's possible to set a shader on a Unity text object so that it has an outline around it (e.g. for better visibility).

However, the only info I have at the moment is this link:

http://digitalnativestudios.com/textmeshpro/docs/shaders/

...which I have no idea what to do with, since it doesn't talk about any sort of programmatic API at all.  Looks like it's some sort of UI tool documentation.

Basically, my issue is, I've got a TextMeshProUGUI object, and I want to somehow set the outline to something.  (The text currently has no outline.)  I'm guessing that what I need to do is to somehow navigate the maze of object references to find a shader upon which I can set a property... except that I have no clue how to do that.  Too many object references all over the place, no idea if I need to navigate up the inheritance hierarchy or down into owned sub-objects or downcast something (Unity does this a lot, ugh), or whatever.  I'm in a maze of twisty passages, all alike.

Does anyone have any suggestions as to how I might do this?  Any advice much appreciated!

Link to comment
Share on other sites

Basically all that you have to do is set the TextMeshProUGUI.outlineWidth to something greater than zero, and you can change the outlineColor.

The problems that might arise could come from instantiating the new TMP object from an existing object in KSP, rather than a new object. And from setting the material. There are materials that seem to be specific for outlined text, but I'm not sure how important that is, you can try just leaving the material alone and see what happens. There is also some very odd behavior that I've seen in SCANsat when trying to change the outline width.

Link to comment
Share on other sites

1 hour ago, DMagic said:

Basically all that you have to do is set the TextMeshProUGUI.outlineWidth to something greater than zero, and you can change the outlineColor.

Thank you!  Yes, that looks like the thing.

However, it doesn't do what I'd hoped.  Basically, it appears to be drawing a an outline of some width in front of the text.  If my text were big and fat and I was just adding a one or two pixel wide border around it, that would be no problem... but my text is only one pixel wide to start with, and the outline is centered on the text's edge, such that adding even a 1-pixel-wide "outline" isn't outside the text and completely obscures the text itself.  So, looks like this won't work.

I'm sure some sort of fancy solution would be possible by drawing two text objects and putting one on top of the other, or some such... but that's going outside the bounds of what I'm interested in doing (too much complexity for too little payoff)-- think I'll just abandon ship at this point, it's simply not worth it.

Thank you very much for the help!

Link to comment
Share on other sites

Did you try making the font size bigger?

Just to be clear, the desired result is to have green text of the same size as used by the stock maneuver node readout,  but with a thin black outline to aid readability?

That should be possible by playing around with the font size and the outline width (which is a float that can be set to less than 1). The TMP object font size can be changed at any time, and you can also set the font size with TMP rich text tags.

Edited by DMagic
Link to comment
Share on other sites

I could try playing around a bit more.  But even just the small amount that I've done so far tells me that it's going to be... kludgy.  It's clear that these are very simplistically implemented shaders.  For example, the outline color I'd want would be essentially black with a large alpha component-- not an opaque line.  And I've already seen that where the outline from letter 1 overlaps the outline for letter 2, the two partially-transparent overlapping things result in an overlap that's visibly darker, like two circles of a Venn diagram.  It looks horrible.

Could I eventually trick it into doing something that approximately does what I want? Perhaps, but so far it's feeling like it would be a lot of work for a feature that I don't actually have to have-- I was just hoping that it was a low-hanging fruit.  If it's halfway up the tree and I have to construct a stepladder to get there, this particular feature is probably not worth it to me.

(I know I probably seem pretty feckless here-- it's just that my admittedly limited experience working with Unity UI elements thus far is that they're nightmarishly finicky and complex, and very easy to go wrong in arcane ways at run time; as a developer, they just give me the slithering creeps, and I find myself very unmotivated to try to wrestle them into submission.  Which is one of the reasons why basically all of my mods avoid UI like the plague.  I've generally been pretty happy with the KSP API, but I gotta say that I positively loathe Unity's.)

I'll probably spend another hour or so fiddling with it, but I'm not super optimistic.

Link to comment
Share on other sites

That feels more like you want a shadow to make it easier to read ? In GCMonitor I do this for a shadow. I forgot is there is an easy way to list all available fonts materials.

Link to comment
Share on other sites

Yes, a drop-shadow would be another good way to accomplish this.  Thanks for the suggestion!

Part of the issue, though, is that I don't actually "own" all of the objects involved.  Some of them, but not all of them.  The context of all this is that I'm considering adding a feature to BetterBurnTime to aid readability.  The text in question is down next to the navball-- it's the "estimated burn time" and "time until burn" text.  Depending on what's going on with the player, the text in question might be an object that I create, own, and manage (e.g. the "impact tracker" and "closest approach tracker" features of BBT), or it might be the actual maneuver node burn vector indicator itself, which is owned and managed by the stock game, and I tinker with it only by fiddling with the game's owned/managed object-- e.g. by adjusting the content of the text.

So any solution that involves creating additional objects and managing their lifetime is kind of problematic, because they'd need to be tied to an object that I don't own and manage, which somewhat limits my wiggle room.

And like I said, it's not something I consider a must-have feature.  If it were just a matter of adding a line or two of code in a couple of places so I can make it work with an hour or two of work, that would be great; but this feels more like a "multi-day effort with lots of debugging and testing and trial-and-error", which puts it on the wrong side of the cost/benefit curve for me.

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...