写在前面

继续填坑了。这次是讲手机端。

  1. 电脑端 [ 按我跳转 ]

    1. 键盘按键控制 [ 上文内容 ]
    2. 鼠标点击控制 [ 上文内容 ]
  2. 手机端
    1. 触屏控制 [ 本文内容 ]
    2. 手势控制 [ 本文内容 ]
    3. 重力控制 [ 下文内容 ]
    4. 陀螺仪控制 [ 下文内容 ]

本文的限制:接上文,本文主要讲在手机检查操作的方法,至于之后执行的相关命令,读者完全可大开脑洞。如果你有什么好的想法,欢迎告诉我!

正文

1 触屏控制

试想象神庙逃亡这类游戏,你能想到些什么操作方式?通常玩家会使用手指手势来操控游戏。所谓的手势指的是,类似下划,上划一类的操作方式。

检测触屏,需要用到,由MonoBehaviour提供的OnMouseDown()方法。这个方法在电脑和手机端都可以调用。

MonoBehaviour.OnMouseDown()​docs.unity3d.com

例子

void OnMouseDown()
{Debug.Log("The Button is pressed"+this.name);
}

这个方法可以检测用户对GUI Element (比如GUI Texture)和碰撞体触屏点击。因此通常这个方法不会放进主程序的Update内,这是因为只要我们给点击相关物件的代码加入这个方法,那么当它被触摸时,就会调用OnMouseDown方法。

Unity Remote可以为电脑和手机提供接口,让游戏画面可以通过Unity的play按钮,在手机上同步呈现。读者可自行到goolg play商店下载安装。

然而,假设你为你的一些GUI button加入了这个方法,并做一些输出之后,你会发现一个问题。如果你试着同时按下两个按钮,会发现什么信息也没有出现,或者只出现其中一个按钮被按下的信息。

绝大部分的游戏都需要多点触控,所以上面的方法显然还行不通。

先来了解多点触控的概念。看图

当玩家的手触碰到手机屏幕时,Unity便会触发触碰事件,我们將手指与屏幕触碰过程中的所有资讯称为触控信息。Unity会为我们识别每一个触控信息所携带的ID、触控点位置、状态、点击次数等资讯。

聪明的你或许已经注意到了,每个触控点都会有一个属于它们的状态。当我们第一次触碰到屏幕时,第一笔的触控信息会被记录,并且设定状态为Begin。而当我们在继续触碰的情况下滑动手指,触控点的状态便更改为Moved。如果我们只是按住而没有滑动的动作,状态便设定为Stationary。当我们把手指离开屏幕,状态变为Ended。当然,即使我们的手指已经离开屏幕,Unity仍然会保留这笔状态一段时间,这是为了可以让那些短时间内再次触碰的动作减少资源消耗。当我们再次触碰屏幕,Unity便会再一次追踪触控信息。每次成功的触控追踪都会被记录为触控事件,并且让资料中的点击次数加一。

如果玩家长时间不碰屏幕,或手机已经离开并触碰屏幕的其他地方。由于系统追踪不到原先的触控点,便会将该点的状态记录为Canceled。值得注意的是,在状态Moved中,触控信息会记录额外的位移与时间信息,供开发者作手势判别。这是我们下一个讨论内容,这里就先介绍到这。

上文提到的关于触控信息的内容,在Unity中会被存储在Touch类中,读者可前往文档详细阅读。

Unity - Scripting API: Touch​docs.unity3d.com

另外,触控点的状态则定义在TouchPhase类的结构中。这是一个Enum类别的数据。有Began, Moved, Stationary, Ended, Canceled五个状态。

Unity - Scripting API: TouchPhase​docs.unity3d.com

小实践:多点触控

为了做到这一点,我们需要抛弃OnMouseDown这个方法,改而在游戏刷新的过程中不断检测触控的数量,根据触控的次数来作对应的操作命令

void Update(){int touchCount = Input.touchCount;  // 获取触控点个数if (touchCount > 0){  // 若玩家有触碰到屏幕for (int i = 0 ; i < touchCount ; i++ ){Touch touch = Input.GetTouch(i);  // 将触控点存储if (this.getTexture.HitTest(touch.position)){if (this.name == "Forward"){Debug.Log("Forward");}else if (this.name == "Jump"){Debug.Log("Jump!");} // 若触控点有碰到按钮,则判断是按下了哪个按钮}}}
}

接下来,你可以把这段代码挂到任何一个需要使用到触控检测的GUI element上。HitTest()是GUI element的方法,你可以将触控点的位置传入来作检测。如果触控点在GUI element的范围内,则回传true,反之回传false。

一些问题和可行的解决方案

当你试着实现多点触控时,你会发现一些事情,如果你一直按住某个按钮。比如Jump键,那么console信息栏中就会一直输出"Jump!"的信息。换句话说,按钮事件会一直处在被触发的状态。这好说,因为手指一直在按钮上,而这段代码则被写在Update中,那么每一帧都会执行这端代码,当然信息会一直输出了。这时读者可以使用上文提到的TouchPhase类进行点击状态的判断,进而减轻系统输出负担。

2 手势检测

多点触控的用处很多,手势的侦测就是其中一种。

source:wikipedia

当我们游玩神庙逃亡时,如果我们手指向上滑动,那么角色就会做出一个跳跃的动作。当然这里很可能是没有实现多点触控的,笔者只是想让读者思考手势检测的例子。

延申前文所提到的光线投射的概念,在结合本文的触控检测概念,就可以写出很美妙的手势操作判断了。笔者假设读者需要开发有多点触控功能的应用,因此延续上文的代码。

void Update(){int touchCount = Input.touchCount;Camera cam = Camera.main;if (touchCount > 0){for (int i = 0 ; i < touchCount ; i++ ){Touch touch = Input.GetTouch(i);if (touch.phase == TouchPhase.Bagan)){ // 如果触控点状态为按下Ray ray = cam.ScreenPointToRay(touch.position);  // 从触控点位置产生一条RayRaycastHit hit;  // 用来检测碰撞的Rayif (Physics.Raycast(ray, out hit)){Debug.Log(hit.transform.name); // 输出点击物体名称}}}}
}

你可能会觉得,这不就是一个【按下】的功能嘛!说好的手势判断呢!哎先别打我啊,我们来看看程式设计的概念:如果玩家的手碰到了屏幕,再做一个向上滑动的手势后,就向上跳。设计手势时,可以善用触控点的状态资讯,就是TouchPhase。

我们可以把这个概念写作这样的流程:

  1. 玩家触碰到屏幕 - 触控点状态:TouchPhase.Began
  2. 玩家向上滑动 - 触控点状态:TouchPhase.Moved
  3. 玩家手指离开 - 触控点状态:TouchPhase.Ended

好的,代码可以写成这样:

...
int touchCount = Input.touchCount;Camera cam = Camera.main;if (touchCount > 0){for (int i = 0 ; i < touchCount ; i++ ){Touch touch = Input.GetTouch(i);if (touch.phase == TouchPhase.Bagan)){ // 如果触控点状态为按下}else if (touch.phase == TouchPhase.Moved)){ // 如果触控点状态为移动}else if (touch.phase == TouchPhase.Ended)){ // 如果触控点状态为离开屏幕}}}

读者可以看到,现在的代码被分成了三个区块,分别处理按下、移动和离开屏幕后的对应事件。由于我们提到的例子只需要检测向上划与否,所以处理按下时,只需检查玩家是否按到游戏内的碰撞体,并记录位置,方便计算即可。

按下的处理:

Vector2 startTouchPos; // pre-defined
Camera cam = Camera.main; // pre-defined
...if (touch.phase == TouchPhase.Bagan)){ // 如果触控点状态为按下Ray ray = cam.ScreenPointToRay(Input.position);RaycastHit hit;if (Physics.Raycast(ray, out hit)){Debug.Log(hit.transform.name); // 输出点击物体名称startTouchPos = touch.position;}
}
...

移动的处理:

...
if (touch.phase == TouchPhase.Moved)){ // 如果触控点状态为按下if ( touch.position.y - startTouchPos.y > 0){Debug.Log("Jump!");}
}
...

离开屏幕的处理:

...
if (touch.phase == TouchPhase.Ended)){ // 如果触控点状态为按下startTouchPos = Vector2.zero;
}
...

如果有讲错或你有更好的实现方法请务必告诉我,我会继续填坑的了。谢谢!

unity 手机上获取手指触摸位置_Unity 操作检测的各种实现#2手机端 - 触屏与手势...相关推荐

  1. Unity 在zSpace上使用鼠标控制相机旋转和鼠标指引式放大缩小,在触屏上手势位置为中心放大缩小

    在zSpace上使用鼠标控制相机旋转和鼠标指引式放大缩小,在触屏上手势位置为中心放大缩小 鼠标和触屏的操作 下面展示一些 内联代码片. using System; using System.Colle ...

  2. Android 手机上获取手机当前上网IP地址(手机网关给手机号分配的IP)

    Android 手机上获取手机当前上网IP地址 (手机网关给手机号分配的IP) 每个手机上网通过移动网关的时候,网关都会给该手机号分配一个IP地址(当然这个IP地址会在下线上线后会改变,网关都有记录的 ...

  3. springboot vue 小程序小区物业管理系统【物业手机版(小程序)+物业系统后端+物业系统前端+业主手机端(小程序)】(功能较丰富)

    springboot vue 小程序小区物业管理系统[物业手机版(小程序)+物业系统后端+物业系统前端+业主手机端(小程序)](功能较丰富) 高清视频演示: https://www.bilibili. ...

  4. Android 高德地图在华为手机上获取位置信息失败

    昨天遇到一个特别奇怪的bug,华为手机获取高德定位信息失败,调试打印数据后发现 location.getAddress()这个获取值为空,之前一直选择高精度模式,但是获取不到位置信息 //设置定位模式 ...

  5. Android 在Android手机上获取其他应用的包名及版本号

    获取Android手机上其他应用的包名及版本号方法有很多,可以通过AAPT从APK包中直接获取,也可以通过代码在手机上获取.显然,对于产品或者用户来说要获取这些信息,在手机上获取更为简便. 下面我们来 ...

  6. 如何在任何Android手机上获取手势导航

    Android's upcoming iteration (currently just called "P") contains a new gesture navigation ...

  7. 华为手机上获取不到定位信息

    项目中用到了webview,然后在H5中用到了定位功能,发现在小米手机上可以定位成功,在华为手机上定位失败.两个手机都是安卓10,因此初步排除了系统版本问题,然后因为项目中是用了腾讯TBS x5内核, ...

  8. unity panel如何设置控件位置_Unity 关于GUI与UGUI坐标 的一点问题解惑

    曾几何时,我一直被Unity里的GUI跟坐标相关的一些问题困扰.比如在做UGUI的一些位移动画,控制UI的拖拽或者就是想在UI的某个位置显示一个实体时,总是会发生很多莫名奇妙的问题.究其原因,就是因为 ...

  9. Android 手机上获取物理唯一标识码

    唯一标识码这东西在网络应用中非常有用,例如检测是否重复注册之类的. 本文转自:http://blog.csdn.net/zhang31jian/article/details/23787037 imp ...

最新文章

  1. Windows Home Server 2011 RC 安装体验
  2. 区块链应用于供应链金融的完整解决方案
  3. JZOJ 5603. 【NOI2018模拟3.27】Xjz
  4. 网易云信10月大事记
  5. android ListView 刷新卡顿问题
  6. 现在是不是很多人都不愿意在银行存钱?
  7. SpringXML方式配置bean的懒加载lazy-init
  8. 可编程ic卡 通用吗_8255可编程IC
  9. mysql书写规则_每天10分钟带你学会MySQL(二)SQL语句的基本书写规则
  10. SpringCloud注册中心集群化及如何抗住大型系统的高并发访问
  11. 全面超越人类!Google称霸SQuAD,BERT横扫11大NLP测试
  12. MFC字符串CString分割函数 简洁 C++
  13. C/C++常见面试题整理
  14. 数据--第27课 - 初始斗转
  15. Python自动化办公:读取Excel数据并批量生成合同
  16. 《百词斩背单词》四级词汇(3486个)-1
  17. Excel快捷键大全 Excel常用快捷键大全
  18. ddos硬件防火墙(DDOS硬件防火墙)
  19. matlab自由落体程序,基于MATLAB的自由落体运动仿真.pdf
  20. Reactjs项目构建

热门文章

  1. 我的世界最新服务器自动打怪,我的世界服务器自动打怪脚本刀剑乱舞图
  2. Linux之kickstart全自动安装
  3. 火狐插件FoxyProxy的使用方法
  4. NRF24LE1E与NRF24LE1G的区别
  5. Java开源的CMS系统
  6. npm publish 发包报错400 Bad Request - Cannot publish over previously published version 1.0.0
  7. 新零售潮退后,其连锁管理观念依然坚挺
  8. 移动增值业务新人入职培训
  9. 网页设计实验二( 格式化文本、段落与列表)
  10. 高效沟通【管理学之四】