"using Skillx.Utils;\nusing UnityEngine;\nusing UnityEngine.UI;\n\nnamespace NoviceTutorial\n{\n ///

\n /// 实现镂空效果的Mask组件\n /// \n public class TutorialHollowOutMask : MaskableGraphic, ICanvasRaycastFilter\n {\n [SerializeField] private RectTransform highLightTarget;\n\n private Vector3 mTargetMin = Vector3.zero;\n private Vector3 mTargetMax = Vector3.zero;\n\n private bool mCanRefresh = true;\n private Transform mCacheTrans = null;\n\n /// \n /// 设置高亮区域的位置大小\n /// \n /// \n public void SetTarget(RectTransform target)\n {\n if (highLightTarget == null)\n {\n return;\n }\n\n highLightTarget.position = target.position;\n highLightTarget.sizeDelta = target.sizeDelta;\n \n mCanRefresh = true;\n RefreshView();\n }\n\n private void SetTarget(Vector3 tarMin, Vector3 tarMax)\n {\n if (tarMin == mTargetMin && tarMax == mTargetMax)\n return;\n mTargetMin = tarMin;\n mTargetMax = tarMax;\n SetAllDirty();\n }\n\n private void RefreshView()\n {\n if (!mCanRefresh)\n {\n return;\n }\n \n mCanRefresh = false;\n\n if (null == highLightTarget)\n {\n SetTarget(Vector3.zero, Vector3.zero);\n }\n else\n {\n Bounds bounds = RectTransformUtility.CalculateRelativeRectTransformBounds(mCacheTrans, highLightTarget);\n SetTarget(bounds.min, bounds.max);\n }\n }\n\n protected override void OnPopulateMesh(VertexHelper vh)\n {\n if (mTargetMin == Vector3.zero && mTargetMax == Vector3.zero)\n {\n base.OnPopulateMesh(vh);\n return;\n }\n\n vh.Clear();\n\n // 填充顶点\n UIVertex vert = UIVertex.simpleVert;\n vert.color = color;\n\n Vector2 selfPiovt = rectTransform.pivot;\n Rect selfRect = rectTransform.rect;\n float outerLx = -selfPiovt.x * selfRect.width;\n float outerBy = -selfPiovt.y * selfRect.height;\n float outerRx = (1 - selfPiovt.x) * selfRect.width;\n float outerTy = (1 - selfPiovt.y) * selfRect.height;\n // 0 - Outer:LT\n vert.position = new Vector3(outerLx, outerTy);\n vh.AddVert(vert);\n // 1 - Outer:RT\n vert.position = new Vector3(outerRx, outerTy);\n vh.AddVert(vert);\n // 2 - Outer:RB\n vert.position = new Vector3(outerRx, outerBy);\n vh.AddVert(vert);\n // 3 - Outer:LB\n vert.position = new Vector3(outerLx, outerBy);\n vh.AddVert(vert);\n\n // 4 - Inner:LT\n vert.position = new Vector3(mTargetMin.x, mTargetMax.y);\n vh.AddVert(vert);\n // 5 - Inner:RT\n vert.position = new Vector3(mTargetMax.x, mTargetMax.y);\n vh.AddVert(vert);\n // 6 - Inner:RB\n vert.position = new Vector3(mTargetMax.x, mTargetMin.y);\n vh.AddVert(vert);\n // 7 - Inner:LB\n vert.position = new Vector3(mTargetMin.x, mTargetMin.y);\n vh.AddVert(vert);\n\n // 设定三角形\n vh.AddTriangle(4, 0, 1);\n vh.AddTriangle(4, 1, 5);\n vh.AddTriangle(5, 1, 2);\n vh.AddTriangle(5, 2, 6);\n vh.AddTriangle(6, 2, 3);\n vh.AddTriangle(6, 3, 7);\n vh.AddTriangle(7, 3, 0);\n vh.AddTriangle(7, 0, 4);\n }\n\n bool ICanvasRaycastFilter.IsRaycastLocationValid(Vector2 screenPos, Camera eventCamera)\n {\n if (highLightTarget == null)\n {\n return true;\n }\n \n // 将目标对象范围内的事件镂空(使事件可以穿透)\n var isClickHighLightArea = RectTransformUtility.RectangleContainsScreenPoint(highLightTarget, screenPos, eventCamera);\n \n //点击到高亮区域时,射线可以穿透\n if (!isClickHighLightArea)\n {\n //判断下方是否有引导窗口,如果有的话,通知引导进行下一步\n var uiTutorialRoot = GoHelper.FindGameObject(transform.parent.gameObject, "TutorialUIRoot");\n var uiTutorial = uiTutorialRoot.GetComponentInChildren();\n if (uiTutorial != null)\n {\n uiTutorial.Next();\n }\n }\n\n return !isClickHighLightArea;\n }\n\n protected override void Awake()\n {\n base.Awake();\n mCacheTrans = GetComponent();\n }\n\n void Update()\n {\n mCanRefresh = true;\n RefreshView();\n }\n }\n}\n

Unity UI 镂空遮罩组件:实现镂空效果的 Mask 组件

原文地址: https://www.cveoy.top/t/topic/qeR4 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录