国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

Unity3D使用GL實(shí)現(xiàn)圖案解鎖功能

2020-01-24 00:08:08
字體:
供稿:網(wǎng)友

聊天是時(shí)候看到有人問如何在Unity3D的UGUI中實(shí)現(xiàn)圖案解鎖的功能,然后便試了一下。剛開始想用LineRender來實(shí)現(xiàn),但又一想是要在UGUI中,然后就用了另外一種方法,即使用GL類來實(shí)現(xiàn)。

GL相關(guān)介紹及官方文檔

實(shí)現(xiàn)后在Android手機(jī)上跑的效果如下:

主要實(shí)現(xiàn)GraphicUnLockManager類。代碼如下:

using UnityEngine;using System.Collections.Generic;using System;using UnityEngine.EventSystems;using UnityEngine.UI;public class GraphicUnLockManager : MonoBehaviour{ [Tooltip("含有Selectable及Image組件的UI對(duì)象,作為連接點(diǎn)。")] public List<RectTransform> _lstPoints = new List<RectTransform>(); [Tooltip("用于設(shè)置所畫線的顏色。(可使用“unlit/Color”Shader)")] public Material _matLineColor; [Tooltip("用于設(shè)置所畫線的高度。")] public int _nHalfHeight = 15; [Tooltip("用于設(shè)置選擇時(shí)Image的顏色。")] public Color _clrSelect = Color.red; [Tooltip("用于設(shè)置未選擇時(shí)Image的顏色。")] public Color _clrUnSelect = Color.white; [HideInInspector] public List<RectTransform> _lstSelectPoints = new List<RectTransform>();//已選擇連接點(diǎn) [HideInInspector] public List<int> _lstPassword = new List<int>();//以輸入密碼 [HideInInspector] public Action<bool> onInputState;//true為開始輸入,false為結(jié)束輸入 private bool _isPressing = false;//是否按下 private Vector2 _vtPressPos;//按下點(diǎn)坐標(biāo) private float _fDistance;//距離 private float _fDegree;//夾角 private Matrix4x4 _matrixTrans;//變換矩陣 private Vector2[] _vertexPos = new Vector2[4];//頂點(diǎn)數(shù)組 private Vector2 _tempPos; void Awake() {  InitEnterEvent();//初始化所有連接點(diǎn)的消息  ClearLines();//清空相關(guān)數(shù)據(jù) } void Update() {  if (!IsPressed())  {//當(dāng)未按下時(shí)清空是數(shù)據(jù)   ClearLines();  } } bool IsPressed() {  //觸摸  if (Input.touchCount > 0)  {   switch (Input.touches[0].phase)   {    case TouchPhase.Began:     _isPressing = true;     if (onInputState != null)     {      onInputState(true);//狀態(tài)改變     }     break;    case TouchPhase.Ended:    case TouchPhase.Canceled:     _isPressing = false;     if (onInputState != null)     {      onInputState(false);//狀態(tài)改變     }     break;   }   _vtPressPos = Input.touches[0].position;  }  else  {   //鼠標(biāo)   if (Input.GetMouseButtonDown(0))   {    _isPressing = true;    if (onInputState != null)    {     onInputState(true);//狀態(tài)改變    }   }   if (Input.GetMouseButtonUp(0))   {    _isPressing = false;    if (onInputState != null)    {     onInputState(false);//狀態(tài)改變    }   }   _vtPressPos = Input.mousePosition;  }  return _isPressing; } void OnPostRender() {  DrawLines();//畫所有線 } void OnGUI() {  string msg = "";  msg += "是否正在輸入:" + IsPressed() + "/n";  msg += "密碼:";  for (int i = 0; i < _lstPassword.Count; i++)  {   msg += _lstPassword[i] + ",";  }  GUIStyle guiStyle = new GUIStyle();  guiStyle.normal.textColor = new Color(1, 1, 1); //設(shè)置字體顏色  guiStyle.fontSize = 75;  //設(shè)置字體大小  GUILayout.Label(msg, guiStyle); } void InitEnterEvent() {  //為每個(gè)點(diǎn)添加Enter事件  _lstPoints.ForEach((rtTrans) =>  {   EventTrigger trigger = rtTrans.GetComponent<EventTrigger>();   if (trigger == null)   {    trigger = rtTrans.gameObject.AddComponent<EventTrigger>();   }   //添加事件   EventTrigger.Entry entryEnter = new EventTrigger.Entry();   entryEnter.eventID = EventTriggerType.PointerEnter;//進(jìn)入事件   EventTrigger.TriggerEvent evtEnter = new EventTrigger.TriggerEvent();   evtEnter.AddListener(OnSelectPoint);   entryEnter.callback = evtEnter;   trigger.triggers.Add(entryEnter);   EventTrigger.Entry entryDown= new EventTrigger.Entry();   entryDown.eventID = EventTriggerType.PointerDown;//按下事件   EventTrigger.TriggerEvent evtDown = new EventTrigger.TriggerEvent();   evtDown.AddListener(OnSelectPoint);   entryDown.callback = evtDown;   trigger.triggers.Add(entryDown);  }); } public void OnSelectPoint(BaseEventData obj) {  //轉(zhuǎn)換數(shù)據(jù)類型  PointerEventData data = obj as PointerEventData;  GameObject target = null;  if (null != data.pointerEnter)  {   target = data.pointerEnter;  }  else if (null != data.pointerPress)  {   target = data.pointerPress;  }   AddSelectPoint(target);//添加選擇連接點(diǎn) } void AddSelectPoint(GameObject obj) {  if (IsPressed() && null != obj)  {   //將未連接的點(diǎn)添加到需要連接的點(diǎn)的列表中去   RectTransform rtTrans = obj.GetComponent<RectTransform>();   if (null != rtTrans && !_lstSelectPoints.Contains(rtTrans))   {    //添加到繪制列表    _lstSelectPoints.Add(rtTrans);    //添加密碼序列    _lstPassword.Add(_lstPoints.IndexOf(rtTrans));    //改變顏色    rtTrans.GetComponent<Image>().color = _clrSelect;   }  } } void ClearLines() {  //清空選擇及密碼列表  _lstSelectPoints.Clear();  _lstPassword.Clear();  //還原顏色  _lstPoints.ForEach((rtTrans) =>  {   rtTrans.GetComponent<Image>().color = _clrUnSelect;  }); } void DrawLine(Vector2 vtStart, Vector2 vtEnd) {  _tempPos = vtEnd - vtStart;  _fDistance = Vector3.Distance(Vector3.zero, _tempPos);//距離  _fDegree = Vector3.Angle(_tempPos, Vector3.right);//與x軸正方向的夾角  //判斷旋轉(zhuǎn)方向,逆時(shí)針為正,順時(shí)針為付  if (_tempPos.y < 0)  {   _fDegree *= -1;  }  //設(shè)置變換矩陣  _matrixTrans.SetTRS(vtStart, Quaternion.Euler(0, 0, _fDegree), Vector3.one);//設(shè)置變換矩陣  //設(shè)置繪制頂點(diǎn)坐標(biāo)  _vertexPos[0].x = 0;  _vertexPos[0].y = -_nHalfHeight;  _vertexPos[1].x = 0;  _vertexPos[1].y = _nHalfHeight;  _vertexPos[2].x = _fDistance;  _vertexPos[2].y = _nHalfHeight;  _vertexPos[3].x = _fDistance;  _vertexPos[3].y = -_nHalfHeight;  //繪制  GL.PushMatrix();  GL.LoadPixelMatrix();//使(0,0,0)為左下角,(Screen.width,Screen.height,0)為右上角  GL.MultMatrix(_matrixTrans);  GL.Begin(GL.QUADS);//繪制四邊形  for (int n = 0; n < 4; n++)  {   GL.Vertex(_vertexPos[n]);  }  GL.End();  GL.PopMatrix(); } void DrawLines() {  //設(shè)置線的材質(zhì)  _matLineColor.SetPass(0);  //連接已選擇的點(diǎn)  for (int nIndex = 0; nIndex < _lstSelectPoints.Count - 1; nIndex++)  {   DrawLine(_lstSelectPoints[nIndex].position, _lstSelectPoints[nIndex + 1].position);  }  //連接到Press點(diǎn)  if (IsPressed() && _lstSelectPoints.Count > 0)  {   DrawLine(_vtPressPos, _lstSelectPoints[_lstSelectPoints.Count - 1].position);  } }}

上面的實(shí)現(xiàn)中都有注明,如有不清楚的地方請(qǐng)留言。繪制主要在DrawLine函數(shù)中。

然后將GraphicUnLockManager類添加到MainCamera上,只有這樣OnPostRender才會(huì)被正確調(diào)用,使線能夠在場景中的物體都渲染完成后再繪制。

創(chuàng)建連接點(diǎn),如下設(shè)置:

設(shè)置GraphicUnLockManager,如下設(shè)置:

接下來就可以在編輯器中運(yùn)行看看結(jié)果了!按下鼠標(biāo)左鍵開始選擇,釋放結(jié)束選擇,效果如下:

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 图们市| 金溪县| 宝兴县| 霍城县| 综艺| 池州市| 清流县| 溆浦县| 临高县| 班玛县| 崇礼县| 卓尼县| 八宿县| 镇远县| 京山县| 栖霞市| 章丘市| 玉田县| 康马县| 胶州市| 华坪县| 星子县| 务川| 微山县| 朔州市| 潍坊市| 郁南县| 澜沧| 东丰县| 南部县| 临泽县| 黔南| 仁布县| 潞西市| 宕昌县| 凌云县| 靖宇县| 黔南| 肥城市| 大厂| 剑河县|