うにてぃブログ

主にUnityとC#に関する記事を書いていきます

【Unity】Text や イメージ に頂点カラーを追加する

ImageText など Graphic 継承のクラスに対して
水平もしくは垂直に色のグラデーションを入れられる機能

Is Each Vertex にチェックを入れることで Text の場合1文字ずつグラデーションが可能

f:id:hacchi_man:20200411020600p:plain:w400

f:id:hacchi_man:20200411020517p:plain:w400

using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
 
[RequireComponent(typeof(Graphic))]
public class GraphicVertexColor : BaseMeshEffect
{
    private enum Direction
    {
        Horizontal,
        Vertical,
    }
     
    [SerializeField]
    private Color _beginColor = Color.white;
    [SerializeField]
    private Color _endColor = Color.white;
    [SerializeField]
    private Direction _direction;
    [SerializeField]
    private bool isEachVertex;
     
    private List<UIVertex> _vertexList = new List<UIVertex>();
    private UIVertex _vertex;
 
    public override void ModifyMesh(VertexHelper vertex)
    {
        _vertexList.Clear();
        vertex.GetUIVertexStream(_vertexList);
        var count = _vertexList.Count;
        if (isEachVertex)
        {
            for (var i = 0; i < count; i += 6)
            {
                var min = _direction == Direction.Horizontal ? _vertexList[i].position.x : _vertexList[i].position.y;
                var max = _direction == Direction.Horizontal ? _vertexList[i].position.x : _vertexList[i].position.y;
                for (int j = 1; j < 6; j++)
                {
                    var value = _direction == Direction.Horizontal
                        ? _vertexList[i + j].position.x
                        : _vertexList[i + j].position.y;

                    if (value > max)
                        max = value;
                    else if (value < min)
                        min = value;
                        
                }
                
                for (int j = 0; j < 6; j++)
                {
                    var t = Mathf.InverseLerp(
                        min, 
                        max,
                        _direction == Direction.Horizontal ? _vertexList[i + j].position.x : _vertexList[i + j].position.y
                    );
                    SetColor(i + j, Color.Lerp(_beginColor, _endColor, t));
                }
            }
        }
        else
        {
            var min = _vertexList.Min(v => _direction == Direction.Horizontal ? v.position.x : v.position.y);
            var max = _vertexList.Max(v => _direction == Direction.Horizontal ? v.position.x : v.position.y);

            for (var i = 0; i < count; i++)
            {
                var t = Mathf.InverseLerp(
                    min, 
                    max,
                    _direction == Direction.Horizontal ? _vertexList[i].position.x : _vertexList[i].position.y
                );
                SetColor(i, Color.Lerp(_beginColor, _endColor, t));
            }
        }
 
        vertex.Clear();
        vertex.AddUIVertexTriangleStream(_vertexList);
    }
 
    private void SetColor(int index, Color color)
    {
        _vertex = _vertexList[index];
        _vertex.color = color;
        _vertexList[index] = _vertex;
    }
}