仿《Enter The Gungeon》相机实现问题:鼠标跟随角色时相机失控
问题原因
- 直接使用像素坐标的
Input.mousePosition设置m_ScreenX/m_ScreenY,而Cinemachine的FramingTransposer这两个参数需要的是归一化屏幕坐标(范围通常为0~1,对应屏幕左→右/下→上)。当鼠标在屏幕边缘时,像素坐标值远大于999,导致偏移量超出合理范围,相机直接飞离角色。 - 硬编码除数999没有适配不同屏幕分辨率,换高分辨率屏幕问题会更严重。
解决方案
将鼠标像素坐标转换为视口归一化坐标,以屏幕中心为基准计算偏移,再通过灵敏度参数控制偏移幅度,避免过度偏移。同时确保相机始终以角色为跟随目标,保持平行(俯视视角下只需保证相机正交参数稳定,跟随目标设为角色即可)。
修正后的代码:
public class Cam : MonoBehaviour { [SerializeField] private CinemachineVirtualCamera _virtualCamera; // 控制鼠标偏移的灵敏度,值越大偏移越明显,建议0.1~0.3 [SerializeField] private float _mouseOffsetSensitivity = 0.2f; private CinemachineFramingTransposer _framingTransposer; void Start() { // 提前获取FramingTransposer组件,避免Update里重复GetType判断 var componentBase = _virtualCamera.GetCinemachineComponent(CinemachineCore.Stage.Body); if (componentBase is CinemachineFramingTransposer transposer) { _framingTransposer = transposer; // 初始设为屏幕中心,避免初始偏移 _framingTransposer.m_ScreenX = 0.5f; _framingTransposer.m_ScreenY = 0.5f; } } void Update() { if (_framingTransposer == null) return; // 将鼠标像素坐标转为视口坐标(范围0~1,左下(0,0),右上(1,1)) Vector2 mouseViewportPos = Camera.main.ScreenToViewportPoint(Input.mousePosition); // 计算相对于屏幕中心的偏移,乘以灵敏度后叠加到中心位置 float offsetX = (mouseViewportPos.x - 0.5f) * _mouseOffsetSensitivity; float offsetY = (mouseViewportPos.y - 0.5f) * _mouseOffsetSensitivity; // 设置屏幕偏移,确保值在合理范围(0~1)内,防止极端情况 _framingTransposer.m_ScreenX = Mathf.Clamp(0.5f + offsetX, 0.1f, 0.9f); _framingTransposer.m_ScreenY = Mathf.Clamp(0.5f + offsetY, 0.1f, 0.9f); } }
额外注意事项
- 确保
_virtualCamera的Follow目标设置为玩家角色,这样相机始终以角色为核心进行偏移,不会完全脱离。 - 若要保持相机与角色朝向平行(比如角色转向时相机同步旋转),可以给CinemachineVirtualCamera添加
CinemachineAimWithPOV组件,绑定鼠标输入控制旋转,同时设置跟随目标的旋转跟踪。 - 调整
_mouseOffsetSensitivity参数直到手感接近《Enter The Gungeon》的相机偏移效果。
内容的提问来源于stack exchange,提问作者Gn0rl
相关产品推荐
相关产品推荐

