Unity中如何实现相机从后方跟随玩家控制的滚动球体?
相机跟随滚动球体的优化方案
我需要编写一个脚本,实现相机始终从后方跟随玩家控制的滚动球体:当球体向右旋转时,相机也同步旋转,但始终保持在球体后方并朝向球体移动方向,且不绕X轴和Z轴旋转。我刚接触编程一个月,以下是我编写的脚本,但它运行卡顿、流畅度差,不符合我的需求:
void Start() { offset = transform.position - player.transform.position; } // Update is called once per frame void LateUpdate() { CameraMovement(); } private void CameraMovement() { float inputX = Input.GetAxis("Horizontal"); float inputZ = Input.GetAxis("Vertical"); if (inputX > 0) { transform.position = player.transform.position + new Vector3(-3.5f, 2f, 0f); transform.LookAt(player.position); } else if (inputX < 0) { transform.position = player.transform.position + new Vector3(3.5f, 2f, 0f); transform.LookAt(player.position); } if(inputZ > 0) { transform.position = player.transform.position + new Vector3(0f, 2f, -3.5f); transform.LookAt(player.position); } else if(inputZ < 0) { transform.position = player.transform.position + new Vector3(0f, 2f, 3.5f); transform.LookAt(player.position); } else if(inputX == 0 && inputZ == 0) { transform.position = player.transform.position + new Vector3(0f, 5f, 0f); transform.LookAt(player.position); } }
原脚本问题分析
- 位置跳变无平滑:直接给相机赋值固定位置,没有过渡动画,导致视觉卡顿
- 逻辑冲突:同时按多个方向键时,后面的if分支会覆盖前面的位置设置,相机行为混乱
- 依赖输入而非实际移动:当球体因惯性滚动时,输入为0但球体还在动,相机会跳转到上方,不符合跟随需求
优化后的脚本
using UnityEngine; public class CameraFollow : MonoBehaviour { public Transform player; public float followDistance = 3.5f; public float heightOffset = 2f; public float smoothSpeed = 10f; private void LateUpdate() { FollowPlayer(); } private void FollowPlayer() { if (player == null) return; // 获取球体水平移动方向(忽略Y轴) Rigidbody playerRb = player.GetComponent<Rigidbody>(); Vector3 moveDir = new Vector3(playerRb.velocity.x, 0f, playerRb.velocity.z).normalized; // 球体静止时,沿用当前相机的朝向作为后方方向 if (moveDir.magnitude < 0.1f) { moveDir = -transform.forward; moveDir.y = 0f; moveDir.Normalize(); } // 计算相机目标位置:球体后方指定距离 + 高度偏移 Vector3 targetPos = player.position - moveDir * followDistance + Vector3.up * heightOffset; // 平滑移动相机 transform.position = Vector3.Lerp(transform.position, targetPos, Time.deltaTime * smoothSpeed); // 计算目标旋转:朝向球体,且只保留Y轴旋转(锁定X、Z轴) Quaternion targetRot = Quaternion.LookRotation(player.position - transform.position); targetRot = Quaternion.Euler(0f, targetRot.eulerAngles.y, 0f); // 平滑旋转相机 transform.rotation = Quaternion.Lerp(transform.rotation, targetRot, Time.deltaTime * smoothSpeed); } }
关键改进说明
- 基于球体实际移动方向:通过Rigidbody的速度获取移动方向,不管是输入控制还是惯性滚动,相机都能正确跟随
- 平滑过渡:用
Vector3.Lerp和Quaternion.Lerp实现位置和旋转的渐变,彻底解决卡顿 - 锁定非必要旋转:强制相机只绕Y轴旋转,满足不绕X、Z轴旋转的需求
- 参数可调试:
followDistance、heightOffset、smoothSpeed都能在Inspector面板调整,不用改代码就能适配不同场景
内容的提问来源于stack exchange,提问作者K-Afnan
相关产品推荐
相关产品推荐

