這篇文章將為大家詳細講解有關(guān)Unity實現(xiàn)新手引導鏤空效果的方法,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
勃利ssl適用于網(wǎng)站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書合作)期待與您的合作!
具體內(nèi)容如下
一、實現(xiàn)思路
創(chuàng)建有8個頂點的Mesh,內(nèi)外邊界都是四邊形(矩形)。只生成內(nèi)、外邊之間的Mesh,內(nèi)層矩形就產(chǎn)生了鏤空部分,外層的4個頂點,是組件自身RectTransform的四個頂點,內(nèi)層的4個頂點,使用鏤空目標(_target)RectTransform的四個頂點。確定內(nèi)層的頂點的時候需要注意,多數(shù)情況下_target和HollowOutMask都不在同一個本地坐標空間,所以需要使用CalculateRelativeRectTransformBounds計算出HollowOutMask空間下坐標
這種鏤空的表現(xiàn),可以稍稍提高下性能。因為鏤空的位置不參與渲染,Overdraw會降低
UGUI提供了ICanvasRaycastFilter接口,我們實現(xiàn)IsRaycastLocationValid方法,就可以很方便的控制HollowOutMask是否要攔截下在某一點觸發(fā)的事件
二、這個組件的作用
這個組件做了兩件事情:表現(xiàn)上鏤空一塊區(qū)域和不攔截鏤空范圍上的事件
三、代碼實現(xiàn)
using UnityEngine; using UnityEngine.UI; ////// 實現(xiàn)鏤空效果的Mask組件 /// public class HollowOutMask : MaskableGraphic, ICanvasRaycastFilter { [SerializeField] private RectTransform _target; private Vector3 _targetMin = Vector3.zero; private Vector3 _targetMax = Vector3.zero; private bool _canRefresh = true; private Transform _cacheTrans = null; ////// 設(shè)置鏤空的目標 /// public void SetTarget(RectTransform target) { _canRefresh = true; _target = target; _RefreshView(); } private void _SetTarget(Vector3 tarMin, Vector3 tarMax) { if (tarMin == _targetMin && tarMax == _targetMax) return; _targetMin = tarMin; _targetMax = tarMax; SetAllDirty(); } private void _RefreshView() { if (!_canRefresh) return; _canRefresh = false; if (null == _target) { _SetTarget(Vector3.zero, Vector3.zero); SetAllDirty(); } else { Bounds bounds = RectTransformUtility.CalculateRelativeRectTransformBounds(_cacheTrans, _target); _SetTarget(bounds.min, bounds.max); } } protected override void OnPopulateMesh(VertexHelper vh) { if (_targetMin == Vector3.zero && _targetMax == Vector3.zero) { base.OnPopulateMesh(vh); return; } vh.Clear(); // 填充頂點 UIVertex vert = UIVertex.simpleVert; vert.color = color; Vector2 selfPiovt = rectTransform.pivot; Rect selfRect = rectTransform.rect; float outerLx = -selfPiovt.x * selfRect.width; float outerBy = -selfPiovt.y * selfRect.height; float outerRx = (1 - selfPiovt.x) * selfRect.width; float outerTy = (1 - selfPiovt.y) * selfRect.height; // 0 - Outer:LT vert.position = new Vector3(outerLx, outerTy); vh.AddVert(vert); // 1 - Outer:RT vert.position = new Vector3(outerRx, outerTy); vh.AddVert(vert); // 2 - Outer:RB vert.position = new Vector3(outerRx, outerBy); vh.AddVert(vert); // 3 - Outer:LB vert.position = new Vector3(outerLx, outerBy); vh.AddVert(vert); // 4 - Inner:LT vert.position = new Vector3(_targetMin.x, _targetMax.y); vh.AddVert(vert); // 5 - Inner:RT vert.position = new Vector3(_targetMax.x, _targetMax.y); vh.AddVert(vert); // 6 - Inner:RB vert.position = new Vector3(_targetMax.x, _targetMin.y); vh.AddVert(vert); // 7 - Inner:LB vert.position = new Vector3(_targetMin.x, _targetMin.y); vh.AddVert(vert); // 設(shè)定三角形 vh.AddTriangle(4, 0, 1); vh.AddTriangle(4, 1, 5); vh.AddTriangle(5, 1, 2); vh.AddTriangle(5, 2, 6); vh.AddTriangle(6, 2, 3); vh.AddTriangle(6, 3, 7); vh.AddTriangle(7, 3, 0); vh.AddTriangle(7, 0, 4); } bool ICanvasRaycastFilter.IsRaycastLocationValid(Vector2 screenPos, Camera eventCamera) { if (null == _target) return true; // 將目標對象范圍內(nèi)的事件鏤空(使其穿過) return !RectTransformUtility.RectangleContainsScreenPoint(_target, screenPos, eventCamera); } protected override void Awake() { base.Awake(); _cacheTrans = GetComponent(); } #if UNITY_EDITOR void Update() { _canRefresh = true; _RefreshView(); } #endif }
四、使用說明
將以上組件掛載到有RectTransform組件的游戲物體身上,設(shè)置Color的顏色以及Target區(qū)域的大小即可
——此組件掛載的游戲物體身上只能有一個繼承Graphics類的組件
——若自定義添加Image控制Target區(qū)域大小,記得將Image的Alpha設(shè)置為0并且取消射線檢測
關(guān)于“Unity實現(xiàn)新手引導鏤空效果的方法”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。