3D Text - Stroke/Outline

I’ve been doing some research on how to get an outline on my 3D text within my scene. I can’t believe that there isn’t a shader out there that allows me to add a simple outline to my 3D text?!?

Saying that, I have found some attempted shaders, but they don’t give the desired effect (pixilated stroke, etc).

I have found that you can export the actual font texture and edit that in Photoshop, but thats a pain in the arse as I have to do it for each fill colour, stroke colour and font size I use throughout my game.

Surely, there must be something out there in where I can just define the stroke colour, and size, and boom! its there …?

Thanks

Take your text object and simply add following script to it:

using UnityEngine;
using System.Collections;

public class TextOutline : MonoBehaviour {

	public float pixelSize = 1;
	public Color outlineColor = Color.black;
	public bool resolutionDependant = false;
	public int doubleResolution = 1024;

	private TextMesh textMesh;
	private MeshRenderer meshRenderer;

	void Start() {
		textMesh = GetComponent<TextMesh>();	
		meshRenderer = GetComponent<MeshRenderer>();

		for (int i = 0; i < 8; i++) {
			GameObject outline = new GameObject("outline", typeof(TextMesh));
			outline.transform.parent = transform;
			outline.transform.localScale = new Vector3(1, 1, 1);

			MeshRenderer otherMeshRenderer = outline.GetComponent<MeshRenderer>();
			otherMeshRenderer.material = new Material(meshRenderer.material);
			otherMeshRenderer.castShadows = false;
			otherMeshRenderer.receiveShadows = false;
			otherMeshRenderer.sortingLayerID = meshRenderer.sortingLayerID;
			otherMeshRenderer.sortingLayerName = meshRenderer.sortingLayerName;
		}
	}
	
	void LateUpdate() {
		Vector3 screenPoint = Camera.main.WorldToScreenPoint(transform.position);

		outlineColor.a = textMesh.color.a * textMesh.color.a;

		// copy attributes
		for (int i = 0; i < transform.childCount; i++) {

			TextMesh other = transform.GetChild(i).GetComponent<TextMesh>();
			other.color = outlineColor;
			other.text = textMesh.text;
			other.alignment = textMesh.alignment;
			other.anchor = textMesh.anchor;
			other.characterSize = textMesh.characterSize;
			other.font = textMesh.font;
			other.fontSize = textMesh.fontSize;
			other.fontStyle = textMesh.fontStyle;
			other.richText = textMesh.richText;
			other.tabSize = textMesh.tabSize;
			other.lineSpacing = textMesh.lineSpacing;
			other.offsetZ = textMesh.offsetZ;

			bool doublePixel = resolutionDependant && (Screen.width > doubleResolution || Screen.height > doubleResolution);
			Vector3 pixelOffset = GetOffset(i) * (doublePixel ? 2.0f * pixelSize : pixelSize);
			Vector3 worldPoint = Camera.main.ScreenToWorldPoint(screenPoint + pixelOffset);
			other.transform.position = worldPoint;

			MeshRenderer otherMeshRenderer = transform.GetChild(i).GetComponent<MeshRenderer>();
			otherMeshRenderer.sortingLayerID = meshRenderer.sortingLayerID;
			otherMeshRenderer.sortingLayerName = meshRenderer.sortingLayerName;
		}
	}

	Vector3 GetOffset(int i) {
		switch (i % 8) {
		case 0: return new Vector3(0, 1, 0);
		case 1: return new Vector3(1, 1, 0);
		case 2: return new Vector3(1, 0, 0);
		case 3: return new Vector3(1, -1, 0);
		case 4: return new Vector3(0, -1, 0);
		case 5: return new Vector3(-1, -1, 0);
		case 6: return new Vector3(-1, 0, 0);
		case 7: return new Vector3(-1, 1, 0);
		default: return Vector3.zero;
		}
	}
}

Hi!

If you are after a simple process to add an outline to a text object, then I would use TextMesh Pro which allows you to add an outline / stroke dynamically and much more. All these styling options are real-time and dynamic. No need for Photoshop or editing font textures.

Here is an example (1) the plain text, (2) text with an Outline and (3) Just the Outline.

alt text

The only difference between those 3 text objects are different material properties. For instance, here is another example with a soft shadow with slightly thinner outline / stroke.

alt text

To learn more about TextMesh Pro, you can check out the Asset Store Thread.

Hopefully my answer gives you some good insight on some alternative ways or workflow to achieve the results you seek.

P.S. In case you are wondering, the text with outline and shadow is still one single text object. Not several duplicates.

Sorry for reviving an old thread. Now I have found this amazing repository on Github that does just what you wanted to do: GitHub - n-yoda/unity-vertex-effects: Beautiful text outline for Unity UI.

It’s raw and straight forward but I solved this problem by adding 4 shadows to each text. Place them by using a combination of positions between -1 and 1 on the x and y axis. I don’t know if and how this would work for 3D texts but it looks pretty good for 2D ones.