Unity官方FPS教程(三)
咱今天开始从脚本来解析具体的功能实现以及一些技巧
如图:
这是当前所有脚本所在文件夹,其类别也以及分好了,这期我们就先从最基础的角色控制相关脚本开始吧。
打开Scripts/Gameplay/Managers中的Player Input Handler脚本
打开了以后看到最后其在267行左右,对于刚学习的各位来说这样密密麻麻的代码看着就是脑瓜子嗡嗡的,特别是没有计算机基础的同学更是雪上加霜,所以我们在阅读代码的时候我们先看把整个脚本根据不同函数体,声明,以及其他模块。先区分到底有多少个这种部分,然后我们再从第一个开始慢慢解析,如图:
乍一看光是函数体还是很多,然后就脑补出了这些函数如何如何的负责相互调用各种嵌套啥的,直接劝退(至少我是这样的),但是我们注意观察函数命名就可以看出其实是几个功能的不同流程,整合之后的函数就是这个脚本的所有功能也就是 以下几个:
1.CanProcessInput() : 判断当前能否读取用户输入
2.GetMoveInput() :移动
3.GetLookInputsHorizontal(),GetLookInputsVertical() :获取视角轴
4.GetJumpInputDown(),GetJumpInoutHeld() :跳跃
5.GetFireInputDown(),GetFireInputRealesed(),GetFireInputHeld() :开火
6.GetAimInputHeld() :瞄准
7.GetSprintInputHeld() :冲刺
8.GetCrouchInputDown() ,GetCrouchInputRealesed() :下蹲
9.GetReloadButtonDown() :装弹
10.GetSwichWeaponInput() :切换武器
11.GetSelectWeaponInput() :选择武器
12.GetMouseOrStickLookAxis() :获取鼠标或者控制杆的轴
以上这几个功能就是一个游戏对象拥有武器的情况下的基本行为组成,如果去掉武器组,整个模块可以砍一半左右(差不多5个)。
但是注意!!!在此脚本中所有方法都只是注册了,但是都没有在本脚本中调用(延迟帧中检查是否开火了也只是为了其他函数服务的一个条件)
现在我们就能感觉到整个脚本的结构以及功能组成,就不会觉得无从下手了,当然以后大家再开发设计的时候也尽量模块分明减少整个程序的耦合性,调用也更方便。
现在我们再回到开头,我这里为了避免理解歧义我直接翻译原注释。
上图中的Tooltip其实属于编辑器扩展的相关应用,作用也不是高大上,就是将你当前的公开的变量在检查面板上有一个注释
鼠标放上去就会有自定义得内容,需要注意你用这个工具那么对应的变量一定是可以在检查面板出现的,不然没有任何意义(因为你连变量都看不见怎么看他的注释)。
void start():
在start函数中就做了三件事:① :获取m_PlayerCharacterController 引用,做空引用错误处理。
② :获取m_GameFlowManager引用,做空引用错误处理。
③ :开始游戏时将光标隐藏并且锁定 Cursor
其实随着练习多了以后各位也会理解让一些在程序全局不会轻易更改的对象引用从一开始就写入,这样就不用频繁查找一个基本不变的值,浪费时间,这也算是设计模式中的组合模式,即为了在项目中提高代码复用性,降低对象成本而产生的一种模式,例如减少或者完全避免GetComponent<>在Update系列函数中调用,在程序一开始获取其引用。
void LateUpdate():
游戏运行之后每次延迟帧中调用GetFireInputHeld()函数并将值赋给这个全局变量再由他为调动其他函数的运行提供条件。
void CanProcessInput():
这个函数算是整个行为脚本的基础条件之一,判断光标是否锁定状态(你是否切换到其他的应用去了,或者最小化了)并且游戏还在运行没有达到任何结束条件,此时才会返回一个true,即接收用户的输入。
Vector3 GetMoveInput():
GameConstants 脚本是一个专门管理输入轴的信息的,如下图:
这些命名不是凭空自定义的,而是在Unity->Edit->Project Settings->Input Manager 中,如图:
仔细看是可以找到所以关联的轴的。
回到函数,当可以接收用户输入时,创建一个Vector3变量用于存储用户输入的垂直轴与水平轴的值构成的位置信息,然后对其加以限制,并返回。
float GetLookInput()系列:
两个函数都是一样的,只不过调用的轴名字不同,此处调用了方法GetMouseOrStickLookAxis()方法,所以我们直接贴出此方法:
看起来有点复杂,代码量有点多,但其实也是做了一些完备处理的,其功能为:
①当接受用户输入时,创建一个bool 值 isGamePad 来判断是否有对应的轴stickInputName的输入,有就是true,没有就是false。
②创建一个float值 i 用于记录一个输入的轴值,二元运算,根据当前isGamepad的值来决定取的轴值,true取stickInputName,false取mouseInputName。
③判断是否需要翻转垂直轴,并且将 i 的值与LookSensitivity变量(视角灵敏度)结合
④当读取到来自stickInput的值时才做一个时间增量的相乘,否则乘以一个浮点数
⑤ #if UNITY_WEBGL ~ #endif :这是Unity的编译预处理指令,在此处的作用其实就是当处在WebGL平台时,程序会保留if其中的语句并执行,这里执行的就是对WebGL上鼠标速度的调优,而如果条件不成立,编译后将不会保留其中代码。
总结来说就是获取轴值并加以修改以后返回一个float浮点值,然后GetLookInput系列根据不同轴获取到不同值,即玩家的移动Vector3中x,y,z的值。
然后下一个,GetJumpInput系列:
大家可以看到,两个函数基本没有区别只是调用了检测不同状态的函数,流程就是检测是否按下/按住了指定的跳跃键,然后返回一个bool值,其实写过一点练习的应该能看出来就是为了后面的地面检测,以及虚空踏步,多段跳做的条件。
下一个是GetFireInput系列:
不能说一模一样,只能说两模一样,只不过判断的条件bool值置换了,那我们来看看GetFireInputHeld()函数:
其实整体与GetMouseOrStickLookAxis()差异不大,获取对应轴,当输入为操纵杆时限制输入的最小响应值,可以理解为射速吧(也许),否则输出其他对应的键的轴值,
回到上面的两个函数,当开火按下时(GetFireInputDown())必须确定此时以及收到了输入的对应轴值信号并且在上一帧的LateUpdate中检测的输入为空,此时返回true。当放开开火键时(GetFireInputReleased())当前没有收到用户对应输入且上一帧的LateUpdate中检测到了输入,此时返回true。
然后是GetAimInputHeld()函数
同样接收输入信号,判断是否接受到了瞄准操作的轴值并返回对应bool值(功能没什么要点,我就跳过了)
GetSprintInputHeld()函数:
同上,只不过功能为冲刺
GetCrouchInput系列:
同上,功能为下蹲
GetReloadInputDown()函数,也是同上,功能为装弹
GetSwitchWeaponInput():
这里的切换武器功能其实并不是直接实现,通过他的返回值可以看见其实这个函数返回的是一个状态,通过这个状态来改变武器队列的index实现切换,这里的功能是读取切换武器的轴通过轴的值来做调动,可以想一下鼠标滚轮。
GetSelectWeaponInput()函数:
这个呢就是一个状态机了,根据在指定了键的基础上根据用户的输入返回一个对应的值,这里的值对应武器的index,然后就可以切换到对应的武器了。
总结一下:这次的脚本其实就处理了基本的并且用于玩家的用户输入,这也和脚本名很贴合,之所以这么多函数,其实都是为了复用性以及减少耦合性,我们在编程中虽然第一时间想不出来但是我们在多次修改时应该注意到这些方面,这也是一种加快运行的方式吧,这篇文章水了3600字左右,本来想着随便写一些的,但是为了我自己养成这种习惯的话我也是坚持下来多水了几个字(doge),希望各位也能从中找到一些什么,这个教程呢脚本还是有点多的,按照我的速度可能很水很拖拉,但是能写就尽量写吧,至此第一个脚本到此结束,感谢我自己。(才第一个脚本。。。。。疯了都!!!)
Unity官方FPS教程(三)相关推荐
- Unity官方FPS教程解析(一)
在刚接触Unity的时候学习官方教程时下载导入过官方FPS教程,但是由于什么都不懂所以光是看着整个层次面板都觉得难受
- Unity官方FPS教程解析(二)
在上一篇文章中我们只是初步了解了这个游戏层次构造的一部分,今天我们继续上一章的内容吧. Enemy 两个enemy本质上没有差别,所以就其中一个来说说吧 Enemy_Turret:这个初始场景的bos ...
- Unity官方实例教程 Roll-a-Ball(一)
文章转载自:http://www.jianshu.com/p/6e4b0435e30e 前言 Unity官方实例教程Roll-a-Ball汉化视频地址,点击这里. 官方视频所用的unity版本是4.3 ...
- Unity官方实例教程 Roll-a-Ball(二)
Roll-a-Ball 游戏 文章转自:http://www.jianshu.com/p/97b630a23234 前言 在Unity官方实例教程 Roll-a-Ball(一)中,我们学会了: 新建一 ...
- Unity官方图形教程 学习笔记(三) -- 线性工作流
原文链接:https://docs.unity3d.com/Manual/LinearLighting.html 1 线性渲染概述 Unity编辑器支持使用gamma颜色空间和linear颜色空间.G ...
- Unity官方图形教程 学习笔记(二) -- Precomputed Realtime GI(实时全局光照)
原文链接:https://unity3d.com/cn/learn/tutorials/s/graphics 1 介绍 当使用Baked GI的时候,会在预计算阶段,离线创建一张lightmap纹理贴 ...
- java集合课程,I学霸官方免费课程三十三:Java集合框架之Map集合
I学霸官方免费教程三十三:Java集合框架之Map集合 Map接口 Map集合采用键值对(key-value)的方式存储数据,其中键不可以重复.值可以重复. 常用类有HashMap.TreeMap和P ...
- unity官方教程-TANKS(一)
unity官方教程TANKS,难度系数中阶. 跟着官方教程学习Unity,通过本教程你可以学会使用Unity开发游戏的基本流程. 一.环境 Unity 版本 > 5.2 Asset Store ...
- Unity官方教程Ruby大冒险的自学笔记
Unity官方教程Ruby大冒险的自学笔记 一. //正确例子: void Update(){//获取运动矢量moveX = Input.GetAxisRaw("Horizontal&quo ...
最新文章
- 德勒报告:2018年全球生命科学发展趋势
- 【Rollo的Python之路】Python 同步条件 学习笔记 Event
- php 自动创建文件,php:自动创建多级文件夹
- 如何设计一个牛逼的API接口
- Java SE 12扩展Switch语句/表达式完整指南
- 架构畅想:如果以你所会去进行架构,会到哪一步?
- 关于无线温度监测系统
- 五菱“神车”再添一员,小型电动车迎来“均值回归”?
- 汇编语言的基础知识一
- python爬取王者皮肤_Python爬取王者荣耀所有英雄以及高清大图
- Glide v4详解
- 《合成孔径雷达成像——算法与实现》之【0】仿真汇报
- Unity学习笔记第二章:如何创建一个2D游戏
- 1. 编写函数 cal_numbers:参数为字符串,统计并返回该字符串中的英文字母、空格、数字和其它字符的个数
- linux 网口对应网卡_Intel 700系列 电口万兆网卡 X710T2L评测
- table中英文值显示其对应中文
- 破解百度网盘屏蔽文件分享失效被和谐的独家秘籍
- 3天精通Postman---基础应用接口测试流程接口架构和协议
- 多普勒流量计测流系统
- python主成分分析各变量重要性_主成分分析的理解
热门文章
- 判断iphone设备版本号
- MachineLearning(吴恩达)week6的ex5的选做部分代码及讲解
- 拼夕夕:套路的尽头是不要脸
- 本轮下跌基金科汇净值只下跌了0.22%
- nvm的简介、安装、使用(简单明了)
- springboot在配置文件中控制 @Scheduled 开关
- 阿里技术面全A,终面却被产品经理拉下马,我不服
- 烦人的IE弹窗:设置Windows Internet Explorer
- 吉大计算机科学与技术学院官网,张晋东-吉林大学计算机科学与技术学院
- java计算机毕业设计防疫期社区人员信息动态管理系统源码+系统+lw+数据库+调试运行