《守望先锋》的女英雄Pharah拥有独特的火箭跳技能,使用喷射背包的她能在虚拟战场上实施空中控制。本篇文章将教大家学会通过分解和重建组件,在Unity中重建火箭跳的运动系统。

184843wd08kz2v299qaq5k.jpg
《守望先锋》的女英雄Pharah

本教程将帮助大家熟悉Unity的物理系统,学习在Unity中创建基本的FPS(第一人称射击游戏)角色,实现《守望先锋》中Pharah一样的的地面运动,火箭跳和悬浮技能。



工程设置

首先,创建一个空白工程。在Assets资源文件夹下新建Scenes和Scripts 2个文件夹,分别存放场景和脚本。

184901ng8iw8wywsiwflf3.jpg

访问Asset Store资源商店下载资源包Standard Assets和 Guns Pack。 Standard Assets提供了环境模型网格 Guns Pack 则提供了项目中所需要使用的火箭发射器模型。

184912wzz9ur9ru9245ce5.jpg
Standard Assets

185015oebtpb3u6bz3bkb2.jpg
Guns Pack

访问GameObject > Light > Directional Light 为场景中加入方向光。

工程项目中必须有可以使用的地面。访问Assets > Standard Assets > Prototyping > Prefabs中查找可以使用的地面原型。调整地面的位置到原点,并将其定位到希望的坐标位置。到这里工程设置就完成了,现在可以开始下一步创建角色了。

创建角色

在本工程中,我们不打算直接使用Standard Assets中的FPS角色。我们来创建自定义的FPS角色并为其编写脚本。

首先我们来创建Player 玩家。点击 GameObject > 3D Object > Capsule,使用胶囊体创建FPS的身体。重置胶囊体的位置到原点,将其放置在地面上方。在Hierarchy层级窗口中,右键点击胶囊体,将胶囊体的命名为Player。

Hierarchy层级窗口中拖放将摄像机关联到Player 的FPS身体上,将其位置设置为身体的中心,并提升到合适的高度,这就符合角色的FPS摄像机视角了,而它的位置也会随着玩家的位置变化而变化。将Field of View值设置为70。设置方式为选择摄像机后,在其Inspector检视窗口中进行修改。

185038nzujgssiswewbjwo.jpg

然后我们来创建RocketLauncher 火箭发射器。访问Assets > Guns Pack > Prefabs > RocketLauncher 添加该预制体。对RocketLauncher预制体重复以上操作,但将其关联到摄像机而不是Player,重新定位它到合适的位置。

现在场景和游戏视图应如下所示。

185113tv2gg98qix69v2ja.jpg

角色物理系统

为了让我们的角色适用于Unity的物理,我们需要添加一些组件来保证它们的正确运作。

现在我们需要建立角色与刚体组件的连接,选择对象Player ,在 Inspector检视窗口中:使用 Add Component > Physics > Rigidbody为其添加刚体组件。

在Inspector检视窗口中确保Player的刚体组件中重力gravity选项勾选。同时锁定Player刚体组件在X,Y,Z三轴上的旋转。

185130qqmjllm60cudhguz.jpg

如果此时运行游戏,我们会发现重力作用似乎不明显。有很多办法可以增加作用在刚体上的重力,这次我们直接在游戏对象上使用内建组件Constant Force。请按照以下操作:为Player添加一个名为Constant Force组件,选择Player在Inspector检视窗口中选择: Add Component > Physics > Constant Force。在Constant Force组件检视窗口中,为Y轴方向的力赋一个值。在本教程中,我们用-9.8。注意前面一定要有负号,否则游戏中角色会展翅高飞而不是向下掉落。

185141ts3sl33xqsmqmxsz.jpg

这样就完成了创建基础角色。

角色的地面运动

为了赋予角色创建基本的地面运动能力,我们只需一个简短的脚本。

首先为对象Player创建一个C#脚本。在 Inspector检视窗口中:选择 Add Component > New Script 。 语言选择: C# 。将脚本命名为P_Controller。

下面为脚本代码与功能注释。

[C#] 纯文本查看 复制代码using UnityEngine; using System.Collections; public class P_Controller : MonoBehaviour { public float p_WalkSpeed; // 这是角色的移动速度变量。使用public类型,可以在Inspector检视窗口直接访问 void Start () { Cursor.lockState = CursorLockMode.Locked; } //在游戏窗口中锁定鼠标 void Update () { if (Input.GetKeyDown (escape)) { Cursor.lockState = CursorLockMode.None; } // 如果“esc”按下,解除鼠标在游戏窗口中的锁定。注意,GetKey判断键按住的状态,GetKeyDown是按键操作 float p_WalkFB = Input.GetAxis (Vertical) * p_WalkSpeed; // 在“垂直”轴上创建变量并与前面创建的移动速度变量关联,使角色向前和向后移动 float p_WalkLR = Input.GetAxis (Horizontal) * p_WalkSpeed; // 在水平轴线上创建变量与移动速度关联,支持玩家的左右移动 p_WalkFB *= Time.deltaTime; p_WalkLR *= Time.deltaTime; // 使上述两个变量的运动控制与时间同步而不是游戏帧速 transform.Translate (p_WalkLR, 0, p_WalkFB); } } // 在此启动上述所有设置,使Player产生运动。注意: p_WalkLR左右移动是在X轴上的,而Y轴移动为0,p_WalkFB前后运动则是在Z轴上的 // 注意:我们之前冻结了游戏对象在X,Y,Z轴上的旋转。上面的脚本则只与角色在某个方向上的位移有关系,这样,旋转并不包括在玩家身体控制中,这样,一旦Player身体收到外力作用(如:撞上一个对象)就会导致玩家身体倾倒或发生旋转。但是在3个轴上锁定Player上刚体的旋转后,这个问题就得以解决啦。

代码非常简单,如下图所示。

185234kt0jbebsk0b7si0c.jpg

现在,我们在Inspector检视窗口中,在Player游戏对象的P_Controller 脚本中为p_WalkSpeed赋值。本教程中设置玩家的移动速度为5。

185245bleht91gpxswsslq.jpg

玩家的鼠标动作

现在,我们需要为Player创建一个基本的瞄准系统。

首先为摄像机创建新的C#脚本‘P_Mouse。在Inspector检视窗口中选择摄像机Camera,Add Component > New Script > 语言选择: C #。

下面为脚本代码与功能注释。

[C#] 纯文本查看 复制代码using UnityEngine; using System.Collections; public class P_Mouse : MonoBehaviour { Vector2 p_MouseLook; Vector2 p_MouseSmooth; // 创建2个Vector2类型变量 public float sensitivity; public float smoothing; // 分别表示鼠标敏感度和平滑度,设置为public后就可以在Inspector检视窗口中直接访问了 GameObject p_Camera; // 引用的游戏对象 void Start () { p_Camera = this.transform.parent.gameObject; } // 为引用游戏对象,为p_Camera赋值,在此设置为使用transform取得的其父游戏对象。 void Update () { var cp = new Vector2 (Input.GetAxisRaw (Mouse X), Input.GetAxisRaw (Mouse Y)); // 创建表示鼠标位置变化的变量。Vector2类型变量中包含2个部分,分别是在X轴和Y轴上的位置,这个Vector2变量用于保存鼠标的X(左右移动)和Y轴(上下移动)位置 cp = Vector2.Scale (cp, new Vector2 (sensitivity * smoothing, sensitivity * smoothing)); // 定义一帧中鼠标在X和Y轴上的移动的值 p_MouseSmooth.x = Mathf.Lerp (p_MouseSmooth.x, cp.x, 1f / smoothing); p_MouseSmooth.y = Mathf.Lerp (p_MouseSmooth.y, cp.y, 1f / smoothing); p_MouseLook += p_MouseSmooth; // 使用Lerp插值在之前创建的变量之间插值,平滑摄像机旋转 transform.localRotation = Quaternion.AngleAxis (-p_MouseLook.y, Vector3.right); p_Camera.transform.localRotation = Quaternion.AngleAxis (p_MouseLook.x, p_Camera.transform.up); } } // 设置开启摄像机旋转

代码如下图所示。

185333o8s2z8ssun2pznaz.jpg

在Inspector检视窗口中为Player对象在P_Mouse脚本中的p_MouseLook 和p_MouseSmooth赋值。本教程中我们都使用值5。

185347a59zyg9i7isnu6ts.jpg

火箭跳跃和悬浮

制作Pharah火箭跳和悬浮效果看起来难,但实际却可以用简单的脚本加以实现。

首先为对象Player创建新的C#脚本‘‘P_Jump。在Inspector检视窗口中选择游戏对象Player,Add Component > New Script > 语言选择: C #。

下面为脚本代码与功能注释。

[C#] 纯文本查看 复制代码using UnityEngine; using System.Collections; public class P_Jump : MonoBehaviour { public float p_ForceRJ; public float p_ForceHover; // 为火箭跳和悬浮分别创建变量 Rigidbody p_Rigidbody; // 引用游戏对象的刚体对象 void Start () { p_Rigidbody = GetComponent<Rigidbody> (); } // 获得游戏对象的刚体组件,其中设置了脚本。注意:要让这段代码工作必须关联到玩家的刚体组件。 void Update () { if (Input.GetKeyDown (KeyCode.LeftShift)) { p_Rigidbody.AddForce (0, p_ForceRJ, 0); } // 使用左Shift键,玩家会受到p_ForceRJ大小的力而向上移动,这样玩家就可以进行火箭跳了。 if (Input.GetKey (KeyCode.Space)) { p_Rigidbody.AddForce (0, p_ForceHover, 0); } } } // 如果按住了空格键,玩家每帧就会受到p_ForceHover大小的向上的力量推进,进而使玩家漂浮空中

代码如下图所示。

185436tpmo1j1lggnragmm.jpg

在Inspector检视窗口中为对象Player在P_Jump脚本中的p_ForceRJ 和 p_ForceHover变量赋值,本例程中我们分别使用1000和25。

185447b1t5f5gqgyrd545h.jpg

效果

我们还在环境里添加了一些预制体原型,我们就不在本教程中细致阐述了。运行项目,下面是演示结果。



小结

希望大家通过对本文内容的学习,可以创造出更加优秀的游戏作品。后面我们还会继续分享一些开发中的实用技巧在Unity官方中文社区(unitychina.cn),请保持关注!

Unity, 游戏, 火箭跳锐亚教育

锐亚教育 锐亚科技 unity unity教程