Unity中如何实现拖拽结束后相机继续移动一段距离?
问题描述
若问题较为基础,还请见谅我的知识储备不足。我希望实现以下效果:拖拽屏幕时相机向滑动的反方向移动,当拖拽结束后,相机继续向该方向再移动一小段距离。我已在YouTube和谷歌搜索相关解决方案但未找到结果,恳请提供相关实现思路。
当前代码:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PanZoom : MonoBehaviour { Vector3 touchStart; [SerializeField] float moveCameraSpeed = 3f; // Update is called once per frame void LateUpdate() { if (Input.GetMouseButtonDown(0)) { touchStart = Camera.main.ScreenToWorldPoint(Input.mousePosition); } if (Input.GetMouseButton(0)) { Vector3 direction = touchStart - Camera.main.ScreenToWorldPoint(Input.mousePosition); transform.position = Vector3.Lerp(Camera.main.transform.position, Camera.main.transform.position + direction, Time.deltaTime * moveCameraSpeed); } } }
实现思路与修改方案
核心是通过记录拖拽时的移动速度,在拖拽结束后做减速运动模拟惯性滑动,具体实现步骤如下:
- 添加变量记录拖拽过程中的速度、惯性衰减系数、停止阈值,以及是否处于惯性状态
- 拖拽时实时计算移动速度,同时执行相机移动
- 拖拽结束后,基于记录的速度继续移动相机,并逐渐衰减速度直至停止
修改后的完整代码:
using UnityEngine; public class PanZoom : MonoBehaviour { Vector3 touchStart; Vector3 lastMousePos; // 记录上一帧鼠标位置 Vector3 currentVelocity; // 当前移动速度 bool isInertiaMoving = false; // 是否处于惯性滑动状态 [SerializeField] float moveCameraSpeed = 3f; [SerializeField] float inertiaDecay = 0.9f; // 惯性衰减系数,越小停得越快 [SerializeField] float minInertiaSpeed = 0.01f; // 停止惯性的最小速度阈值 void LateUpdate() { // 拖拽开始 if (Input.GetMouseButtonDown(0)) { touchStart = Camera.main.ScreenToWorldPoint(Input.mousePosition); lastMousePos = Input.mousePosition; isInertiaMoving = false; // 开始拖拽时停止惯性 currentVelocity = Vector3.zero; } // 拖拽过程中 if (Input.GetMouseButton(0)) { Vector3 currentMousePos = Input.mousePosition; // 计算鼠标移动的世界空间距离,得到移动方向和速度 Vector3 worldDelta = Camera.main.ScreenToWorldPoint(lastMousePos) - Camera.main.ScreenToWorldPoint(currentMousePos); currentVelocity = worldDelta / Time.deltaTime; // 计算速度(单位时间移动距离) // 移动相机 transform.position += currentVelocity * Time.deltaTime * moveCameraSpeed; lastMousePos = currentMousePos; } // 拖拽结束后的惯性滑动触发 if (Input.GetMouseButtonUp(0)) { isInertiaMoving = true; } // 执行惯性滑动逻辑 if (isInertiaMoving) { // 移动相机 transform.position += currentVelocity * Time.deltaTime * moveCameraSpeed; // 衰减速度 currentVelocity *= inertiaDecay; // 当速度低于阈值时停止惯性 if (currentVelocity.magnitude < minInertiaSpeed) { isInertiaMoving = false; currentVelocity = Vector3.zero; } } } }
关键细节说明
inertiaDecay:设置为0.9左右效果比较自然,数值越小惯性消失越快,越大滑得越久minInertiaSpeed:防止相机因为微小速度一直抖动,达到阈值就停止惯性- 拖拽时的速度计算:通过前后帧鼠标位置的世界空间差值除以时间,得到真实的移动速度,保证不同分辨率下惯性效果一致
内容的提问来源于stack exchange,提问作者SoManyQuestions
相关产品推荐
相关产品推荐

