FPS游戏的Joystick操纵杆如何实现?
bigegpt 2024-10-12 06:29 3 浏览
作者: Mitty
关于Input组件,有款比较知名的插件叫Easy Touch,在许多的项目中都应用过,在Untiy的Standard Assets下也有一款官方的Input插件-CrossPlatformInput,我之前还没有使用过,所以参考了一些资料,将简单的使用教程记录一下。
关键词:
1.Input组件和Gesture手势
2.Unity Remote
3.Survival Shooter官方教程
4.Joystick操纵杆实现&拖动角色旋转
现在Unity都是分模块下载,Standard Assets需要我们单独去官网下载,并安装到Unity的路径下。
Unity的官方教程Survival Shooter便是采用Standard Assets下的CrossPlatformInput,实现Input输入部分的功能。
CrossPlatformInput比较基础,通常使用都需要进行扩展。
Unity官方的教程-Survival Shooter中便是采用CrossPlatformInput处理Input的部分,但比较精简。
导入CrossPlatformInput后,会在菜单栏上生成Mobile Input,打开并点击Enable,会弹出如下提示:
这里有提到使用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,可以看到如下两段代码:
玩家移动鼠标,通过射线检测来控制主角的360度旋转,!MOBILE_INPUT宏告诉我们,Survival Shooter并没有提供移动端的代码,这需要由我们自己来实现。
当选择Mobile Input-Enable后,实际上在Player Settings的Scripting Define Symbols下加入了MOBILE_INPUT的FLAG:
Survival Shooter移动版本Input,改造开始:
添加JoyStick摇杆。
在CrossPlatformInput下Prefabs目录的MobileSingleStickControl预设,直接拖到当前的场景中。(如果发现适配不对,检测Canvas下是否有绑定Canvas Scaler脚本。)
CrossPlatformInput已经提供了基本JoyStick实现,我们可以根据自己的需求调整适合的尺寸或是替换纹理。
右边的白色方块是对应Jump跳跃,通常我们用来实现射击等操作。我们可以Duplicate它来添加许多其它的按钮功能。
打开MobileSingleStickControl预设可以看到如下结构:
JumpButton和MobileJoystick分别有着不同的实现,JumpButton下绑定了ButtonHandler脚本,我们可以指定Name,用于标识当前按钮的功能,通过查看源码,可以它的触发逻辑也是通过CrossPlatformInputManager脚本统一管理的。
JumpButton按下和抬起事件处理:
我们放在Update下处理即可。
MobileJoystick是通过Joystick脚本实现。
但在实际的测试中发现,Joystick是操纵杆的范围是“矩形”的,如下图这样:
操纵杆会在限制在矩形的区域内。区域通过MovementRange参数来控制。
这种操纵杆方便支持那些仅需要“左右”或是“上下”移动的操作,但我们常见的操纵杆是限定在圆的范围内,这也是大多数游戏采用的操纵杆方式,所以我们需要对Joystick脚本进行扩展,在实现基于圆的范围之前,先看一下,原有限定在矩形范围内的实现,在JoyStick.cs下:
代码解析:
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。
实现代码:
data.position当前鼠标或是手势移动的位置;
m_StartPos JoyStick初始位置(不变);
MovementRange半径限定的区别;
newPos移动的增量,移动中的位置由m_StartPos+newPos决定;
nwePos.normalized*MovementRange 限定在长度MovementRange以内。
效果如图:
但在实际的测试中发现,切换到不同的分辨率下,Joystick滑动的区域会不一致,因为MovementRange并未考虑到多分辨率适配,比如480*320的机型(举例方便说明),MovementRange设置为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去记录,而不是定义一个变量去保存它。
关于要处理拖拽的操作,这里将屏幕的右半部分做为可拖拽的区域,那么第一步要做的就是判断当前按下去的手指是否在拖拽区域内判断点击屏幕是在拖拽区域内,可以使用屏幕坐标系或视口坐标系来计算。
如果满足条件,我们就记录当前手指的fingerId,后面会根据当前fingerId的Touch进行逻辑的计算。
如果按下的手指不满足条件,就继续等待其它手指,这时候可能按下第2个手指,第3个手指,直到满足条件,就不再判断,此时我们可以使用一个布尔或是其它的方式来禁止他每一次都判断。
实现代码:
CheckGesture 放在Update中执行。
这里要使用touch.phase的状态进行判定。
touch的状态有以几种:
具体的生命周期如下:
通过滑动手势来控制角色的旋转,定义TouchStart向量,记录按下时的位置
touch.position表示当前手指的移动中的距离。
因为我们只需控制角色左右移动,所以只需要判断横向坐标X:
touch.position.x>TouchStart.x
说明向右滑动,角色向右旋转
touch.position.x <TouchStart.x
说明向左滑动,角色向左旋转
并且每一帧都要重置TouchStart的位置为touch.position,因为我们需要计算两者之间的差值并用来计算移动的速率。
游戏是45度俯视角,角色的旋转是绕着Y轴进行,如何让角色进行旋转,肯定是要使用到四元数Quaternion。
除此之外,还需要实现如何根据我手指移动的速率来控制角色旋转的速率,上面刚有提到。
这里就需要使用到上面touch.position和TouchStart之间的差值决定。逻辑是放在FixedUpdate固定时间更新。
所以每一帧的执行都会计算当前的TouchStart和touch.position之间的差值。
手指移动的速度没有FixedUpdate帧刷新的频率快,所以值是渐进的增大或是缩减的。
代码就一行:
RotateSpeed=1,可以自己调节以测试合适的speed。
核心只修改了两个类:
Joystick
PlayerMovement
以及场景中的Joystick的Prefab
相关推荐
- 恢复软件6款汇总推荐,帮你减轻数据恢复压力!
-
在当今数字化生活中,数据丢失的风险如影随形。无论是误删文件、硬盘故障,还是遭遇病毒攻击,丢失的数据都可能给我们带来不小的麻烦。此时,一款优秀的数据恢复软件就成为了挽救数据的关键。今天,为大家汇总推荐...
- 中兴星星一号刷回官方原版recovery的教程
-
【搞科技教程】中兴星星一号的官方recovery也来说一下了,因为之前给大家分享过了第三方的recovery了,之前给大家分享的第三方recovery也是采用一键刷入的方式,如果细心的朋友会发现,之前...
- 新玩机工具箱,Uotan柚坛工具箱软件体验
-
以前的手机系统功能比较单调,各厂商的重视程度不一样,所以喜欢玩机的朋友会解锁手机系统的读写权限,来进行刷机或者ROOT之类的操作,让使用体验更好。随着现在的手机系统越来越保守,以及自身功能的增强,...
- 三星g906k刷recovery教程_三星g906k中文recovery下载
-
【搞科技教程】看到有一些机友在找三星g906k的第三方recovery,下面就来说一下详细的recovery的刷入方法了,因为手机只有有了第三方的recovery之后才可以刷第三方的root包和系统包...
- 中兴星星2号刷recovery教程_星星二号中文recovery下载
-
【搞科技教程】咱们的中兴星星2手机也就是中兴星星二号手机的第三方recovery已经出来了,并且是中文版的,有了这个recovery之后,咱们的手机就可以轻松的刷第三方的系统包了,如果没有第三方的re...
- 数据恢复软件有哪些值得推荐?这 6 款亲测好用的工具汇总请收好!
-
在数字生活中,数据丢失的阴霾常常突如其来。无论是误删工作文档、格式化重要磁盘,还是遭遇系统崩溃,都可能让我们陷入焦虑。关键时刻,一款得力的数据恢复软件便是那根“救命稻草”。今天,为大家精心汇总6...
- 中兴u956刷入recovery的教程(中兴e5900刷机)
-
【搞科技教程】这次主要来给大家说说中兴u956手机如何刷入第三方的recovery,因为第三方的recovery工具是咱们刷第三方rom包的基础,可是很我欠却不会刷,所以太这里来给大家整理了一下详细的...
- 联想A850+刷recovery教程 联想A850+第三方recovery下载
-
【搞科技教程】联想A850+的第三方recovery出来了,这个第三方的recovery是非常的重要的,比如咱们的手机要刷第三方的系统包的时候,都是需要用到这个第三方的recovery的,在网上也是有...
- 工具侠重大更新 智能机上刷机一条龙完成
-
工具侠是针对玩机的机油开发的一款工具,不管是发烧级别的粉丝,还是普通小白用户,都可以在工具侠上找到你喜欢的工具应用。这不,最新的工具侠2.0.16版本,更新了专门为小白准备的刷机助手工具,以及MTK超...
- shift+delete删除的文件找回6种硬盘数据恢复工具
-
硬盘作为电脑的重要存储设备,如同一个巨大的数字仓库,承载着我们日常工作、学习和生活中的各种文件,从珍贵的照片、重要的工作文档到喜爱的视频、音乐等,都依赖硬盘来安全存放。但有时,我们可能会不小心用sh...
- 使用vscode+Deepseek 实现AI编程 基于Cline和continue
-
尊敬的诸位!我是一名专注于嵌入式开发的物联网工程师。关注我,持续分享最新物联网与AI资讯和开发实战。期望与您携手探寻物联网与AI的无尽可能。这两天deepseek3.0上线,据说编程能力比肩Cl...
- 详解如何使用VSCode搭建TypeScript环境(适合小白)
-
搭建Javascript环境因为TypeScript不能直接在浏览器上运行。它需要编译器来编译并生成JavaScript文件。所以需要首先安装好javascript环境,可以参考文章:https://...
- 使用VSCode来书写你的Jupyter Notebooks
-
现在你可以在VScode里面来书写你的notebook了,使用起来十分的方便。下面来给大家演示一下环境的搭建。首先需要安装一个jupyter的包,使用下面的命令安装:pip3install-ih...
- 使用VSCode模板提高Vue开发效率(vscode开发vue插件)
-
安装VSCode安装Vetur和VueHelper插件,安装完成后需要重启VScode。在扩展插件搜索框中找到如下Vetur和VueHelper两个插件,注意看图标。添加Vue模板打...
- 干货!VsCode接入DeepSeek实现AI编程的5种主流插件详解
-
AI大模型对编程的影响非常之大,可以说首当其冲,Cursor等对话式编程工具渐渐渗透到开发者的工作中,作为AI编程的明星产品,Cursor虽然好用,但是贵啊,所以咱们得找平替,最好免费那种。俗话说,不...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- linuxlink (65)
- pythonwget (67)
- androidinclude (65)
- libcrypto.so (74)
- linux安装minio (74)
- ubuntuunzip (67)
- vscode使用技巧 (83)
- logstashinput (65)
- vue阻止冒泡 (67)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)