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

unity3d 九宫密码锁的更多相关文章

  1. Android实现九宫拼图过程记录

    算法老师给了一份关于九宫拼图的算法过程用C++写的,让我们自己封装,成为一个有图形界面的工程,我接触过android,c++的mfc,Java的图形界面JUI,网页的css.html.javascri ...

  2. Unity3d学习 预设体(prefab)的一些理解

    之前一直在想如果要在Unity3d上创建很多个具有相同结构的对象,是如何做的,后来查了相关资料发现预设体可以解决这个问题! 预设体的概念: 组件的集合体 , 预制物体可以实例化成游戏对象. 创建预设体 ...

  3. Unity3d入门 - 关于unity工具的熟悉

    上周由于工作内容较多,花在unity上学习的时间不多,但总归还是学习了一些东西,内容如下: .1 根据相关的教程在mac上安装了unity. .2 学习了unity的主要的工具分布和对应工具的相关的功 ...

  4. TDD在Unity3D游戏项目开发中的实践

    0x00 前言 关于TDD测试驱动开发的文章已经有很多了,但是在游戏开发尤其是使用Unity3D开发游戏时,却听不到特别多关于TDD的声音.那么本文就来简单聊一聊TDD如何在U3D项目中使用以及如何使 ...

  5. warensoft unity3d 更新说明

    warensoft unity3d 组件的Alpha版本已经发布了将近一年,很多网友发送了改进的Email,感谢大家的支持. Warensoft Unity3D组件将继续更新,将改进的功能如下: 1. ...

  6. Unity3D框架插件uFrame实践记录(一)

    1.概览 uFrame是提供给Unity3D开发者使用的一个框架插件,它本身模仿了MVVM这种架构模式(事实上并不包含Model部分,且多出了Controller部分).因为用于Unity3D,所以它 ...

  7. Unity3D 5.3 新版AssetBundle使用方案及策略

    1.概览 Unity3D 5.0版本之后的AssetBundle机制和之前的4.x版本已经发生了很大的变化,一些曾经常用的流程已经不再使用,甚至一些老的API已经被新的API所取代. 因此,本文的主要 ...

  8. 山寨Unity3D?搜狐畅游的免费开源游戏引擎Genesis-3D

    在CSDN上看到了<搜狐畅游发布3D游戏引擎Genesis-3D 基于MIT协议开源>(http://www.csdn.net/article/2013-11-21/2817585-cha ...

  9. 从Unity3D编译器升级聊起Mono

    接前篇Unity 5.3.5p8 C#编译器升级,本文侧重了解一些Mono的知识. Unity3D的编译器升级 新升级的Mono C#编译器(对应Mono 4.4) Unity编辑器及播放器所使用的M ...

随机推荐

  1. canvas学习之折线图

    接着上一张柱状图讲,我们是使用折线图: import {canvasPoint} from '../../assets/js/canvas';import {basicInfo,histogramMo ...

  2. MySQL表类型和存储引擎

    一.基本介绍 从事务安全性的角度,可以把存储引擎分为两大类: 事务安全: BDB和innodb; 事务非安全性: myisam 和 memory 二.存储引擎的比较图 看你的mysql当前默认的存储引 ...

  3. 2018-2019 ACM-ICPC Brazil Subregional Programming Contest

    A:留坑 B:二维sg函数,特判边界情况 //#pragma GCC optimize(2) //#pragma GCC optimize(3) //#pragma GCC optimize(4) / ...

  4. bzoj4176. Lucas的数论 杜教筛

    题意:求\(\sum_{i=1}^n\sum_{j=1}^nd(ij),d是约数个数函数\) 题解:首先有一个结论\(d(ij)=\sum_{x|i}\sum_{y|j}[(i,j)==1]\) 那么 ...

  5. 【JS】【4】字符串数字比较大小

    两个转换函数: parseInt():把值转换成整数 parseFloat():把值转换成浮点数 也有其他方法,详情请看参考博客,但个人认为转换函数是最好的方法 参考文档: 1,js.jquery字符 ...

  6. HTML5 <li> <ol> <ul> 用法

    定义和用法 <li> 标签定义列表项目. <li> 标签可用在有序列表 (<ol>) 和无序列表 (<ul>) 中. HTML 与 XHTML 之间的差 ...

  7. 时间序列(六): 炙手可热的RNN: LSTM

    目录 炙手可热的LSTM 引言 RNN的问题 恐怖的指数函数 梯度消失* 解决方案 LSTM 设计初衷 LSTM原理 门限控制* LSTM 的 BPTT 参考文献: 炙手可热的LSTM 引言 上一讲说 ...

  8. Vue keep-alive总结

    <keep-alive>是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM. <keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是 ...

  9. new 和 delete

    new 和 delete 众所周知,C中的malloc和free是用来申请和释放内存的,相应的C++中也有对应的申请和释放内存的操作,即是new和delete,但是C++的new和delete比C中的 ...

  10. openssl安装/更新教程(CentOS)

    1.下载openssl 下载链接:https://www.openssl.org/source/snapshot/ 里边是当前仍支持版本的快照:同版本不同日期内容可能不同的,所以下载一般下对应版本的最 ...