首页/ 第 7 章 · 物理系统/ 第 103 课
LESSON 103 · 物理系统

拖拽物体(鼠标拖拽 3D 物体)

拖拽已实现。下一课学爆炸与冲击力。

⏱ 约 14 分钟📊 难度:入门🗂 第 7 章 · 物理系统📍 第 103 / 300 课
课程进度
103 / 300

🎯本节学习目标

  • 实现射线拾取
  • 实现拖拽移动
  • 实现放下物体

🚀课程导读

“把箱子拖到机关上”是很多解谜/建造游戏的玩法。本课用射线 + 物理实现完整拖拽。

拖拽原理

三步走。

  1. 【拾取】鼠标按下时,从屏幕发射射线(第 100 课),命中带“可拖拽”标签/脚本的对象。
  2. 【拖起】让对象跟随鼠标移动(射线打在某个平面上,对象移动到命中点)。
  3. 【放下】鼠标松开时,停止跟随并保持物理状态。
  4. 【关键点】射线要打在“拖拽平面”(如地面 Plane)或使用“深度固定”。
  5. 【坐标转换】把鼠标屏幕坐标转成世界坐标。
  6. 【实现选择】简单版用直接改 Transform;物理版用刚体 velocity 或 MovePosition 更真实。
  7. 【标签】给可拖拽物体加 Tag “Draggable” 或专用脚本标记。
💡
本课是“射线 + 坐标转换 + 物理”的综合运用,逻辑简单但细节多。

实现拖拽

完整代码。

  1. 新建脚本 DragObject 挂到可拖拽物体上:
  2. private bool isDragging = false;
  3. private float distance = 5f;
  4. void OnMouseDown() { isDragging = true; }
  5. void OnMouseUp() { isDragging = false; }
  6. void Update() { if (isDragging) { Vector3 mouse = Input.mousePosition; mouse.z = distance; // 到相机的深度
  7. Vector3 worldPos = Camera.main.ScreenToWorldPoint(mouse);
  8. transform.position = Vector3.Lerp(transform.position, worldPos, 0.3f); // 平滑跟随 } }
  9. 【说明】OnMouseDown/Up 是 Unity 内置的“鼠标点中本物体”回调,前提:对象有碰撞体 + 有相机脚本。
  10. 保存播放:鼠标按住物体拖动,松开放下。
  11. 【物理版】给物体加刚体,改用 rb.MovePosition(worldPos) 更平滑。
  12. 【限制】一次拖一个:拖起时禁用其他物体拖拽(管理器控制)。
  13. 【放置判断】放下时检测是否在“目标区域”(触发器)内,触发机关。
OnMouseDown/Up 是最简单的拖拽入口;复杂需求再用射线+UI 事件(第 166 课)。

常见错误与排查

错误:OnMouseDown 不触发?
原因:对象无碰撞体,或相机没有挂可执行脚本,或物体被 UI 遮挡
解决:确认有碰撞体;确认 Main Camera 存在;UI 遮挡时改用射线方案。

动手练习

课后小任务(做出来才算真的学会)

  • 实现基本拖拽(Transform 跟随)
  • 给物体加刚体实现物理拖拽
  • 拖到指定触发器区域触发事件

本节小结

拖拽已实现。下一课学爆炸与冲击力。

完成打卡后,主站会实时更新你的学习进度 🎯

← 上一课物理查询与抛体运动