Skip to content

Commit

Permalink
feat: maskingShape with TextMeshPro
Browse files Browse the repository at this point in the history
close #217
  • Loading branch information
mob-sakai committed Dec 22, 2024
1 parent fe7354b commit 858655f
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ private static float Convert(TransformSensitivity self)
{
switch (self)
{
case TransformSensitivity.Low: return 1f / (1 << 2);
case TransformSensitivity.Medium: return 1f / (1 << 5);
case TransformSensitivity.Low: return 1f / (1 << 4);
case TransformSensitivity.Medium: return 1f / (1 << 8);
case TransformSensitivity.High: return 1f / (1 << 12);
default: return 1f / (1 << (int)self);
}
Expand Down
63 changes: 47 additions & 16 deletions Packages/src/Runtime/MaskingShape/MaskingShape.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
using UnityEngine.Profiling;
using UnityEngine.Rendering;
using UnityEngine.UI;
#if TMP_ENABLE
using TMPro;
#endif

namespace Coffee.UISoftMask
{
Expand Down Expand Up @@ -73,10 +76,7 @@ public MaskingMethod maskingMethod
m_MaskingMethod = value;

SetContainerDirty();
if (graphic)
{
graphic.SetMaterialDirty();
}
SetMaterialDirty();
}
}

Expand All @@ -90,10 +90,7 @@ public bool showMaskGraphic
{
if (m_ShowMaskGraphic == value) return;
m_ShowMaskGraphic = value;
if (graphic)
{
graphic.SetMaterialDirty();
}
SetMaterialDirty();
}
}

Expand Down Expand Up @@ -165,7 +162,7 @@ protected override void OnEnable()
graphic.RegisterDirtyVerticesCallback(_setContainerDirty ?? (_setContainerDirty = SetContainerDirty));
graphic.RegisterDirtyLayoutCallback(_setContainerDirty ?? (_setContainerDirty = SetContainerDirty));

graphic.SetMaterialDirty();
SetMaterialDirty();
graphic.SetVerticesDirty();
}

Expand Down Expand Up @@ -193,7 +190,7 @@ protected override void OnDisable()
graphic.UnregisterDirtyVerticesCallback(_setContainerDirty ?? (_setContainerDirty = SetContainerDirty));
graphic.UnregisterDirtyLayoutCallback(_setContainerDirty ?? (_setContainerDirty = SetContainerDirty));

graphic.SetMaterialDirty();
SetMaterialDirty();
graphic.SetVerticesDirty();
}
}
Expand Down Expand Up @@ -224,11 +221,7 @@ protected override void OnValidate()
SetContainerDirty();
RegisterAntiAliasingIfNeeded();
UpdateAntiAliasing();

if (graphic)
{
graphic.SetMaterialDirty();
}
SetMaterialDirty();
}
#endif

Expand Down Expand Up @@ -331,6 +324,21 @@ void IMeshModifier.ModifyMesh(VertexHelper verts)
Logging.Log(this, " >>>> Graphic mesh is modified.");
}

public void UpdateMesh(Mesh mesh)
{
if (!mesh || !isActiveAndEnabled) return;

Profiler.BeginSample("(SM4UI)[MaskingShape)] UpdateMesh");
if (!_mesh)
{
_mesh = MeshExtensions.Rent();
}

mesh.CopyTo(_mesh);
Profiler.EndSample();
Logging.Log(this, " >>>> Graphic mesh is modified.");
}

internal bool AntiAliasingEnabled()
{
return isActiveAndEnabled && _mask is SoftMask softMask && softMask.AntiAliasingEnabled();
Expand Down Expand Up @@ -364,6 +372,15 @@ private void SetContainerDirty()
}
}

private void SetMaterialDirty()
{
if (graphic)
{
graphic.SetMaterialDirty();
SoftMaskUtils.UpdateMeshUI(graphic);
}
}

private void UpdateContainer()
{
Mask mask = null;
Expand Down Expand Up @@ -414,9 +431,23 @@ internal bool IsInside(Vector2 sp, Camera eventCamera, float threshold = 0.01f)
return true;
}

protected virtual Texture GetMainTexture(Graphic graphic)
{
#if TMP_ENABLE
if (graphic is TextMeshProUGUI || graphic is TMP_SubMeshUI)
{
var cr = graphic.canvasRenderer;
if (!cr || cr.materialCount == 0) return null;

return cr.GetMaterial(0).mainTexture;
}
#endif
return graphic.mainTexture;
}

internal void DrawSoftMaskBuffer(CommandBuffer cb, int depth)
{
var texture = graphic.mainTexture;
var texture = GetMainTexture(graphic);
var mesh = _mesh;
if (!mesh) return;
if (!graphic.IsInScreen()) return;
Expand Down
42 changes: 27 additions & 15 deletions Packages/src/Runtime/Utilities/SoftMaskUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.Rendering;
using UnityEngine.UI;
#if URP_ENABLE
using UnityEngine.Rendering.Universal;
#endif
Expand Down Expand Up @@ -100,39 +101,50 @@ private static void InitializeOnLoadMethod()
};

#if TMP_ENABLE
TMPro_EventManager.TEXT_CHANGED_EVENT.Add(obj =>
{
if (!(obj is TextMeshProUGUI text)) return;

if (text.TryGetComponent<SoftMask>(out var sm))
{
UpdateSubMeshUI(text, sm.showMaskGraphic, sm.antiAliasingThreshold, sm.softnessRange);
}
else if (text.TryGetComponent<MaskingShape>(out var ms))
{
UpdateSubMeshUI(text, ms.showMaskGraphic, ms.antiAliasingThreshold, ms.softnessRange);
}
});
TMPro_EventManager.TEXT_CHANGED_EVENT.Add(UpdateMeshUI);
#endif
}

public static void UpdateMeshUI(Object obj)
{
#if TMP_ENABLE
private static void UpdateSubMeshUI(TextMeshProUGUI text, bool show, float aa, MinMax01 softness)
if (!(obj is TextMeshProUGUI text)) return;

if (text.TryGetComponent<SoftMask>(out var sm))
{
UpdateSubMeshUI(text, sm.enabled, sm.showMaskGraphic, sm.antiAliasingThreshold, sm.softnessRange,
MaskingShape.MaskingMethod.Additive);
}
else if (text.TryGetComponent<MaskingShape>(out var ms))
{
ms.UpdateMesh(text.mesh);
UpdateSubMeshUI(text, ms.enabled, ms.showMaskGraphic, ms.antiAliasingThreshold, ms.softnessRange,
ms.maskingMethod);
}
}

private static void UpdateSubMeshUI(TextMeshProUGUI text, bool enabled, bool show, float aa, MinMax01 softness,
MaskingShape.MaskingMethod method)
{
var subMeshes = UISoftMaskInternal.ListPool<TMP_SubMeshUI>.Rent();
text.GetComponentsInChildren(subMeshes, 1);

for (var i = 0; i < subMeshes.Count; i++)
{
var maskingShape = subMeshes[i].GetOrAddComponent<MaskingShape>();
maskingShape.hideFlags = UISoftMaskProjectSettings.hideFlagsForTemp;
maskingShape.hideFlags = HideFlags.NotEditable;
maskingShape.enabled = enabled;
maskingShape.maskingMethod = method;
maskingShape.antiAliasingThreshold = aa;
maskingShape.softnessRange = softness;
maskingShape.showMaskGraphic = show;
maskingShape.UpdateMesh(subMeshes[i].mesh);
}

UISoftMaskInternal.ListPool<TMP_SubMeshUI>.Return(ref subMeshes);
}
#else
}
#endif

/// <summary>
Expand Down

0 comments on commit 858655f

Please sign in to comment.