Unity实现移动端手势解锁功能

 更新时间:2020年11月3日 15:20  点击:1607

本文实例为大家分享了Unity实现移动端手势解锁的具体代码,供大家参考,具体内容如下

一、效果演示

二、实现思路

——当鼠标选中一个密码按钮时开始记录输入的数字和鼠标的起始位置
——当鼠标按下过程中,始终根据记录的鼠标起始位置和当前鼠标的位置两个点绘制线段并添加到线段的列表中,并一直清空掉列表中除了最后一个线段外的其余线段
——当鼠标按下过程中,如果有覆盖到其他的密码按钮,则根据起始的密码按钮与当前的密码按钮两个点绘制线段并重新记录输入的数字和鼠标起始位置

三、实现过程

——创建9个密码块,并依次命名为1、2.....9,并设置tag为PasswordBlock

——编写生成LineRenderer的方法,初始化LineRenderer属性的方法,绘制线的方法以及清空线的方法
注意绘制线段时,需要将起始位置和结束位置的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>();//存储每个LineRenderer的列表
 private List<GameObject> passwordButtonList = new List<GameObject>();//存储每个密码按钮的列表
 
 private Vector3 startPos;//鼠标开始的位置
 
 //线的参数
 public Color startColor = Color.black;//线开始的颜色
 public Color endColor = Color.black;//线结束的颜色
 public float width = 0.1f;//线宽度
 public int vertices = 90;//顶点数
 
 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>
 /// 绘制已经连线完成的线段
 /// </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);//每次开始拖拽时清空所有线段
 
 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);//绘制已经连线完成的线段
 
 RecordPassword(go);//记录密码
 }
 }
 
 #region 线段相关操作
 
 /// <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>
 /// 两点绘制一条直线
 /// </summary>
 /// <param name="_uncompleteLR">线段</param>
 /// <param name="startPos">起始位置</param>
 /// <param name="endPos">结束位置</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>
 /// 清除未完成的线段(每次拖拽结束时清除)
 /// </summary>
 private void ClearUnCompleteLine()
 {
 if (lrList.Count == 0)
 {
 return;
 }
 
 GameObject go = lrList[lrList.Count - 1];
 Destroy(go);
 lrList.Remove(go);
 }
 
 #endregion
 
 #region 工具方法
 
 /// <summary>
 /// 当前密码块是否存在于密码块列表中
 /// </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>
 /// 屏幕坐标转世界坐标
 /// </summary>
 /// <param name="screenPos">屏幕坐标位置</param>
 /// <param name="camera">相机</param>
 /// <returns>转换后的世界坐标</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
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。

[!--infotagslink--]

相关文章

  • Unity时间戳的使用方法

    这篇文章主要为大家详细介绍了Unity时间戳的使用方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • Unity中 ShaderGraph 实现旋涡传送门效果入门级教程(推荐)

    通过Twirl 旋转节点对Gradient Noise 梯度噪声节点进行操作,就可得到一个旋转的旋涡效果。具体实现代码跟随小编一起通过本文学习下吧...2021-07-11
  • Unity延时执行的多种方法小结

    本文主要介绍了4种延时执行的方法,主要包括Update计时器,Invoke,协程,DoTween,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-07-07
  • Unity shader实现遮罩效果

    这篇文章主要为大家详细介绍了Unity shader实现遮罩效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • unity 如何判断鼠标是否在哪个UI上(两种方法)

    这篇文章主要介绍了unity 判断鼠标是否在哪个UI上的两种实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-10
  • Unity实现换装系统

    这篇文章主要为大家详细介绍了Unity实现换装系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-04-11
  • 利用unity代码C#封装为dll的步骤分享

    这篇文章主要给大家介绍了关于利用unity代码C#封装为dll的相关资料,文中通过图文将实现的方法介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
  • Unity Shader实现径向模糊效果

    这篇文章主要为大家详细介绍了Unity Shader实现径向模糊效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-08-09
  • unity 实现摄像机绕某点旋转一周

    这篇文章主要介绍了unity 实现摄像机绕某点旋转一周,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-12
  • Unity实现截图功能

    这篇文章主要为大家详细介绍了Unity实现截图功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • Unity中EventTrigger的几种使用操作

    这篇文章主要介绍了Unity中EventTrigger的几种使用操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-10
  • Unity Shader实现2D水流效果

    这篇文章主要为大家详细介绍了Unity Shader实现2D水流效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • Unity 按钮添加OnClick事件操作

    这篇文章主要介绍了Unity 按钮添加OnClick事件操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-10
  • Unity使用EzySlice实现模型多边形顺序切割

    这篇文章主要为大家详细介绍了Unity使用EzySlice实现模型多边形顺序切割,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-11-03
  • Unity Shader实现描边OutLine效果

    这篇文章主要为大家详细介绍了Unity Shader实现描边OutLine效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • Unity Shader实现裁切效果

    这篇文章主要为大家详细介绍了Unity Shader实现裁切效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • unity实现车方向盘转动效果

    这篇文章主要为大家详细介绍了unity实现车方向盘转动效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • Unity实现汽车前后轮倒车轨迹计算

    这篇文章主要为大家详细介绍了Unity实现汽车前后轮倒车轨迹计算,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-13
  • Unity 点击UI与点击屏幕冲突的解决方案

    这篇文章主要介绍了Unity 点击UI与点击屏幕冲突的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-10
  • Unity实现虚拟摇杆效果

    这篇文章主要为大家详细介绍了Unity实现虚拟摇杆效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25