FPS 游戏的 Joystick 操纵杆如何实现?

栏目: 后端 · 发布时间: 6年前

内容简介:关于Input组件,有款比较知名的插件叫Easy Touch,在许多的项目中都应用过,在Untiy的Standard Assets下也有一款官方的Input插件-CrossPlatformInput,我之前还没有使用过,所以参考了一些资料,将简单的使用教程记录一下。关键词:1.Input组件和Gesture手势

关于Input组件,有款比较知名的插件叫Easy Touch,在许多的项目中都应用过,在Untiy的Standard Assets下也有一款官方的Input插件-CrossPlatformInput,我之前还没有使用过,所以参考了一些资料,将简单的使用教程记录一下。

关键词:

1.Input组件和Gesture手势

2.Unity Remote

3.Survival Shooter官方教程

4.Joystick操纵杆实现&拖动角色旋转

现在Unity都是分模块下载,Standard Assets需要我们单独去官网下载,并安装到Unity的路径下。

FPS 游戏的 Joystick 操纵杆如何实现?

Unity的官方教程Survival Shooter便是采用Standard Assets下的CrossPlatformInput,实现Input输入部分的功能。

CrossPlatformInput比较基础,通常使用都需要进行扩展。

Unity官方的教程-Survival Shooter中便是采用CrossPlatformInput处理Input的部分,但比较精简。

导入CrossPlatformInput后,会在菜单栏上生成Mobile Input,打开并点击Enable,会弹出如下提示:

FPS 游戏的 Joystick 操纵杆如何实现?

这里有提到使用Unity Remote App的形式来测试。

顺便一道的记录下来。

Unity Remote 使用步骤:

1.去Google Play上下载Unity Remote的APK安装包,并装在目标手机上。

2.将目标手机连接到电脑,并在Unity中做如下操作:

Edit-Project Settings-Edit-Device下选择Any Android Device(我这里是使用Android测试)。

3.在目标手机运行Unity Remote,并在Unity Editor中点击Play,我们就可以通过手机来进行远程的测试了,省去了重复安装APK包的麻烦,但他也有许多的限制,它仅仅是渲染的投射和一些基本的操作,作用并不大,但仅是看真机显示效果,还是可以的。

打开Survival Shooter项目中PlayerMovement.cs,可以看到如下两段代码:

FPS 游戏的 Joystick 操纵杆如何实现?

玩家移动鼠标,通过射线检测来控制主角的360度旋转,!MOBILE_INPUT宏告诉我们, Survival Shooter并没有提供移动端的代码,这需要由我们自己来实现。

当选择Mobile Input-Enable后,实际上在Player Settings的Scripting Define Symbols下加入了MOBILE_INPUT的FLAG:

FPS 游戏的 Joystick 操纵杆如何实现?

Survival Shooter移动版本Input,改造开始:

添加JoyStick摇杆。

在CrossPlatformInput下Prefabs目录的MobileSingleStickControl预设,直接拖到当前的场景中。(如果发现适配不对,检测Canvas下是否有绑定Canvas Scaler脚本。)

FPS 游戏的 Joystick 操纵杆如何实现?

CrossPlatformInput已经提供了基本JoyStick实现,我们可以根据自己的需求调整适合的尺寸或是替换纹理。

右边的白色方块是对应Jump跳跃,通常我们用来实现射击等操作。我们可以Duplicate它来添加许多其它的按钮功能。

打开MobileSingleStickControl预设可以看到如下结构:

FPS 游戏的 Joystick 操纵杆如何实现?

JumpButton和MobileJoystick分别有着不同的实现,JumpButton下绑定了ButtonHandler脚本,我们可以指定Name,用于标识当前按钮的功能,通过查看源码,可以它的触发逻辑也是通过CrossPlatformInputManager脚本统一管理的。

JumpButton按下和抬起事件处理:

FPS 游戏的 Joystick 操纵杆如何实现?

我们放在Update下处理即可。

MobileJoystick是通过Joystick脚本实现。

FPS 游戏的 Joystick 操纵杆如何实现?

但在实际的测试中发现,Joystick是操纵杆的范围是“矩形”的,如下图这样:

FPS 游戏的 Joystick 操纵杆如何实现?

操纵杆会在限制在矩形的区域内。区域通过MovementRange参数来控制。

这种操纵杆方便支持那些仅需要“左右”或是“上下”移动的操作,但我们常见的操纵杆是限定在圆的范围内,这也是大多数游戏采用的操纵杆方式,所以我们需要对Joystick脚本进行扩展, 在实现基于圆的范围之前,先看一下,原有限定在矩形范围内的实现,在 JoyStick.cs 下:

FPS 游戏的 Joystick 操纵杆如何实现?

代码解析:

m_UseX:是否开启横向移动

m_UseY:是否开启纵向移动

float delta = (data.position.x - m_StartPos.x);

移动的增量

计算新的位置x相对于起始位置x的增量

delta = Mathf.Clamp (delta, -MovementRange, MovementRange);

通过Mathf.Clamp将delta限制在范围(-MovementRange,MovementRange)之间,比如 -100,100

newPos.x = delta;

更新newPos位置

transform.position = new Vector3 (m_StartPos.x + newPos.x, m_StartPos.y + newPos.y, m_StartPos.z + newPos.z);

更新位置,StartPos+newPos(起始位置+增量)

m_UseY的部分和m_UseX部分是一样的。

我们需要修改的就是控制delta增量。

我们将JoyStick限制在一个圆的区域内,实际是限定在圆半径的长度,长度不能超出圆的半径。

向量本身是包含大小和方向的量,通过使用Vector2.Distance计算两点之间的距离。

当大于等于半径时,我们需要限制它继续向更远处进行移动。

这里如何在任意方向上限定在一个固定的长度内?

使用向量的规一化normalized。

实现代码:

FPS 游戏的 Joystick 操纵杆如何实现?

data.position当前鼠标或是手势移动的位置;

m_StartPos JoyStick初始位置(不变);

MovementRange半径限定的区别;

newPos移动的增量,移动中的位置由m_StartPos+newPos决定;

nwePos.normalized*MovementRange 限定在长度MovementRange以内。

效果如图:

FPS 游戏的 Joystick 操纵杆如何实现?

但在实际的测试中发现,切换到不同的分辨率下,Joystick滑动的区域会不一致,因为MovementRange 并未考虑到多分辨率适配,比如 480*320 的机型(举例方便说明), Move mentRange 设置为 50 那么 2 倍的屏幕分辨率 960*640 ,如果 MovementRanget 移动 50 就会显得很短,既然是 2 倍的分辨率大小, 所以 MovementRange 设置为 50*2=100 ,才符合一致的效果

所以我们需要将MovementRange乘上一个Factor缩放比,这个比值可以通过当前的Canvas获得:

下一步,实现右半边 屏幕拖拽旋转角色。

这里会涉及到几个点,因为上面JoyStick和将要实现的拖拽旋转均是通过手势实现, 这里就需要判断哪个手指来影响哪个操作。

比如我默认先按下手指A在Joystick上,然后再按下手指B在可拖动的区域,那么手指B 就来控制拖拽旋转的处理; 如果我手指 A Joystick 上,手指 B 也在 Joystick 上,则拖拽的逻辑不进行处理; 如果我手指 A 在拖拽区域,手指 B 也在拖拽区域,使用手指 A 来处理拖拽; 如果我当前只有一个手指在屏幕上操作,那点在哪个区域就执行哪部分的处理即可。

有点儿啰嗦,需要处理的情况就是要记录具体的手指Touch数据。

但是Touch是Struct值类型,不是引用类型,所以 想要判断具体是哪根手指发挥作用,需要通过 fingerId 去记录,而不是定义一个变量去保存它。

关于要处理拖拽的操作,这里将屏幕的右半部分做为可拖拽的区域,那么第一步要做的就是 判断当前按下去的手指是否在拖拽区域内 判断点击屏幕是在拖拽区域内,可以使用屏幕坐标系或视口坐标系来计算。

FPS 游戏的 Joystick 操纵杆如何实现?

如果满足条件,我们就记录当前手指的fingerId,后面会根据当前fingerId的Touch进行逻辑的计算。

如果按下的手指不满足条件,就继续等待其它手指,这时候可能按下第2个手指,第3个手指,直到满足条件,就不再判断,此时我们可以使用一个布尔或是其它的方式来禁止他每一次都判断。

实现代码:

FPS 游戏的 Joystick 操纵杆如何实现?

CheckGesture 放在Update中执行。

这里要使用touch.phase的状态进行判定。

touch的状态有以几种:

FPS 游戏的 Joystick 操纵杆如何实现?

具体的生命周期如下:

FPS 游戏的 Joystick 操纵杆如何实现?

通过滑动手势来控制角色的旋转,定义TouchStart向量,记录按下时的位置

touch.position表示当前手指的移动中的距离。

因为我们只需控制角色左右移动,所以只需要判断横向坐标X:

touch.position.x>TouchStart.x

说明向右滑动,角色向右旋转

touch.position.x <TouchStart.x

说明向左滑动,角色向左旋转

并且每一帧都要重置TouchStart的位置为touch.position,因为我们需要计算两者之间的差值并用来计算移动的速率。

游戏是45度俯视角,角色的旋转是绕着Y轴进行,如何让角色进行旋转,肯定是要使用到四元数Quaternion。

除此之外,还需要实现如何根据我手指移动的速率来控制角色旋转的速率,上面刚有提到。

这里就需要使用到上面touch.position和TouchStart之间的差值决定。 逻辑是放在 Fixed Update 固定时间更新。

所以每一帧的执行都会计算当前的TouchStart和touch.position之间的差值。

手指移动的速度没有FixedUpdate帧刷新的频率快,所以值是渐进的增大或是缩减的。

代码就一行:

RotateSpeed=1,可以自己调节以测试合适的speed。

核心只修改了两个类:

Joystick

PlayerMovement

以及场景中的Joystick的Prefab

Demo已经打包, 点击阅读原文 即可下载。

FPS 游戏的 Joystick 操纵杆如何实现?

FPS 游戏的 Joystick 操纵杆如何实现?

↓↓↓点击阅读原文,了解更多。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Google成功的七堂课

Google成功的七堂课

罗耀宗 / 电子工业出版社 / 2005-7 / 28.00元

Google是全球使用人数最多的搜索引擎,在短短几年内,Google从斯坦福大学的实验室,茁壮成长为举世瞩目的IT业超级巨人,他们的成功绝非偶然,尤其是在网络泡沫破灭,行业一片萧条之际,它的崛起更为IT业带来一缕曙光。作者从趋势观察家的角度,以讲座的形式,向读者讲述Google成功的关键因素:破除因循守旧、不断打破常规,核心技术领先、做出了“更好的捕鼠器”,使得Google在搜索技术方面远远超越对......一起来看看 《Google成功的七堂课》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具