【Unity 2D实战】从零打造物理画线游戏:核心组件解析与鼠标交互实现

张开发
2026/6/9 10:54:32 15 分钟阅读

分享文章

【Unity 2D实战】从零打造物理画线游戏:核心组件解析与鼠标交互实现
1. 物理画线游戏的核心原理物理画线游戏的核心在于将物理模拟和图形渲染完美结合。当你用手指在屏幕上划出一条线时这条线不仅要能显示出来还要具备真实的物理特性——可以掉落、碰撞、甚至影响其他物体。在Unity中实现这个效果主要依赖三个关键组件EdgeCollider2D、Rigidbody2D和LineRenderer。EdgeCollider2D负责为画出的线条添加碰撞体让它可以与其他物体发生碰撞。Rigidbody2D则赋予线条物理特性比如重力、质量等。而LineRenderer则是Unity提供的专门用于绘制线条的组件它能根据一系列的点来渲染出平滑的线条。这三个组件各司其职又相互配合LineRenderer负责视觉表现EdgeCollider2D负责物理碰撞Rigidbody2D负责物理运动。当你在屏幕上画线时代码会实时记录鼠标位置作为线条的点同时更新LineRenderer的显示和EdgeCollider2D的碰撞形状。2. 项目准备与基础设置2.1 创建基础场景首先创建一个新的2D Unity项目。在场景中添加一个地面物体给它添加BoxCollider2D组件这样我们画出的线条才能有东西可以碰撞。地面可以简单用一个SpriteRenderer加上一个矩形Sprite来表现。接下来创建一个空物体命名为LineDrawer这将是我们的画线控制器。再创建一个名为Line的预制体它将代表我们画出的每一条线。给Line预制体添加三个关键组件LineRenderer、EdgeCollider2D和Rigidbody2D。2.2 组件参数配置LineRenderer的配置需要特别注意几个参数Width控制线条的粗细建议设置为0.1-0.3之间Color可以设置渐变颜色让线条更美观Corner Vertices建议设置为5这样线条拐角会更圆滑Use World Space一定要取消勾选否则线条会错位EdgeCollider2D只需要关注Edge Radius参数它决定了碰撞体的厚度通常设置为线条宽度的一半。Rigidbody2D保持默认即可但可以根据需要调整Gravity Scale来控制下落速度。3. 核心代码实现3.1 Line脚本解析Line脚本负责管理单条线的行为。核心功能包括动态添加新的点到线条中同步更新LineRenderer和EdgeCollider2D控制物理特性的开关public class Line : MonoBehaviour { public LineRenderer lineRenderer; public EdgeCollider2D edgeCollider; public Rigidbody2D rigidBody; [HideInInspector] public ListVector2 points new ListVector2(); [HideInInspector] public int pointCount 0; float pointsMinDistance 0.1f; float circleColliderRadius; public void AddPoint(Vector2 newPoint) { if (pointCount 1 Vector2.Distance(newPoint, GetLastPoint()) pointsMinDistance) return; points.Add(newPoint); pointCount; // 更新LineRenderer lineRenderer.positionCount pointCount; lineRenderer.SetPosition(pointCount - 1, newPoint); // 更新EdgeCollider if (pointCount 1) edgeCollider.points points.ToArray(); } public void UsePhysics(bool usePhysics) { rigidBody.isKinematic !usePhysics; } }AddPoint方法是核心它做了三件事检查新点与上一个点的距离避免点过于密集更新LineRenderer的点列表当点数大于1时更新EdgeCollider2D的碰撞点3.2 LinesDrawer脚本解析LinesDrawer负责处理鼠标输入和线条创建public class LinesDrawer : MonoBehaviour { public GameObject linePrefab; public LayerMask cantDrawOverLayer; Line currentLine; Camera cam; void Update() { if (Input.GetMouseButtonDown(0)) BeginDraw(); if (currentLine ! null) Draw(); if (Input.GetMouseButtonUp(0)) EndDraw(); } void BeginDraw() { currentLine Instantiate(linePrefab).GetComponentLine(); currentLine.UsePhysics(false); } void Draw() { Vector2 pos cam.ScreenToWorldPoint(Input.mousePosition); currentLine.AddPoint(pos); } void EndDraw() { if (currentLine.pointCount 2) { Destroy(currentLine.gameObject); } else { currentLine.UsePhysics(true); currentLine null; } } }这个脚本实现了完整的画线流程鼠标按下时开始画线BeginDraw鼠标移动时持续添加点到当前线Draw鼠标释放时结束画线EndDraw4. 高级功能与优化4.1 防止线条交叉在实际游戏中我们通常不希望线条可以交叉绘制。这可以通过物理检测来实现void Draw() { Vector2 pos cam.ScreenToWorldPoint(Input.mousePosition); float checkRadius lineWidth / 3f; RaycastHit2D hit Physics2D.CircleCast(pos, checkRadius, Vector2.zero, 0f, cantDrawOverLayer); if (hit) { EndDraw(); } else { currentLine.AddPoint(pos); } }这里使用了CircleCast来检测鼠标位置周围是否已经有线条存在。如果有就立即结束当前画线。4.2 线条美化技巧为了让画出的线条更美观可以尝试以下技巧使用渐变色LineRenderer的Color属性可以设置渐变添加发光效果通过Post Processing或Shader实现线条尾迹可以添加粒子效果跟随画线public Gradient lineColor; public float lineWidth; void Start() { currentLine.SetLineColor(lineColor); currentLine.SetLineWidth(lineWidth); }4.3 性能优化当画线数量很多时可能会影响游戏性能。可以考虑以下优化合并碰撞体将相邻线条的碰撞体合并简化线条减少不必要的点对象池重用线条对象而非频繁创建销毁5. 常见问题与解决方案5.1 线条显示不正常如果线条显示有问题检查以下几点LineRenderer的Use World Space是否关闭摄像机Projection是否设置为Orthographic材质球是否正确设置5.2 物理表现不符合预期如果物理表现不正常检查Rigidbody2D的Gravity Scale确认EdgeCollider2D的Edge Radius设置合适确保碰撞层级设置正确5.3 移动端适配要在手机上有更好的体验增加Input.touches处理调整线条宽度适应不同屏幕优化触控检测逻辑void Update() { if (Input.touchCount 0) { Touch touch Input.GetTouch(0); if (touch.phase TouchPhase.Began) BeginDraw(); if (currentLine ! null) Draw(); if (touch.phase TouchPhase.Ended) EndDraw(); } }6. 扩展思路掌握了基础实现后可以考虑扩展游戏玩法添加关卡设计要求玩家画出特定形状物理谜题用画线解决物理难题多人竞技实时比拼画线技巧特殊画笔不同物理属性的线条实现这些扩展的关键在于灵活运用物理参数和碰撞检测。比如可以通过修改Rigidbody2D的物理材质来创建弹性不同的线条或者通过修改LineRenderer的材质来创建特殊视觉效果。

更多文章