基本原理概述
第一人称视角移动模拟的是玩家以自身视角在场景中移动和观察的体验。主要包含两个核心部分:
位置移动:根据用户的输入(如 W、A、S、D 键),在三维空间中改变相机的位置,实现前后左右移动。
视角旋转:根据鼠标的移动,改变相机的旋转角度,实现上下左右观察。
具体实现原理和步骤
- 位置移动
输入检测:通过Input类检测用户的按键输入。在 Unity 中,可以使用Input.GetAxis方法获取水平(Horizontal)和垂直(Vertical)方向的输入值,这些输入值通常是由键盘的 W、A、S、D 键或方向键控制的。
移动计算:根据输入值和移动速度,计算相机在当前帧需要移动的距离。移动方向通常基于相机的本地坐标系,即前后移动沿着相机的 Z 轴,左右移动沿着相机的 X 轴。
位置更新:将计算得到的移动距离添加到相机的当前位置上,使用transform.Translate方法实现相机位置的更新。 - 视角旋转
鼠标输入检测:使用Input.GetAxis方法获取鼠标的水平(Mouse X)和垂直(Mouse Y)移动值。
旋转计算:根据鼠标的移动值和旋转速度,计算相机在当前帧需要旋转的角度。通常,鼠标的水平移动控制相机绕 Y 轴旋转(左右观察),垂直移动控制相机绕 X 轴旋转(上下观察)。
旋转限制:为了避免相机在上下观察时出现翻转的情况,需要对相机绕 X 轴的旋转角度进行限制,通常将其限制在一个合理的范围内(如 -90° 到 90°)。
旋转更新:使用transform.Rotate或直接修改transform.eulerAngles来更新相机的旋转角度。
代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour {
public GameObject CapsulePlayer, MainCamerahead;
private float aixsX, aixsY, mouseScroll;
private int moveSpeed;
private int standardMoveSpeed = 600;
private int runMoveSpeed = 1000;
private int mouseScrollSpeed = 10;
private float mouseScrolbackSpeed = 0.05f;
private CharacterController charaControl;
private Camera charaCam;
public float mouseNumOne = 0, mouseNumTwo = 0;
public static bool chufa = false;
void Awake()
{
charaControl = GetComponent<CharacterController>();
charaCam = MainCamerahead.GetComponent<Camera>();
}
void Update()
{
aixsX = Input.GetAxis("Horizontal");
aixsY = Input.GetAxis("Vertical");
mouseScroll = Input.GetAxis("Mouse ScrollWheel");
if (Input.GetKey(KeyCode.LeftShift))
{
moveSpeed = runMoveSpeed;
}
else
{
moveSpeed = standardMoveSpeed;
}
charaControl.SimpleMove(transform.forward * moveSpeed * aixsY * 0.02f + transform.right * moveSpeed * aixsX * 0.02f);
/* ***********************镜头跟随鼠标移动的第一种方法**********************
float mousex = Input.GetAxis("Mouse X") * 2f;
float mousey = Input.GetAxis("Mouse Y") * 2f;
if (mousex > 180)
{
mousex = 180;
}
else if (mousex < -180)
{
mousex = -180;
}
if (Mathf.Abs(mousey) < 120f)
{
MainCamerahead.transform.localRotation = charaCam.transform.localRotation * Quaternion.Euler(-mousey, 0, 0);
CapsulePlayer.transform.localRotation = transform.localRotation * Quaternion.Euler(0, mousex, 0);
}
*/
//镜头跟随鼠标移动的第二种写法 (总之写法有很多,自己用着舒服就行)
if (chufa )
{
mouseNumOne += Input.GetAxis("Mouse Y");
mouseNumTwo += Input.GetAxis("Mouse X");
if (mouseNumOne > 180)
{
mouseNumOne = 180;
}
else if (mouseNumOne < -180)
{
mouseNumOne = -180;
}
if (Mathf.Abs(mouseNumOne) < 90f)
{
MainCamerahead.transform.Rotate(new Vector3(-1 * Input.GetAxis("Mouse Y"), 0, 0));
CapsulePlayer.transform.Rotate(0, 1.6f * Input.GetAxis("Mouse X"), 0);
}
}
else
{
//鼠标滑动镜头跟着滑动
if (Input.GetMouseButton(0))
{
mouseNumOne += Input.GetAxis("Mouse Y");
mouseNumTwo += Input.GetAxis("Mouse X");
if (mouseNumOne > 180)
{
mouseNumOne = 180;
}
else if (mouseNumOne < -180)
{
mouseNumOne = -180;
}
if (Mathf.Abs(mouseNumOne) < 90f)
{
MainCamerahead.transform.Rotate(new Vector3(-1 * Input.GetAxis("Mouse Y"), 0, 0));
CapsulePlayer.transform.Rotate(0, 1.6f * Input.GetAxis("Mouse X"), 0);
}
}
}
//放大缩小功能
if (charaCam.fieldOfView > 60)
{
charaCam.fieldOfView -= mouseScrolbackSpeed;
}
else if (charaCam.fieldOfView < 10)
{
charaCam.fieldOfView += mouseScrolbackSpeed;
}
else
{
charaCam.fieldOfView -= mouseScroll * mouseScrollSpeed;
}
}
}