一、效果展示
第三人称视角:固定摄像机,无任何操作
第一人称视角:用户可以通过wsad进行前后左右移动,qe进行上升下降操作
不同视角之间切换会有一个过渡动画,切换第一视角的初始位置始终为原点(0,0,0)的位置,视频展示如下:
Unity实现第一人称视角与第三人称视角切换功能
二、实现完整代码
using System.Collections;
using UnityEngine;
using UnityEngine.UI;public class CameraControl : MonoBehaviour
{public Camera controlCameral; // ✅ 要控制的摄像机public Button buttoncChangeCamera; //切换视角按钮public float moveSpeed = 5f; //第一视角移动速度public float lookSensitivity = 2f; //第一视角镜头旋转灵敏度public float verticalLookLimit = 80f; //第一视角镜头垂直方向变化范围限制public Transform thirdPersonPosition; // 第三视角参考点(位置 + 角度)public Transform firstPersonPosition; // 第一视角参考点(位置 + 角度)public float transitionSpeed = 2f; //不同视角切换速度[SerializeField] private float rotationX = 0f;[SerializeField] private float currentYRotation = 0f;[SerializeField] private bool inFirstPerson = false;[SerializeField] private bool isTransitioning = false;void Start(){if (controlCameral == null){Debug.LogError("Camera is not assigned!");return;}// 初始化摄像机位置角度controlCameral.transform.position = thirdPersonPosition.position;controlCameral.transform.rotation = thirdPersonPosition.rotation;var euler = controlCameral.transform.eulerAngles;rotationX = euler.x;currentYRotation = euler.y;buttoncChangeCamera.onClick.AddListener(ChangeCameraView);}void Update(){if (!isTransitioning && inFirstPerson){HandleMouseLook();HandleMovement();}}/// <summary>/// 切换视角的方法/// </summary>public void ChangeCameraView(){if (isTransitioning || controlCameral == null) return;if (inFirstPerson){StartCoroutine(SwitchToPosition(thirdPersonPosition.position, thirdPersonPosition.rotation));}else{StartCoroutine(SwitchToPosition(firstPersonPosition.position, firstPersonPosition.rotation));}inFirstPerson = !inFirstPerson;}/// <summary>/// 第一视角,上下左右镜头旋转/// </summary>void HandleMouseLook(){float mouseX = Input.GetAxis("Mouse X") * lookSensitivity;float mouseY = Input.GetAxis("Mouse Y") * lookSensitivity;currentYRotation += mouseX;rotationX -= mouseY;rotationX = Mathf.Clamp(rotationX, -verticalLookLimit, verticalLookLimit);controlCameral.transform.localEulerAngles = new Vector3(rotationX, currentYRotation, 0f);}/// <summary>/// 第一视角,前后左右上下移动方法/// </summary>void HandleMovement(){float moveForward = Input.GetAxis("Vertical");float moveRight = Input.GetAxis("Horizontal");float moveUp = 0f;if (Input.GetKey(KeyCode.E)) moveUp += 1f;if (Input.GetKey(KeyCode.Q)) moveUp -= 1f;Vector3 move = controlCameral.transform.forward * moveForward +controlCameral.transform.right * moveRight +controlCameral.transform.up * moveUp;controlCameral.transform.position += move * moveSpeed * Time.deltaTime;}/// <summary>/// 切换不同位置方法/// </summary>/// <param name="targetPos">目标位置</param>/// <param name="targetRot">目标旋转角度</param>/// <returns></returns>IEnumerator SwitchToPosition(Vector3 targetPos, Quaternion targetRot){isTransitioning = true;Vector3 startPos = controlCameral.transform.position;Quaternion startRot = controlCameral.transform.rotation;float t = 0f;while (t < 1f){t += Time.deltaTime * transitionSpeed;controlCameral.transform.position = Vector3.Lerp(startPos, targetPos, t);controlCameral.transform.rotation = Quaternion.Slerp(startRot, targetRot, t);yield return null;}controlCameral.transform.position = targetPos;controlCameral.transform.rotation = targetRot;// 更新角度缓存Vector3 euler = controlCameral.transform.eulerAngles;rotationX = euler.x;currentYRotation = euler.y;isTransitioning = false;}
}