Unity實(shí)現(xiàn)移動端手勢解鎖功能
本文實(shí)例為大家分享了Unity實(shí)現(xiàn)移動端手勢解鎖的具體代碼,供大家參考,具體內(nèi)容如下
一、效果演示
二、實(shí)現(xiàn)思路
——當(dāng)鼠標(biāo)選中一個(gè)密碼按鈕時(shí)開始記錄輸入的數(shù)字和鼠標(biāo)的起始位置
——當(dāng)鼠標(biāo)按下過程中,始終根據(jù)記錄的鼠標(biāo)起始位置和當(dāng)前鼠標(biāo)的位置兩個(gè)點(diǎn)繪制線段并添加到線段的列表中,并一直清空掉列表中除了最后一個(gè)線段外的其余線段
——當(dāng)鼠標(biāo)按下過程中,如果有覆蓋到其他的密碼按鈕,則根據(jù)起始的密碼按鈕與當(dāng)前的密碼按鈕兩個(gè)點(diǎn)繪制線段并重新記錄輸入的數(shù)字和鼠標(biāo)起始位置
三、實(shí)現(xiàn)過程
——創(chuàng)建9個(gè)密碼塊,并依次命名為1、2.....9,并設(shè)置tag為PasswordBlock
——編寫生成LineRenderer的方法,初始化LineRenderer屬性的方法,繪制線的方法以及清空線的方法
注意繪制線段時(shí),需要將起始位置和結(jié)束位置的z軸置為0
——編寫記錄密碼和刪除密碼的方法
四、完整代碼(掛載到手勢解鎖界面的物體身上)
using UnityEngine; using System.Collections.Generic; using UnityEngine.EventSystems; public class GestureUnlock : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler { private List<GameObject> lrList = new List<GameObject>();//存儲每個(gè)LineRenderer的列表 private List<GameObject> passwordButtonList = new List<GameObject>();//存儲每個(gè)密碼按鈕的列表 private Vector3 startPos;//鼠標(biāo)開始的位置 //線的參數(shù) public Color startColor = Color.black;//線開始的顏色 public Color endColor = Color.black;//線結(jié)束的顏色 public float width = 0.1f;//線寬度 public int vertices = 90;//頂點(diǎn)數(shù) public string password;//密碼 private string inputPassword;//輸入的密碼 /// <summary> /// 刷新線段(拖拽過程中一直刷新) /// </summary> private void RefreshLine() { if (passwordButtonList.Count == 0) { return; } LineRenderer uncompleteLR = SpawnLineRenderer(false); InitLine(uncompleteLR); DrawLine(uncompleteLR, startPos, ScreenToWorld(Input.mousePosition)); ClearLine(false); } /// <summary> /// 繪制已經(jīng)連線完成的線段 /// </summary> private void DrawCompleteLine(Vector3 endPos) { LineRenderer completeLR = SpawnLineRenderer(true); InitLine(completeLR); DrawLine(completeLR, startPos, endPos); } /// <summary> /// 記錄密碼 /// </summary> /// <param name="_passwordBlock">密碼塊物體</param> private void RecordPassword(GameObject _passwordButton) { passwordButtonList.Add(_passwordButton); inputPassword += _passwordButton.name; startPos = _passwordButton.transform.position;//記錄起始位置 } /// <summary> /// 刪除密碼 /// </summary> private void DeletePassword() { passwordButtonList.Clear(); inputPassword = ""; } public void OnBeginDrag(PointerEventData eventData) { ClearLine(true);//每次開始拖拽時(shí)清空所有線段 GameObject go = eventData.pointerEnter; if (go != null && go.tag == "PasswordButton" && IsExistInPasswordBlockList(go) == false) { RecordPassword(go);//記錄密碼 } } public void OnEndDrag(PointerEventData eventData) { ClearUnCompleteLine();//清除未完成的線段 } public void OnDrag(PointerEventData eventData) { RefreshLine();//刷新線段(拖拽過程中一直刷新) GameObject go = eventData.pointerEnter; if (passwordButtonList.Count != 0 && go != null && go.tag == "PasswordButton" && IsExistInPasswordBlockList(go) == false) { DrawCompleteLine(go.transform.position);//繪制已經(jīng)連線完成的線段 RecordPassword(go);//記錄密碼 } } #region 線段相關(guān)操作 /// <summary> /// 生成LineRenderer /// </summary> private LineRenderer SpawnLineRenderer(bool isCompleteLine) { LineRenderer uncompleteLR = new GameObject().AddComponent<LineRenderer>(); uncompleteLR.material = new Material(Shader.Find("Sprites/Default")); lrList.Add(uncompleteLR.gameObject); if (isCompleteLine) { uncompleteLR.gameObject.name = "CompleteLine"; } else { uncompleteLR.gameObject.name = "UncompleteLine"; } return uncompleteLR; } /// <summary> /// 初始化線 /// </summary> private void InitLine(LineRenderer _uncompleteLR) { _uncompleteLR.startColor = startColor; _uncompleteLR.endColor = endColor; _uncompleteLR.startWidth = width; _uncompleteLR.endWidth = width; _uncompleteLR.numCapVertices = vertices; _uncompleteLR.numCornerVertices = vertices; } /// <summary> /// 兩點(diǎn)繪制一條直線 /// </summary> /// <param name="_uncompleteLR">線段</param> /// <param name="startPos">起始位置</param> /// <param name="endPos">結(jié)束位置</param> private void DrawLine(LineRenderer _uncompleteLR, Vector3 startPos, Vector3 endPos) { _uncompleteLR.positionCount = 2; startPos.z = 0; endPos.z = 0; _uncompleteLR.SetPosition(0, startPos); _uncompleteLR.SetPosition(1, endPos); } /// <summary> /// 清除線段 /// </summary> /// <param name="clearAll">是否清除全部線段</param> private void ClearLine(bool clearAll) { if (lrList.Count == 0) { return; } for (int i = lrList.Count - 1; i >= 0; i--) { GameObject go = lrList[i]; if (clearAll) { Destroy(go); lrList.Remove(go); } else { if (go.name != "CompleteLine" && i != lrList.Count - 1) { Destroy(go); lrList.Remove(go); } } } if (clearAll) { DeletePassword(); } } /// <summary> /// 清除未完成的線段(每次拖拽結(jié)束時(shí)清除) /// </summary> private void ClearUnCompleteLine() { if (lrList.Count == 0) { return; } GameObject go = lrList[lrList.Count - 1]; Destroy(go); lrList.Remove(go); } #endregion #region 工具方法 /// <summary> /// 當(dāng)前密碼塊是否存在于密碼塊列表中 /// </summary> /// <param name="_passwordBlock">密碼塊</param> private bool IsExistInPasswordBlockList(GameObject _passwordButton) { if (passwordButtonList.Count == 0) { return false; } if (passwordButtonList.Contains(_passwordButton)) { return true; } else { return false; } } /// <summary> /// 屏幕坐標(biāo)轉(zhuǎn)世界坐標(biāo) /// </summary> /// <param name="screenPos">屏幕坐標(biāo)位置</param> /// <param name="camera">相機(jī)</param> /// <returns>轉(zhuǎn)換后的世界坐標(biāo)</returns> private Vector3 ScreenToWorld(Vector3 screenPos, Camera camera = null) { if (camera == null) { camera = Camera.main; } Vector3 _screenPos = new Vector3(screenPos.x, screenPos.y, -camera.transform.position.z); Vector3 v = camera.ScreenToWorldPoint(_screenPos); return v; } #endregion }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Unity?AssetPostprocessor模型函數(shù)Model實(shí)用案例深入解析
這篇文章主要為大家介紹了Unity?AssetPostprocessor模型Model函數(shù)實(shí)用案例深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05如何使用LinQ To Object把數(shù)組或DataTable中的數(shù)據(jù)進(jìn)行向上匯總
這篇文章主要介紹了如何使用LinQ To Object把數(shù)組或DataTable中的數(shù)據(jù)進(jìn)行向上匯總,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12Unity 實(shí)現(xiàn)框選游戲戰(zhàn)斗單位的思路詳解
這篇文章主要介紹了Unity 如何實(shí)現(xiàn)框選游戲戰(zhàn)斗單位,本文簡單介紹如何實(shí)現(xiàn)即時(shí)戰(zhàn)略游戲中框選戰(zhàn)斗單位的功能,需要的朋友可以參考下2022-12-12C# IP地址與整數(shù)之間轉(zhuǎn)換的具體方法
這篇文章介紹了C# IP地址與整數(shù)之間轉(zhuǎn)換的具體方法,有需要的朋友可以參考一下2013-10-10