unity3d 九宫密码锁
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 九宫密码锁的更多相关文章
- Android实现九宫拼图过程记录
算法老师给了一份关于九宫拼图的算法过程用C++写的,让我们自己封装,成为一个有图形界面的工程,我接触过android,c++的mfc,Java的图形界面JUI,网页的css.html.javascri ...
- Unity3d学习 预设体(prefab)的一些理解
之前一直在想如果要在Unity3d上创建很多个具有相同结构的对象,是如何做的,后来查了相关资料发现预设体可以解决这个问题! 预设体的概念: 组件的集合体 , 预制物体可以实例化成游戏对象. 创建预设体 ...
- Unity3d入门 - 关于unity工具的熟悉
上周由于工作内容较多,花在unity上学习的时间不多,但总归还是学习了一些东西,内容如下: .1 根据相关的教程在mac上安装了unity. .2 学习了unity的主要的工具分布和对应工具的相关的功 ...
- TDD在Unity3D游戏项目开发中的实践
0x00 前言 关于TDD测试驱动开发的文章已经有很多了,但是在游戏开发尤其是使用Unity3D开发游戏时,却听不到特别多关于TDD的声音.那么本文就来简单聊一聊TDD如何在U3D项目中使用以及如何使 ...
- warensoft unity3d 更新说明
warensoft unity3d 组件的Alpha版本已经发布了将近一年,很多网友发送了改进的Email,感谢大家的支持. Warensoft Unity3D组件将继续更新,将改进的功能如下: 1. ...
- Unity3D框架插件uFrame实践记录(一)
1.概览 uFrame是提供给Unity3D开发者使用的一个框架插件,它本身模仿了MVVM这种架构模式(事实上并不包含Model部分,且多出了Controller部分).因为用于Unity3D,所以它 ...
- Unity3D 5.3 新版AssetBundle使用方案及策略
1.概览 Unity3D 5.0版本之后的AssetBundle机制和之前的4.x版本已经发生了很大的变化,一些曾经常用的流程已经不再使用,甚至一些老的API已经被新的API所取代. 因此,本文的主要 ...
- 山寨Unity3D?搜狐畅游的免费开源游戏引擎Genesis-3D
在CSDN上看到了<搜狐畅游发布3D游戏引擎Genesis-3D 基于MIT协议开源>(http://www.csdn.net/article/2013-11-21/2817585-cha ...
- 从Unity3D编译器升级聊起Mono
接前篇Unity 5.3.5p8 C#编译器升级,本文侧重了解一些Mono的知识. Unity3D的编译器升级 新升级的Mono C#编译器(对应Mono 4.4) Unity编辑器及播放器所使用的M ...
随机推荐
- 关于Android 主题的那些事
最近遇到了一个问题,主题的ActionBar的Title 颜色是黑色的 但是我的主界面由于用的是CoordinateLayot所以是白色的 整个黑色的就很难看 所以也想要把ActionBar 的Tit ...
- android AIDL 语言用法
跨进程通信可以用AIDL语言 这里讲述下如何使用AIDL语言进行跨进程通信 文章参考 <设计模式>一书 demo结构参考 主要的文件类有:IBankAidl.aidl java文件:Aid ...
- Confluence 6 内容在空间中是如何组织的
你可以将空间考虑为一个容器,在这个容器中保持了有关你项目中所有重要的东西,包括小组,项目或者项目相关的工作.这些东西有很高的自主性,这表示的是每个空间都有自己的的页面,文件,评论以及 RSS 新闻源. ...
- php 中文字符串反转
/** * * 中文字符串倒序 * @param str $str * return str **/ function str_en_desc($str){ $len=mb_strlen($str); ...
- vue嵌套路由--params传递参数
在嵌套路由中,父路由向子路由传值除了query外,还有params,params传值有两种情况,一种是值在url中显示,另一种是值不显示在url中. 1.显示在url中index.html <d ...
- 快速学习HTML
1.先写基本的框架标签 2.HTML基本标签 段落标签 <p></p> 空格标签 标题标签 <h1></h1>……<h6></h6 ...
- zzw原创_expdp及impdp中的exclude及include参数的那点事
zzw原创:转载请注明出处 在oracle的expdp 及imdpd命令中,exclude及include参数还是有一些要注意的地方,特别是涉及选择性条件时. 一.通用 1.exclude及inclu ...
- java中super和this的使用
要说super就先要说this."this",作为一个特殊的关键字,它的规则如下: 1.可以表示构造函数传递.this(a,b)表示调用另外一个构造函数.这里面的this就是一个特 ...
- 前端开发VScode常用插件
名称 功能 Auto Close Tag 自动闭合HTML标签 Auto Import Typescript 自动import提示 Auto Rename Tag 修改HTML标签时,自动修改匹配的标 ...
- php composer 使用 以及 psr0和psr4的真正区别
composer 使用 项目和库之间唯一的区别是,你的项目是一个没有名字的包 包名不区分大小写,但惯例是使用小写字母,并用连字符作为单词的分隔 入门比较好资源: 官网适合读一遍 https://do ...