うにてぃブログ

UnityやUnreal Engineの記事を書いていきます

【Unity】Text の Outline をきれいにする

Unity 付属の Outline を使うと下図のようにちょっと見栄えが悪くなってしまう

[:plai:w300]

そのため描画する数を指定できる Outline を作成してみました

きれいには見えるようになりますが、その分描画負荷が上がってしまうので注意

MultiOutline

作成した Outline がこちらです

f:id:hacchi_man:20200916004700p:plain

頂点数を 8にしてありますが結構きれいになります

見た目は Outline を2つにしたもの と変わりませんが

Outline は 頂点数が 16倍 増えてるのに対し、こちらは 8倍 の増加で済みます

f:id:hacchi_man:20200916004837p:plain

設定

Outline と異なり x, y 個別に ズレを指定する機能は実装していません

f:id:hacchi_man:20200916005039p:plain

コード

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof(Text))]
public class MultiOutline : BaseMeshEffect
{
    [SerializeField]
    [Range(0, 100)]
    private int _amount;
    [SerializeField]
    private Color _color;
    [SerializeField]
    private float _offset;
 
    private readonly List<UIVertex> _outlineVertexList = new List<UIVertex>();
    private readonly List<UIVertex> _vertexList = new List<UIVertex>();
 
    public override void ModifyMesh(VertexHelper vh)
    {
        if (!IsActive())
            return;
 
        _vertexList.Clear();
        _outlineVertexList.Clear();
        vh.GetUIVertexStream(_vertexList);
 
        var splitAngle = 360f / _amount;
        UIVertex v;
 
        var count = _vertexList.Count;
        for (var i = 0; i < _amount; i++)
        {
            var angle = splitAngle * i;
            for (var j = 0; j < count; j++)
            {
                v = _vertexList[j];
                var pos = v.position;
                pos.x += Mathf.Cos(angle * Mathf.Deg2Rad) * _offset;
                pos.y += Mathf.Sin(angle * Mathf.Deg2Rad) * _offset;
                v.position = pos;
                v.color = _color;

                _outlineVertexList.Add(v);
            }
        }
 
        _outlineVertexList.AddRange(_vertexList);
 
        vh.Clear();
        vh.AddUIVertexTriangleStream(_outlineVertexList);
    }
}