您好,登錄后才能下訂單哦!
Unity中怎么實(shí)現(xiàn)新手引導(dǎo)鏤空效果,相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。
一、實(shí)現(xiàn)思路
創(chuàng)建有8個(gè)頂點(diǎn)的Mesh,內(nèi)外邊界都是四邊形(矩形)。只生成內(nèi)、外邊之間的Mesh,內(nèi)層矩形就產(chǎn)生了鏤空部分,外層的4個(gè)頂點(diǎn),是組件自身RectTransform的四個(gè)頂點(diǎn),內(nèi)層的4個(gè)頂點(diǎn),使用鏤空目標(biāo)(_target)RectTransform的四個(gè)頂點(diǎn)。確定內(nèi)層的頂點(diǎn)的時(shí)候需要注意,多數(shù)情況下_target和HollowOutMask都不在同一個(gè)本地坐標(biāo)空間,所以需要使用CalculateRelativeRectTransformBounds計(jì)算出HollowOutMask空間下坐標(biāo)這種鏤空的表現(xiàn),可以稍稍提高下性能。因?yàn)殓U空的位置不參與渲染,Overdraw會(huì)降低
UGUI提供了ICanvasRaycastFilter接口,我們實(shí)現(xiàn)IsRaycastLocationValid方法,就可以很方便的控制HollowOutMask是否要攔截下在某一點(diǎn)觸發(fā)的事件
二、這個(gè)組件的作用
這個(gè)組件做了兩件事情:表現(xiàn)上鏤空一塊區(qū)域和不攔截鏤空范圍上的事件
三、代碼實(shí)現(xiàn)
using UnityEngine;using UnityEngine.UI; /// <summary>/// 實(shí)現(xiàn)鏤空效果的Mask組件/// </summary>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; /// <summary> /// 設(shè)置鏤空的目標(biāo) /// </summary> 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(); // 填充頂點(diǎn) 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; // 將目標(biāo)對(duì)象范圍內(nèi)的事件鏤空(使其穿過(guò)) return !RectTransformUtility.RectangleContainsScreenPoint(_target, screenPos, eventCamera); } protected override void Awake() { base.Awake(); _cacheTrans = GetComponent<RectTransform>(); } #if UNITY_EDITOR void Update() { _canRefresh = true; _RefreshView(); }#endif}
看完上述內(nèi)容,你們掌握Unity中怎么實(shí)現(xiàn)新手引導(dǎo)鏤空效果的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。