Files
MinFt/Client/LocalPackages/SoftMaskForUGUI-3.5.0/Runtime/MaskingShape/TerminalMaskingShape.cs
2026-04-27 12:07:32 +08:00

157 lines
4.8 KiB
C#

using Coffee.UISoftMaskInternal;
using UnityEditor;
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.Rendering;
using UnityEngine.UI;
namespace Coffee.UISoftMask
{
[ExecuteAlways]
[RequireComponent(typeof(RectTransform))]
[RequireComponent(typeof(CanvasRenderer))]
[DisallowMultipleComponent]
[AddComponentMenu("")]
[Icon("Packages/com.coffee.softmask-for-ugui/Icons/SoftMaskIcon.png")]
public class TerminalMaskingShape : MaskableGraphic, ILayoutElement, ILayoutIgnorer, IMaskable
{
private static Material s_SharedTerminalMaterial;
private Mask _mask;
private Mask _parentMask;
private bool _shouldRecalculateStencil;
private int _stencilBits;
public override bool raycastTarget
{
get => false;
set { }
}
protected override void OnEnable()
{
if (!s_SharedTerminalMaterial)
{
s_SharedTerminalMaterial = new Material(Shader.Find("Hidden/UI/TerminalMaskingShape"))
{
hideFlags = HideFlags.DontSave | HideFlags.NotEditable
};
}
material = s_SharedTerminalMaterial;
transform.parent.TryGetComponent(out _parentMask);
_shouldRecalculateStencil = true;
hideFlags = UISoftMaskProjectSettings.hideFlagsForTemp;
#if UNITY_EDITOR
UISoftMaskProjectSettings.shaderRegistry.RegisterVariant(s_SharedTerminalMaterial, "UI > Soft Mask");
#endif
base.OnEnable();
}
protected override void OnDisable()
{
base.OnDisable();
if (_parentMask && _parentMask.MaskEnabled())
{
_parentMask.graphic.SetMaterialDirty();
}
}
void ILayoutElement.CalculateLayoutInputHorizontal()
{
}
void ILayoutElement.CalculateLayoutInputVertical()
{
}
float ILayoutElement.minWidth => 0;
float ILayoutElement.preferredWidth => 0;
float ILayoutElement.flexibleWidth => 0;
float ILayoutElement.minHeight => 0;
float ILayoutElement.preferredHeight => 0;
float ILayoutElement.flexibleHeight => 0;
int ILayoutElement.layoutPriority => 0;
bool ILayoutIgnorer.ignoreLayout => true;
void IMaskable.RecalculateMasking()
{
_shouldRecalculateStencil = true;
}
public override Material GetModifiedMaterial(Material baseMaterial)
{
if (!IsActive())
{
StencilMaterial.Remove(m_MaskMaterial);
m_MaskMaterial = null;
return null;
}
RecalculateStencilIfNeeded();
if ((_stencilBits == 0 && !_mask) || _parentMask != _mask)
{
StencilMaterial.Remove(m_MaskMaterial);
m_MaskMaterial = null;
return null;
}
var maskMat = StencilMaterial.Add(baseMaterial, _stencilBits, StencilOp.Zero, CompareFunction.Equal, 0,
_stencilBits, Utils.GetHighestBit(_stencilBits));
StencilMaterial.Remove(m_MaskMaterial);
m_MaskMaterial = maskMat;
return maskMat;
}
protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
if (!IsActive()) return;
// Full-screen rendering.
Profiler.BeginSample("(SM4UI)[TerminalMaskingShape)] OnPopulateMesh");
vh.AddVert(new Vector3(-999999, -999999), new Color32(255, 255, 255, 255), new Vector2(0, 0));
vh.AddVert(new Vector3(-999999, +999999), new Color32(255, 255, 255, 255), new Vector2(0, 1));
vh.AddVert(new Vector3(+999999, +999999), new Color32(255, 255, 255, 255), new Vector2(1, 1));
vh.AddVert(new Vector3(+999999, -999999), new Color32(255, 255, 255, 255), new Vector2(1, 0));
vh.AddTriangle(0, 1, 2);
vh.AddTriangle(2, 3, 0);
Profiler.EndSample();
}
private void RecalculateStencilIfNeeded()
{
if (!isActiveAndEnabled)
{
_mask = null;
_stencilBits = 0;
return;
}
if (!_shouldRecalculateStencil) return;
_shouldRecalculateStencil = false;
var useStencil = UISoftMaskProjectSettings.useStencilOutsideScreen;
_stencilBits = Utils.GetStencilBits(transform, false, useStencil, out _mask, out var _);
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(TerminalMaskingShape))]
internal class TerminalMaskingShapeEditor : Editor
{
public override void OnInspectorGUI()
{
}
}
#endif
}