using System.Collections.Generic; using UnityEngine; using UnityEngine.Pool; namespace UnityEngine.UI { [AddComponentMenu("UI/Effects/Shadow", 80)] /// /// Adds an outline to a graphic using IVertexModifier. /// public class Shadow : BaseMeshEffect { [SerializeField] private Color m_EffectColor = new Color(0f, 0f, 0f, 0.5f); [SerializeField] private Vector2 m_EffectDistance = new Vector2(1f, -1f); [SerializeField] private bool m_UseGraphicAlpha = true; private const float kMaxEffectDistance = 600f; protected Shadow() {} #if UNITY_EDITOR protected override void OnValidate() { effectDistance = m_EffectDistance; base.OnValidate(); } #endif /// /// Color for the effect /// public Color effectColor { get { return m_EffectColor; } set { m_EffectColor = value; if (graphic != null) graphic.SetVerticesDirty(); } } /// /// How far is the shadow from the graphic. /// public Vector2 effectDistance { get { return m_EffectDistance; } set { if (value.x > kMaxEffectDistance) value.x = kMaxEffectDistance; if (value.x < -kMaxEffectDistance) value.x = -kMaxEffectDistance; if (value.y > kMaxEffectDistance) value.y = kMaxEffectDistance; if (value.y < -kMaxEffectDistance) value.y = -kMaxEffectDistance; if (m_EffectDistance == value) return; m_EffectDistance = value; if (graphic != null) graphic.SetVerticesDirty(); } } /// /// Should the shadow inherit the alpha from the graphic? /// public bool useGraphicAlpha { get { return m_UseGraphicAlpha; } set { m_UseGraphicAlpha = value; if (graphic != null) graphic.SetVerticesDirty(); } } protected void ApplyShadowZeroAlloc(List verts, Color32 color, int start, int end, float x, float y) { UIVertex vt; var neededCapacity = verts.Count + end - start; if (verts.Capacity < neededCapacity) verts.Capacity = neededCapacity; for (int i = start; i < end; ++i) { vt = verts[i]; verts.Add(vt); Vector3 v = vt.position; v.x += x; v.y += y; vt.position = v; var newColor = color; if (m_UseGraphicAlpha) newColor.a = (byte)((newColor.a * verts[i].color.a) / 255); vt.color = newColor; verts[i] = vt; } } /// /// Duplicate vertices from start to end and turn them into shadows with the given offset. /// /// Vert list to copy /// Shadow color /// The start index in the verts list /// The end index in the vers list /// The shadows x offset /// The shadows y offset protected void ApplyShadow(List verts, Color32 color, int start, int end, float x, float y) { ApplyShadowZeroAlloc(verts, color, start, end, x, y); } public override void ModifyMesh(VertexHelper vh) { if (!IsActive()) return; var output = ListPool.Get(); vh.GetUIVertexStream(output); ApplyShadow(output, effectColor, 0, output.Count, effectDistance.x, effectDistance.y); vh.Clear(); vh.AddUIVertexTriangleStream(output); ListPool.Release(output); } } }