Unity 2D游戏如何实现基于拖拽的物品投掷功能?
解决方案:给拖拽结束后的刚体添加基于滑动速度的初速度
你的核心问题是结束拖拽时只恢复了重力,但没有给刚体施加与滑动速度匹配的初速度,所以物品只会受重力下落,不会“飞出去”。以下是修改后的完整代码,附带关键逻辑说明:
[SerializeField] private Canvas canvas; private RectTransform rectTransform; private Rigidbody2D rigidbody2D; // 记录拖拽过程的速度相关数据 private Vector2 lastDragDelta; private float lastDragTime; private void Awake() { rectTransform = GetComponent<RectTransform>(); rigidbody2D = GetComponent<Rigidbody2D>(); } public void OnBeginDrag(PointerEventData eventData) { // 拖拽开始时,让刚体暂时不受物理影响(运动学模式),关闭重力 rigidbody2D.isKinematic = true; rigidbody2D.gravityScale = 0; // 初始化速度记录变量 lastDragDelta = Vector2.zero; lastDragTime = Time.time; } public void OnDrag(PointerEventData eventData) { // 更新UI位置,同步到刚体位置 rectTransform.anchoredPosition += eventData.delta / canvas.scaleFactor; rigidbody2D.MovePosition(rectTransform.position); // 记录当前帧的拖拽位移和时间,用于计算速度 lastDragDelta = eventData.delta / canvas.scaleFactor; lastDragTime = Time.time; } public void OnEndDrag(PointerEventData eventData) { // 计算拖拽结束时的滑动速度:位移 / 时间差 float timeSinceLastDrag = Time.time - lastDragTime; Vector2 dragVelocity = lastDragDelta / timeSinceLastDrag; // 恢复刚体的物理特性,施加滑动速度 rigidbody2D.isKinematic = false; rigidbody2D.gravityScale = 50; rigidbody2D.velocity = dragVelocity; }
关键修改点说明:
- 拖拽时切换刚体模式:将
rigidbody2D.isKinematic设为true,避免拖拽过程中物理引擎干扰UI位置控制,同时关闭重力防止位移偏差。 - 同步刚体位置:拖拽时用
rigidbody2D.MovePosition同步UI位置到刚体,保证物理系统的位置数据和UI显示一致。 - 计算滑动速度:通过记录拖拽最后一帧的位移和时间差,算出滑动速度,赋值给
rigidbody2D.velocity,让物品按照拖拽的方向和速度飞出去。 - 调整速度系数(可选):如果飞出去的速度太快/太慢,可以给
dragVelocity乘以一个系数(比如dragVelocity * 1.5f)来调整力度。
额外注意事项:
- 确保Canvas的Render Mode设置为
Screen Space - Overlay或Screen Space - Camera,如果是World Space,需要额外处理UI坐标到世界坐标的转换。 - 动态刚体的
Linear Drag(线性阻力)可以适当调小,否则物品会很快减速停下,影响“飞出去”的效果。
内容的提问来源于stack exchange,提问作者Edavid2010
相关产品推荐
相关产品推荐

