前言
在Unity中要實現第一人稱視角移動的方法有很多,每種方法各有優劣,本次要介紹的就是使用角色控制器CharacterController來實現的方法。
在閱覽下面的步驟之前,你首先需要一個第一人稱視角的實體。
最簡單的第一視角實體只需要一個Capsule和一個攝像機,就像這樣:
這樣,你就獲得了一個最簡單的人和一雙能看見世界的眼睛(雖然沒有四肢)
步驟一、使用角色控制器CharacterController實現角色的移動
接下來只要讓它能動起來就達到了我們的目的。所以我們要給它綁定上角色控制器CharacterController組件
什么是角色控制器CharacterController
角色控制器CharacterController,是Unity提供的可以實現移動的組件
調用CharacterController下的Move()方法即可以實現最簡單的人物移動。
同時,CharacterController下的isGrounded屬性可以檢測當前人物是否在地面上。
組件參數解釋:
Slope Limit 爬坡限制:小於或等於此角度時可以上坡
Step Offset 台階高度
Skin Width 皮膚寬度
Min Move Distance 最小移動距離
Center 中心點坐標
Radius 半徑
Height 高度
簡單的物體移動代碼示例:
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour
{
public float speed = 6.0F;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
private Vector3 moveDirection = Vector3.zero;
void Start()
{
float _horizontal = Input.GetAxis("Horizontal");
float _vertical = Input.GetAxis("Vertical");
}
void Update()
{
CharacterController controller = GetComponent<CharacterController>();
if (controller.isGrounded)
{
moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
if (Input.GetButton("Jump"))
moveDirection.y = jumpSpeed;
}
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
}
}
注意事項:
角色控制器CharacterContriller和剛體不同,它沒有碰撞效果,不可以像剛體一樣對齊施加一個力。
步驟二、添加攝像機視角旋轉代碼
添加上角色控制器組件和代碼之后,人物就可以隨着我們鍵盤WASD進行移動了。
但是只會前后移動不會轉身的人物可算不上是第一人稱視角移動。因此我們需要在角色控制的代碼基礎上添加使攝像機視角旋轉的代碼。
通過GetAxis()獲取鼠標的位移
Input.GetAxis("Mouse X");
Input.GetAxis("Mouse Y");
限定上下視角旋轉的范圍,(因為正常的人不可能縱向觀察360度,但是我們可以通過轉身觀察到橫向360度)
float RotationY = Mathf.Clamp(RotationY, minmouseY, maxmouseY);
需要注意的是,只有攝像機跟隨視角旋轉是不足夠的,還需要讓人物本身也一起旋轉。
this.transform.eulerAngles = new Vector3(0, RotationX, 0);
gretctCamera.transform.eulerAngles = new Vector3(RotationY, RotationX, 0);
最后綁定在人物上的代碼:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMoveController : MonoBehaviour
{
CharacterController playerController;
Vector3 direction;
public float speed = 1;
public float jumpPower = 5;
public float gravity = 7f;
public float mousespeed = 5f;
public float minmouseY = -45f;
public float maxmouseY = 45f;
float RotationY = 0f;
float RotationX = 0f;
public Transform agretctCamera;
// Use this for initialization
void Start()
{
playerController = this.GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
float _horizontal = Input.GetAxis("Horizontal");
float _vertical = Input.GetAxis("Vertical");
if (playerController.isGrounded)
{
direction = new Vector3(_horizontal, 0, _vertical);
if (Input.GetKeyDown(KeyCode.Space))
direction.y = jumpPower;
}
direction.y -= gravity * Time.deltaTime;
playerController.Move(playerController.transform.TransformDirection(direction * Time.deltaTime * speed));
RotationX += agretctCamera.transform.localEulerAngles.y + Input.GetAxis("Mouse X") * mousespeed;
RotationY -= Input.GetAxis("Mouse Y") * mousespeed;
RotationY = Mathf.Clamp(RotationY, minmouseY, maxmouseY);
this.transform.eulerAngles = new Vector3(0, RotationX, 0);
agretctCamera.transform.eulerAngles = new Vector3(RotationY, RotationX, 0);
}
}