一、效果展示
第三人稱視角:固定攝像機,無任何操作
第一人稱視角:用戶可以通過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;}
}