Unity3D实现相机沿朝向垂直方向移动并添加移动限制
旋转相机的侧向移动与范围限制实现
当相机处于旋转状态时,不能直接依赖世界坐标系的X/Z轴做移动限制,核心思路是基于相机自身的局部坐标系来处理移动逻辑与边界约束:
- 移动时,确保拖拽方向贴合相机的左右/前后朝向(局部X/Z轴)
- 限制时,将相机位置相对于初始锚点的偏移转换到局部空间做范围约束,再转回世界空间。
以下是修改后的完整实现代码:
using UnityEngine; [RequireComponent(typeof(Camera))] public class CameraController : MonoBehaviour { Camera cam; Vector3 dragOriginScreen; // 用屏幕坐标存拖拽起点,规避WorldPoint的Z轴误差 Vector3 initialCamPosition; // 相机初始位置,作为移动限制的锚点 bool isDragging = false; // 相机局部坐标系下的移动范围:X=左右最大距离,Z=前后最大距离 [Header("移动限制参数")] public Vector2 moveLimits = new Vector2(5f, 5f); void Awake() { cam = GetComponent<Camera>(); initialCamPosition = transform.position; // 记录初始位置作为移动锚点 } void LateUpdate() { HandleCameraDrag(); } void HandleCameraDrag() { if (Input.GetMouseButtonDown(0)) { isDragging = true; dragOriginScreen = Input.mousePosition; return; } if (Input.GetMouseButtonUp(0)) { isDragging = false; return; } if (!isDragging) return; // 计算屏幕拖拽的差值 Vector3 screenDelta = Input.mousePosition - dragOriginScreen; // 把屏幕差值转换成世界空间的移动量 Vector3 worldDelta = cam.ScreenToWorldPoint(screenDelta + dragOriginScreen) - cam.ScreenToWorldPoint(dragOriginScreen); // 2D视角下固定Z轴高度,3D视角可根据需求调整此逻辑 worldDelta.z = 0; // 计算无限制的目标位置 Vector3 targetPosition = initialCamPosition + worldDelta; // 应用移动范围限制 targetPosition = ClampCameraPosition(targetPosition); // 更新相机位置,并重置拖拽起点避免累积误差 transform.position = targetPosition; dragOriginScreen = Input.mousePosition; } Vector3 ClampCameraPosition(Vector3 targetPos) { // 计算目标位置相对于初始锚点的偏移量 Vector3 offsetFromInitial = targetPos - initialCamPosition; // 将世界空间偏移转换为相机局部坐标系下的偏移 Vector3 localOffset = transform.InverseTransformVector(offsetFromInitial); // 在局部坐标系内限制X(左右)和Z(前后)的移动范围 localOffset.x = Mathf.Clamp(localOffset.x, -moveLimits.x, moveLimits.x); localOffset.z = Mathf.Clamp(localOffset.z, -moveLimits.y, moveLimits.y); // 把受限后的局部偏移转换回世界空间,得到最终合规位置 Vector3 clampedWorldOffset = transform.TransformVector(localOffset); return initialCamPosition + clampedWorldOffset; } }
关键逻辑说明
屏幕拖拽计算优化:
改用屏幕坐标存储拖拽起点,避免ScreenToWorldPoint因相机近平面Z轴导致的计算偏差,让拖拽移动更流畅稳定。局部坐标系的限制逻辑:
transform.InverseTransformVector:将世界空间的位置偏移转换为相机自身局部空间的偏移,这样就能用相机的左右(X轴)、前后(Z轴)来判断是否越界。Mathf.Clamp:对局部空间的X/Z轴偏移做范围约束,确保相机始终在设定的矩形区域内移动。transform.TransformVector:将受限后的局部偏移转回世界空间,得到符合限制的最终相机位置。
视角适配:
代码中默认固定Z轴高度(适配2D视角),如果是3D视角,可删除worldDelta.z = 0的逻辑,同时调整moveLimits的Z轴参数来控制相机的前后移动范围。
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

