先修复一下,错误的场景 删除不必要的钓场资产 修复into场景 update:更新meta文件,修复报错 update:修复资源 修复第一章节建造 修复建造第三章 update:删除多余内容 update:更新README.md update:还原图标 update:更新README update:更新配置
256 lines
8.3 KiB
C#
256 lines
8.3 KiB
C#
using Coffee.UISoftMaskInternal;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using UnityEngine.Experimental.Rendering;
|
|
using UnityEngine.Profiling;
|
|
using UnityEngine.UI;
|
|
#if UNITY_EDITOR
|
|
using UnityEditor.U2D;
|
|
#endif
|
|
|
|
namespace Coffee.UISoftMask
|
|
{
|
|
internal static class Utils
|
|
{
|
|
/// <summary>
|
|
/// Update the smooth edge effect for the graphic.
|
|
/// </summary>
|
|
public static void UpdateAntiAlias(Graphic graphic, bool enabled, float threshold)
|
|
{
|
|
if (!graphic) return;
|
|
|
|
var canvasRenderer = graphic.canvasRenderer;
|
|
var currentColor = canvasRenderer.GetColor();
|
|
var targetAlpha = 1f;
|
|
if (enabled)
|
|
{
|
|
var currentAlpha = graphic.color.a * canvasRenderer.GetInheritedAlpha();
|
|
if (0 < currentAlpha)
|
|
{
|
|
// Adjust the alpha value for a smooth edge based on the threshold.
|
|
threshold = Mathf.Clamp01(threshold);
|
|
targetAlpha = Mathf.Lerp(1f / 255, 0.1f, threshold) / currentAlpha;
|
|
}
|
|
}
|
|
|
|
// Update the alpha value of the canvas renderer's color to achieve the smooth edge effect.
|
|
if (!Mathf.Approximately(currentColor.a, targetAlpha))
|
|
{
|
|
currentColor.a = Mathf.Clamp01(targetAlpha);
|
|
canvasRenderer.SetColor(currentColor);
|
|
}
|
|
}
|
|
|
|
public static int GetStencilBits(Transform transform, bool includeSelf, bool useStencil,
|
|
out Mask nearestMask, out SoftMask nearestSoftMask)
|
|
{
|
|
Profiler.BeginSample("(SM4UI)[SoftMaskable] GetStencilBits");
|
|
nearestMask = null;
|
|
nearestSoftMask = null;
|
|
var stopAfter = MaskUtilities.FindRootSortOverrideCanvas(transform);
|
|
if (transform == stopAfter)
|
|
{
|
|
Profiler.EndSample();
|
|
return 0;
|
|
}
|
|
|
|
var depth = 0;
|
|
var stencilBits = 0;
|
|
var tr = includeSelf ? transform : transform.parent;
|
|
while (tr)
|
|
{
|
|
if (tr.TryGetComponent<Mask>(out var mask) && mask.MaskEnabled())
|
|
{
|
|
if (!nearestMask)
|
|
{
|
|
nearestMask = mask;
|
|
}
|
|
|
|
stencilBits = 0 < depth++ ? stencilBits << 1 : 0;
|
|
if (mask is SoftMask softMask && softMask.SoftMaskingEnabled())
|
|
{
|
|
if (!nearestSoftMask)
|
|
{
|
|
nearestSoftMask = softMask;
|
|
}
|
|
|
|
if (useStencil)
|
|
{
|
|
stencilBits++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
stencilBits++;
|
|
}
|
|
}
|
|
|
|
if (tr == stopAfter) break;
|
|
tr = tr.parent;
|
|
}
|
|
|
|
stencilBits = Mathf.Min(stencilBits, 255);
|
|
Profiler.EndSample();
|
|
|
|
return stencilBits;
|
|
}
|
|
|
|
public static bool AlphaHitTestValid(Graphic src, Vector2 sp, Camera eventCamera, float threshold)
|
|
{
|
|
if (!src || !src.IsActive()) return false;
|
|
if (!(src is Image || src is RawImage)) return true;
|
|
|
|
if (FrameCache.TryGet(src, nameof(AlphaHitTestValid), out bool valid))
|
|
{
|
|
return valid;
|
|
}
|
|
|
|
if (src is Image image)
|
|
{
|
|
valid = AlphaHitTestValid(image, sp, eventCamera, threshold);
|
|
}
|
|
else if (src is RawImage rawImage)
|
|
{
|
|
valid = AlphaHitTestValid(rawImage, sp, eventCamera, threshold);
|
|
}
|
|
|
|
FrameCache.Set(src, nameof(AlphaHitTestValid), valid);
|
|
return valid;
|
|
}
|
|
|
|
private static bool AlphaHitTestValid(Image src, Vector2 sp, Camera eventCamera, float threshold)
|
|
{
|
|
if (!src) return true;
|
|
|
|
var texture = src.overrideSprite.GetActualTexture();
|
|
if (!texture) return true;
|
|
if (GraphicsFormatUtility.IsCrunchFormat(texture.format) || !texture.isReadable) return false;
|
|
|
|
var origin = src.alphaHitTestMinimumThreshold;
|
|
if (0 < origin && origin <= 1) return true;
|
|
|
|
Profiler.BeginSample("(SM4UI)[Utils] AlphaHitTestValid (Image)");
|
|
src.alphaHitTestMinimumThreshold = threshold;
|
|
var valid = src.IsRaycastLocationValid(sp, eventCamera);
|
|
src.alphaHitTestMinimumThreshold = origin;
|
|
Profiler.EndSample();
|
|
return valid;
|
|
}
|
|
|
|
private static bool AlphaHitTestValid(RawImage src, Vector2 sp, Camera eventCamera, float threshold)
|
|
{
|
|
var texture = src.texture as Texture2D;
|
|
if (texture == null || !texture.isReadable) return true;
|
|
|
|
Profiler.BeginSample("(SM4UI)[Utils] AlphaHitTestValid (RawImage)");
|
|
|
|
var rt = src.rectTransform;
|
|
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rt, sp, eventCamera, out var lp))
|
|
{
|
|
Profiler.EndSample();
|
|
return false;
|
|
}
|
|
|
|
var rect = src.GetPixelAdjustedRect();
|
|
var x = Mathf.Repeat((lp.x + rt.pivot.x * rect.width) / rect.width * src.uvRect.width + src.uvRect.x, 1);
|
|
var y = Mathf.Repeat((lp.y + rt.pivot.y * rect.height) / rect.height * src.uvRect.height + src.uvRect.y, 1);
|
|
|
|
try
|
|
{
|
|
return threshold < texture.GetPixelBilinear(x, y).a;
|
|
}
|
|
catch
|
|
{
|
|
return true;
|
|
}
|
|
finally
|
|
{
|
|
Profiler.EndSample();
|
|
}
|
|
}
|
|
|
|
public static int GetHighestBit(int i)
|
|
{
|
|
i |= i >> 1;
|
|
i |= i >> 2;
|
|
i |= i >> 4;
|
|
i |= i >> 8;
|
|
// i |= (i >> 16);
|
|
return i - (i >> 1);
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
private static string GetWarningMessage(Graphic src)
|
|
{
|
|
if (!(src is Image || src is RawImage))
|
|
{
|
|
return $"{src.GetType().Name} is not supported type for alpha hit test.";
|
|
}
|
|
|
|
if (src is Image image && image)
|
|
{
|
|
var atlas = image.overrideSprite
|
|
? image.overrideSprite.GetActiveAtlas()
|
|
: null;
|
|
if (atlas && atlas.GetPackingSettings().enableTightPacking)
|
|
{
|
|
return $"Tight packed sprite atlas '{atlas.name}' is not supported.";
|
|
}
|
|
}
|
|
|
|
var tex = src.GetActualMainTexture();
|
|
if (!tex)
|
|
{
|
|
return "No texture is assigned.";
|
|
}
|
|
|
|
if (!(tex is Texture2D))
|
|
{
|
|
return $"The texture '{tex.name}' is not Texture2D.";
|
|
}
|
|
|
|
if (!tex.isReadable)
|
|
{
|
|
return $"The texture '{tex.name}' is not readable";
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
public static void DrawAlphaHitTestWarning(Graphic graphic)
|
|
{
|
|
if (!graphic) return;
|
|
|
|
var warn = GetWarningMessage(graphic);
|
|
if (string.IsNullOrEmpty(warn)) return;
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
{
|
|
EditorGUILayout.HelpBox(warn, MessageType.Warning);
|
|
if (GUILayout.Button("Select"))
|
|
{
|
|
if (graphic is Image image && image)
|
|
{
|
|
var sprite = image.overrideSprite;
|
|
if (sprite)
|
|
{
|
|
Selection.activeObject = sprite.GetActiveAtlas();
|
|
}
|
|
|
|
if (!Selection.activeObject)
|
|
{
|
|
Selection.activeObject = image.GetActualMainTexture();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Selection.activeObject = graphic.GetActualMainTexture();
|
|
}
|
|
}
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
}
|
|
#endif
|
|
}
|
|
}
|