本章节我们就来使用水平轴和垂直轴来控制游戏物体的移动和旋转。我们之前大致讲过,游戏物体移动最重要的是方向,速度和时间三个要素,同样旋转也是。接下来,我们将之前创建的地形场景导入进来,如下所示
然后将之前的“MecanimDemo”工程里面的模型文件和动画文件拿过来使用,这里可以导入我自定义的“U_Character_Animatiion.unitypackage”资源包文件。
然后,我们将“U_Character_REF.fbx”模型拖入到场景中,
然后选中相机,点击菜单栏“GameObject”->“Align With View”调整Main Camera位置
接下来, 我们创建一个“U_Character_Controller”动画控制器文件,双击打开它
然后将我们之前复制过来的两个动画添加进来
我们默认动画是Idle休闲,然后在Idle和Run之间彼此建立过渡。接下来,我们创建一个动画参数is_run,类型为bool类型,如下所示
接下来,我们设置Idle到Run的过渡条件为is_run = true
然后Run到Idle的过渡条件为is_run = false
设置完毕后,我们将这个“U_Character_Controller.controller”文件拖拽到Animator组件的Controller项上面去。
最后,我们创建一个“MoveScript.cs”脚本文件来控制动画的播放,如下所示
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveScript : MonoBehaviour
{
// 动画播放组件
private Animator animator;
// Start is called before the first frame update
void Start()
{
// 获取动画播放组件
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
// 按下按键W播放动画
if (Input.GetKeyDown(KeyCode.W))
{
animator.SetBool("is_run", true);
}
// 抬起按键W停止播放动画
if (Input.GetKeyUp(KeyCode.W))
{
animator.SetBool("is_run", false);
}
}
}
然后,我们将这个脚本附加到“U_Character_REF”游戏对象上面
我们Play运行工程查看一下。
现在我们的动画播放没有问题了。接下来,我们就开始控制角色的移动。我们之前讲过,这个最好使用“Character Controller”角色控制器组件来实现。
接下来,我们就来修改“MoveScript.cs”脚本文件,增加移动代码,如下所示
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveScript : MonoBehaviour
{
// 动画播放组件
private Animator animator;
// 角色控制器组件
private CharacterController controller;
// 定义移动速度和旋转速度
private float moveSpeed = 10.0f;
private float rotateSpeed = 2.0f;
// Start is called before the first frame update
void Start()
{
// 获取动画播放组件
animator = GetComponent<Animator>();
// 获取角色控制器组件
controller = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
// 垂直方向的输入(WS按键)控制移动
float v = Input.GetAxis("Vertical");
controller.SimpleMove(transform.forward * moveSpeed * v);
// 水平方向的输入(AD按键)控制旋转
float h = Input.GetAxis("Horizontal");
transform.Rotate(0, rotateSpeed * h, 0);
// 按下按键W播放动画
if (Input.GetKeyDown(KeyCode.W))
{
animator.SetBool("is_run", true);
}
// 抬起按键W停止播放动画
if (Input.GetKeyUp(KeyCode.W))
{
animator.SetBool("is_run", false);
}
}
}
接下来,我们就来运行工程。
接下来,我们来添加相机跟随角色移动,鼠标控制相机旋转的代码。以前我们是将相机放置到角色的下面(成为角色的子游戏对象),这种方式虽然简单,但是存在一些问题。这里,我们将使用代码来控制相机跟随角色。原理很简单,就是当角色移动的时候,相机也跟随移动。我们创建一个新的脚本“CameraScript.cs”文件,内容如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraScript : MonoBehaviour
{
// 游戏角色
private Transform player;
// 相机控制参数
private bool isRotating = false;
private Vector3 offset;
private float distance;
private float rotateSpeed = 2.0f;
// Start is called before the first frame update
void Start()
{
// 获取游戏角色
player = GameObject.Find("U_Character_REF").transform;
// 相机和游戏角色的偏移
offset = transform.position - player.position;
// 相机和游戏角色之间的距离
distance = offset.magnitude;
}
// Update is called once per frame
void Update()
{
// 鼠标右键控制相机旋转
if(Input.GetMouseButtonDown(1)) isRotating = true;
if(Input.GetMouseButtonUp(1)) isRotating = false;
// 相机围绕游戏角色旋转
if (isRotating)
{
// 围绕游戏角色的Y轴左右旋转
transform.RotateAround(player.position, player.up, rotateSpeed * Input.GetAxis("Mouse X"));
// 围绕相机(也可以试试游戏角色)的X轴上下旋转
transform.RotateAround(player.position, transform.right, -rotateSpeed * Input.GetAxis("Mouse Y"));
}
// 根据滚轮来增加和减小这个距离
distance += Input.GetAxis("Mouse ScrollWheel") * 1.0f;
offset = offset.normalized * distance;
// 游戏角色移动后,相机跟随移动,保持偏移
transform.position = player.position + offset;
}
}
接下来,我们要将这个脚本附加到相机上面。
接下来,我们稍微调整一下视角,
接下来,我们Play运行整个工程
总结:Unity推荐使用Input Manager来获取设备的输入信息。对于方向性输入肯定是使用Input.GetAxis("Horizontal")和Input.GetAxis("Vertical")方法来获取X/Y数值。这些X/Y数值可以直接用来控制游戏角色的移动(后续章节我们会详细介绍)。而对于按钮的输入,可以通过使用Input.GetButtonUp("Fire1")来获取是否按下状态。至于输入轴对应的什么类型的设备的按键,就可以在Input Manager来设置。可以是键盘,鼠标,或者游戏手柄。当然,Unity默认已经给我们添加了18个输入轴的设置。我们也可以继续添加新的设备按键设置输入轴。但是,这些设置对于我们的代码修改则是没有太大的影响。因为我们代码中,不管使用GetAxis方法,还是GetButtonUp方法,它的参数仅仅是输入轴的名称而已。
本课程涉及的内容已经共享到百度网盘:https://pan.baidu.com/s/1e1jClK3MnN66GlxBmqoJWA?pwd=b2id