[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             }

 

posted @ 2020-05-25 23:03  wayneWy  阅读(2778)  评论(0编辑  收藏  举报