博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
unity3d 九宫密码锁
阅读量:5956 次
发布时间:2019-06-19

本文共 5190 字,大约阅读时间需要 17 分钟。

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);
}
}
}

 

另一个参考:https://blog.csdn.net/nanggong/article/details/52513729

转载于:https://www.cnblogs.com/huwenya/p/9200479.html

你可能感兴趣的文章
通过注册表修改我的文档等系统文件夹默认位置
查看>>
expdp 详解及实例
查看>>
C++中 栈的简单封装
查看>>
我的友情链接
查看>>
Linux常用命令--iconv
查看>>
varnish的了解与常用配置使用
查看>>
Product user profile information 没有导入
查看>>
DELL T410服务器U盘安装Centos7
查看>>
解读最具O2O属性—哈根达斯微信企业号的成功之道
查看>>
Sqlserver2008日志压缩
查看>>
虚拟机usb无线上网同时主机本地上网或无线无线上网
查看>>
View的事件分发机制
查看>>
Android Ndef Message解析
查看>>
mysqldump backup script
查看>>
coding4fun比赛总结
查看>>
Windows Server 2003 系统安装
查看>>
庖丁解牛获取连接状态数的awk数组命令
查看>>
5 kvm虚拟磁盘扩容
查看>>
关于Ubuntu下apt的一些用法及和yum的比较
查看>>
android随机运算器开发小结1
查看>>