[Unity]关于Unity中的触摸类Input.Touch以及简单的虚拟摇杆实现
InputTouch
使用Unity开发的游戏大多是移动端游戏,而一些移动端游戏完全使用触摸操作而不是点击Button
Unity使用Input.Touch来管理触摸操作
Input.TouchCount获得当前触摸的数量,这个数量多少取决于设备,通常使用触摸之前都用这个判断下
Input.GetTouch[index],下标决定了获取当前触摸点的哪一个(先后顺序)
针对触摸点,有很多状态,由枚举TouchPhase列出,Input.GetTouch[index].phase
TouchPhase.Began:开始触摸时触发,仅一次
TouchPhase.Moved:触摸保持触摸且移动的时候触发,注意如果仅仅保持触摸但是不移动,这个不会触发
TouchPhase.Stationary:触摸保持且静止时触发,和上面相反,如果不动则会触发这个,所以是否在触发中可以仅用TouchCount判断或者这两个条件同时满足时,都代表"按住"这个状态
TouchPhase.Ended:手指离开屏幕时触发,仅一次
TouchPhase.Canceled:奇怪的枚举,说是当触摸数量超过最大时,Unity会停止追踪触摸而触发
虚拟摇杆的简单实现
通过上面的APi和状态枚举,虚拟摇杆将变得简单
0:获取当前状态,这里加了个安卓用触摸,编辑器用鼠标的判断,ios一样的
1 bool _beginTouch = false;//Update之外
2
3 //Update之内
4 bool windowsOrEditor = Application.isEditor || Application.platform != RuntimePlatform.Android;
5 bool inputDown = windowsOrEditor
6 ? (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject())
7 : (Input.touchCount > 0 && !_beginTouch && !EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId));
8 bool inputStay = windowsOrEditor
9 ? Input.GetMouseButton(0)
10 : _beginTouch && Input.touchCount > 0;
11 bool inputUp = windowsOrEditor
12 ? Input.GetMouseButtonUp(0) || !Input.GetMouseButton(0) : Input.touchCount <= 0 && _beginTouch;
1:在TouchPhase.Began状态下,可以获取当前点在屏幕的坐标,Input.GetTouch[index].position;,记录为坐标起点_startPos(我这里转到了UGUI某组件下的物体坐标系中)
1 if (inputDown)//update()中
2 {
3 //记录初始位置
4 _beginTouch = true;
5 Vector2 pos;
6 RectTransformUtility.ScreenPointToLocalPointInRectangle(_moveTip.parent as RectTransform,
7 Input.mousePosition, null, out pos);
8 }
2:在TouchPhase.Stationary和TouchPhase.Moved(或者直接判断TouchCount>0)状态中,用移动后的坐标减去起点_startPos(Input.GetTouch[index].position - _startPos,顺序不能变,由起点指向当前点),获得新向量_offsetPos,可以获得它们之间的距离(_offsetPos.magnitude,就是向量减法求模),可以根据距离大于多少后,做出之后的操作
3:同样在2的状态下,给起点一个默认方向_startDir,(如美术给的图默认向下,就是vector2.down),将_offsetPos归一化后和_startDir点乘(Vector2.Dot()),获得向量夹角的余弦CosA,利用反余弦(Mathf.Acos()结果是弧度,需要乘Mathf.Rad2Deg转角度)求出角度,给美术资源做旋转Z轴即可(正向还是反向通过坐标x对比)
1 else if (inputStay)
2 {
3 Vector2 pos;
4 RectTransformUtility.ScreenPointToLocalPointInRectangle(_moveTip.parent as RectTransform,
5 Input.mousePosition, null, out pos);
6 float angleCos = Vector2.Dot((pos - _moveTip.anchoredPosition).normalized, Vector2.down);
7 float angle = Mathf.Acos(angleCos) * Mathf.Rad2Deg;
8 float dis = pos.x < _moveTip.anchoredPosition.x ? -1 : 1;
9
10 }
11 else if (inputUp)
12 {
13 _beginTouch = false;
14 }
最新文章
- C#的四种Timer介绍
- Force StyleCop to Ignore a File
- nova-scheduler start flow
- paip.网页右键复制菜单限制解除解决方案
- LeetCode OJ 题解
- 全局变量&;局部变量
- for循环里面的判断条件
- SoundPool 音频播放 详解 示例
- Week2(9月19日):增加一个CodeFirst的例子来说明
- PostgreSQL 使用 PreparedStatement 导致查询慢的分析
- poj 1182 食物链 带权并查集
- C++ map multimap
- bzoj 4198: [Noi2015]荷马史诗
- find the nth digit(二分查找)
- 腾讯地图 API 调用入门
- MongoDB的ORM框架——Morphia
- MySQL远程连接问题解决方法
- Python 字典 fromkeys()方法
- 微信小程序 - 表单验证插件WxValidate使用
- python __setattr__和__getattr__
热门文章
- [数据与分析可视化] D3入门教程1-d3基础知识
- AspNetCore管道
- linux环境编程(1): 实现一个单元测试框架
- 系列化和反序列化的概述-对象的序列化_Object Output Stream类
- 重写Object类的equals方法-Objects类的equals方法
- 如何通过Java代码向Word文档添加文档属性
- Linux CentOS7查看软件包安装时间
- Vue09 事件
- 一种无损更换iPhone手机铃声方案(无需数据线)
- c++ 程序通用多线程单例设计 c++ web 框架设计经验谈