因为是第一人称射击游戏,所以主角是不可见的,但在屏幕上可以看到主角手中拿的枪,尽管如此,我们还是需要为主角创建碰撞体,并控制其移动。 3.3.1 角色控制器 在菜单栏选择【GameObject】→【Create Empty】创建一个空的游戏体,将它的Tag设为Player,它便是我们的主角。 在菜单栏选择【Component】→【Physics】→【Character Controller】为主角添加一个角色控制器组件,使用这个组件提供的功能,我们将可以实现在控制主角移动的同时与场景的碰撞产生交互,比如在行走时不会穿到墙里面去。 为主角再添加一个Rigidbody组件,取消选择Use Gravity去掉重力模拟,并选中Is Kinematic使其不受物理演算影响,这样我们才能使用脚本控制其移动。在Character Controller组件中需要调整碰撞体的位置和大小,如图3-3所示。 图3-3 设置组件 创建脚本Player.cs: using UnityEngine; using System.Collections; public class Player : MonoBehaviour { // 组件 public Transform m_transform; CharacterController m_ch; // 角色移动速度 float m_movSpeed = 3.0f; // 重力 float m_gravity = 2.0f; // 生命值 public int m_life = 5; void Start () { // 获取组件 m_transform = this.transform; m_ch = this.GetComponent<CharacterController>(); } void Update () { // 如果生命为0,什么也不做 if (m_life <= 0) return; Control(); } void Control() { float xm = 0, ym = 0, zm = 0; // 重力运动 ym -= m_gravity*Time.deltaTime; // 上下左右运动 if (Input.GetKey(KeyCode.W)){ zm += m_movSpeed * Time.deltaTime; } else if (Input.GetKey(KeyCode.S)){ zm -= m_movSpeed * Time.deltaTime; } if (Input.GetKey(KeyCode.A)){ xm -= m_movSpeed * Time.deltaTime; } else if (Input.GetKey(KeyCode.D)){ xm += m_movSpeed * Time.deltaTime; } //移动 m_ch.Move( m_transform.TransformDirection(new Vector3(xm, ym, zm)) ); } void OnDrawGizmos() { Gizmos.DrawIcon(this.transform.position, "Spawn.tif"); } 这里的代码主要是控制主角前后左右移动。 在Start函数中,我们先获取了CharacterController组件,然后在Control函数中,通过键盘操作获得X和Y方向上的移动距离,最后使用CharacterController组件提供的Move移动主角。使用CharacterController提供的功能进行移动,在移动的同时会自动计算移动体与场景之间的碰撞。 在OnDrawGizmos函数中,用一个图标来显示主角,主要是为了观察方便。 将Player.cs脚本指定给主角的游戏体。运行游戏,按W、S、A、D键可以控制主角前后左右移动,但可能不易观察到,这是因为摄像机还没有与主角的游戏体关联起来。 3.3.2 摄像机 接下来我们将在Player.cs脚本中添加少许代码,使摄像机伴随着主角移动。 打开Player.cs,添加用于控制摄像机的属性: // 摄像机Transform Transform m_camTransform; // 摄像机旋转角度 Vector3 m_camRot; // 摄像机高度 float m_camHeight = 1.4f; 在Start函数中初始化摄像机的位置和旋转角度,并锁定鼠标: void Start () { // 获取组件 m_transform = this.transform; m_ch = this.GetComponent<CharacterController>(); // 获取摄像机 m_camTransform = Camera.main.transform; // 设置摄像机初始位置 Vector3 pos = m_transform.position; pos.y += m_camHeight; m_camTransform.position = pos; m_camTransform.rotation = m_transform.rotation; m_camRot = m_camTransform.eulerAngles; //锁定鼠标 Screen.lockCursor = true; } 在Control函数中旋转摄像机,在移动主角后使摄像机位置与主角的位置保持一致: //获取鼠标移动距离 float rh = Input.GetAxis("Mouse X"); float rv = Input.GetAxis("Mouse Y"); // 旋转摄像机 m_camRot.x -= rv; m_camRot.y += rh; m_camTransform.eulerAngles = m_camRot; // 使主角的面向方向与摄像机一致 Vector3 camrot = m_camTransform.eulerAngles; camrot.x = 0; camrot.z = 0; m_transform.eulerAngles = camrot; // 操作主角移动,代码略… // 使摄像机的位置与主角一致 Vector3 pos = m_transform.position; pos.y += m_camHeight; m_camTransform.position = pos; 运行游戏,已经可以自由的在场景中行走。 3.3.3 武器 接下来我们将把武器绑定到摄像机上,使其随着主角移动。 将摄像机的位置和旋转角度都设为0。 将摄像机的Clipping Planes/ Near设为0.1,使其可以看到更近处的物体。 在Project窗口的Prefabs文件夹中找到M16.prefab,这是预设好的武器Prefab,将其拖入场景。 在Hierarchy窗口选择武器的Prefab(名字是M16),将其位置和旋转都设为0,并置于摄像机层级下方,使其成为摄像机的子物体。然后选择武器Prefab下一级层级中的枪模型weapon,调整它的位置和角度,并在Camera Preview中预览效果,直到效果满意为止,如图3-4所示。 图3-4 设置武器位置 运行游戏,效果如图3-5所示。 图3-5 第一人称视角