Unity3D使用GL实现图案解锁功能
更新时间:2020年6月25日 10:37 点击:2471
聊天是时候看到有人问如何在Unity3D的UGUI中实现图案解锁的功能,然后便试了一下。刚开始想用LineRender来实现,但又一想是要在UGUI中,然后就用了另外一种方法,即使用GL类来实现。
GL相关介绍及官方文档
实现后在Android手机上跑的效果如下:
主要实现GraphicUnLockManager类。代码如下:
using UnityEngine; using System.Collections.Generic; using System; using UnityEngine.EventSystems; using UnityEngine.UI; public class GraphicUnLockManager : MonoBehaviour { [Tooltip("含有Selectable及Image组件的UI对象,作为连接点。")] public List<RectTransform> _lstPoints = new List<RectTransform>(); [Tooltip("用于设置所画线的颜色。(可使用“unlit/Color”Shader)")] public Material _matLineColor; [Tooltip("用于设置所画线的高度。")] public int _nHalfHeight = 15; [Tooltip("用于设置选择时Image的颜色。")] public Color _clrSelect = Color.red; [Tooltip("用于设置未选择时Image的颜色。")] public Color _clrUnSelect = Color.white; [HideInInspector] public List<RectTransform> _lstSelectPoints = new List<RectTransform>();//已选择连接点 [HideInInspector] public List<int> _lstPassword = new List<int>();//以输入密码 [HideInInspector] public Action<bool> onInputState;//true为开始输入,false为结束输入 private bool _isPressing = false;//是否按下 private Vector2 _vtPressPos;//按下点坐标 private float _fDistance;//距离 private float _fDegree;//夹角 private Matrix4x4 _matrixTrans;//变换矩阵 private Vector2[] _vertexPos = new Vector2[4];//顶点数组 private Vector2 _tempPos; void Awake() { InitEnterEvent();//初始化所有连接点的消息 ClearLines();//清空相关数据 } void Update() { if (!IsPressed()) {//当未按下时清空是数据 ClearLines(); } } bool IsPressed() { //触摸 if (Input.touchCount > 0) { switch (Input.touches[0].phase) { case TouchPhase.Began: _isPressing = true; if (onInputState != null) { onInputState(true);//状态改变 } break; case TouchPhase.Ended: case TouchPhase.Canceled: _isPressing = false; if (onInputState != null) { onInputState(false);//状态改变 } break; } _vtPressPos = Input.touches[0].position; } else { //鼠标 if (Input.GetMouseButtonDown(0)) { _isPressing = true; if (onInputState != null) { onInputState(true);//状态改变 } } if (Input.GetMouseButtonUp(0)) { _isPressing = false; if (onInputState != null) { onInputState(false);//状态改变 } } _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); //设置字体颜色 guiStyle.fontSize = 75; //设置字体大小 GUILayout.Label(msg, guiStyle); } void InitEnterEvent() { //为每个点添加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;//进入事件 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) { //转换数据类型 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);//添加选择连接点 } void AddSelectPoint(GameObject obj) { if (IsPressed() && null != obj) { //将未连接的点添加到需要连接的点的列表中去 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轴正方向的夹角 //判断旋转方向,逆时针为正,顺时针为付 if (_tempPos.y < 0) { _fDegree *= -1; } //设置变换矩阵 _matrixTrans.SetTRS(vtStart, Quaternion.Euler(0, 0, _fDegree), Vector3.one);//设置变换矩阵 //设置绘制顶点坐标 _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() { //设置线的材质 _matLineColor.SetPass(0); //连接已选择的点 for (int nIndex = 0; nIndex < _lstSelectPoints.Count - 1; nIndex++) { DrawLine(_lstSelectPoints[nIndex].position, _lstSelectPoints[nIndex + 1].position); } //连接到Press点 if (IsPressed() && _lstSelectPoints.Count > 0) { DrawLine(_vtPressPos, _lstSelectPoints[_lstSelectPoints.Count - 1].position); } } }
上面的实现中都有注明,如有不清楚的地方请留言。绘制主要在DrawLine函数中。
然后将GraphicUnLockManager类添加到MainCamera上,只有这样OnPostRender才会被正确调用,使线能够在场景中的物体都渲染完成后再绘制。
创建连接点,如下设置:
设置GraphicUnLockManager,如下设置:
接下来就可以在编辑器中运行看看结果了!按下鼠标左键开始选择,释放结束选择,效果如下:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。
上一篇: Unity3D使用右键菜单打开工程
下一篇: UnityShader3实现彩光效果
相关文章
- 这篇文章主要为大家详细介绍了Unity3D UGUI实现翻书特效,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了Unity3D实现飞机大战游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-11-03
- 这篇文章主要为大家详细介绍了Unity3D使用GL实现图案解锁功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
Unity3D游戏开发数据持久化PlayerPrefs的用法详解
在本篇文章里小编给大家整理了关于Unity3D游戏开发之数据持久化PlayerPrefs的使用的相关知识点内容,需要的朋友们参考下。...2020-06-25- 这篇文章主要介绍了Unity3D基于OnGUI实时显示FPS,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了Unity3D仿写Button面板事件绑定功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了unity3D实现三维物体跟随鼠标,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这个是在网上看到的,经测试可以在电脑上运行,确实调用了本地摄像头。有需要的小伙伴可以参考下。...2020-06-25
- 这篇文章主要为大家详细介绍了Unity3D Shader实现镜子效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了Unity3D实现待机状态图片循环淡入淡出,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了Unity3D Shader实现动态屏幕遮罩效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了Unity3D使用UGUI开发原生虚拟摇杆,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了Unity3D UGUI特效之Image高斯模糊效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了Unity3D实现物体闪烁效果,类似霓虹灯、跑马灯、LED灯效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
混合语言编程—C#使用原生的Directx和OpenGL绘图的方法
本文要说的是混合C#和C/C++语言编程,在C#的Winform和WPF下使用原生的Direct和OpenGL进行绘图...2020-06-25- 这篇文章主要为大家详细介绍了Unity3D利用DoTween实现卡牌翻转效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了Unity3D实现分页系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了Unity3D实现鼠标控制视角转动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
- 这篇文章主要为大家详细介绍了Unity3D生成一段隧道网格的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-18
- 本文通过一段代码给大家详解unity3d获取系统时间,代码简单易懂,小伙伴们快来看看吧...2020-06-25