床に写ったような表現をさくっとできるコンポーネントを作成しました
現状一番下を0にしてもうっすらとは見えてしまうので、見えてしまう最大範囲を変える場合は対応が必要になります
using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; [RequireComponent(typeof(Image))] public class ReflectionImage : BaseMeshEffect { [SerializeField] private Vector2 _shift = Vector2.zero; [SerializeField] [Range(0, 1f)] private float _alphaTop = 1f; [SerializeField] [Range(0, 1f)] private float _alphaBottom = 0.5f; private readonly List<UIVertex> _vertexList = new List<UIVertex>(); #if UNITY_EDITOR protected override void OnValidate() { _alphaTop = Mathf.Max(_alphaTop, _alphaBottom); base.OnValidate(); } #endif public override void ModifyMesh(VertexHelper helper) { _vertexList.Clear(); helper.GetUIVertexStream(_vertexList); var min = _vertexList[0].uv0.y; var max = _vertexList[0].uv0.y; var count = _vertexList.Count; for (var i = 1; i < count; i++) { var uv = _vertexList[i].uv0; if (min > uv.y) min = uv.y; if (max < uv.y) max = uv.y; } var alphaTop = (byte)(255 * _alphaTop); var alphaBottom = (byte)(255 * _alphaBottom); for (var i = 0; i < count; i++) { var vertex = _vertexList[i * 2]; vertex.position.x += _shift.x; vertex.position.y += _shift.y; var uv = vertex.uv0; var t = Mathf.InverseLerp(min, max, uv.y); uv.y = Mathf.Lerp(max, min, t); vertex.uv0 = uv; var color = vertex.color; color.a = (byte)Mathf.Lerp(alphaBottom, alphaTop, t); vertex.color = color; _vertexList.Insert(i, vertex); } helper.Clear(); helper.AddUIVertexTriangleStream(_vertexList); } }