700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 【游戏开发实战】TapTap物理画线游戏 教你使用Unity实现2D物理画线功能 看到我为你

【游戏开发实战】TapTap物理画线游戏 教你使用Unity实现2D物理画线功能 看到我为你

时间:2024-01-04 00:53:09

相关推荐

【游戏开发实战】TapTap物理画线游戏 教你使用Unity实现2D物理画线功能 看到我为你

文章目录

一、前言二、思考三、验证我们的思考1、创建物体挂组件2、设置组件参数3、运行测试4、结论四、撸起袖子写代码1、Line.cs2、LinesDrawer.cs五、场景六、最终运行效果

一、前言

嗨,大家好,我是新发,我又来科普了,相信很多人玩过物理画线小游戏,比如下面这样子:

使用Unity如何实现物理画线功能呢?今天就来教大家。

最后的实现效果如下:

本工程已上传到GitHub,感兴趣的同学可自行下载学习。

GitHub地址:/linxinfa/UnityPhysicsDrawLine

二、思考

物理画线的核心就是:物理+画线。

物理:

想要有物理特性,最简单的做法就是挂碰撞体(Collider)和刚体(Rigidbody)组件。

画线:

可以使用LineRenderer组件来实现画线功能。

三、验证我们的思考

1、创建物体挂组件

创建一个空物体,重命名为Line,挂上EdgeCollider2DRigidbody2DLineRenderer组件。

2、设置组件参数

设置一下LineRenderer组件的参数。

Position:坐标点;

Width:线宽度;

Color:线颜色(支持渐变);

Corner Vertices:拐弯处的顶点数量(让拐弯圆滑一点);

End Cap Vertices:线段头尾的顶点数量(让线段头尾圆滑一点);

Use World Space:是否使用世界坐标(不要勾选);

Materias:材质球。

设置一下EdgeCollider2D组件的参数。

Edge Radius:边界碰撞体的半径。

Points:边界碰撞体的坐标点(要与LineRenderer的点一致)。

边界碰撞体设置完之后效果如下:

最后是Rigidbody2D组件的参数。主要是Gravity Scale:重力缩放值;这个值越大,物体受到的重力越大,掉落的加速度就越大。

3、运行测试

为了模拟掉落到地上的效果,我们加个地面。

运行测试效果如下:

4、结论

理论存在,实践验证成功。那么,接下来就是如何使用代码来实现鼠标画线了,关键的点就是把鼠标的坐标设置为线的点。

四、撸起袖子写代码

两个脚本,一个Line.cs负责线段的绘制,一个LinesDrawer.cs负责检测鼠标和生成线段与点。

1、Line.cs

using System.Collections;using System.Collections.Generic;using UnityEngine;/// <summary>/// 线脚本/// </summary>public class Line : MonoBehaviour{public LineRenderer lineRenderer;public EdgeCollider2D edgeCollider;public Rigidbody2D rigidBody;/// <summary>/// 点数组/// </summary>[HideInInspector] public List<Vector2> points = new List<Vector2>();[HideInInspector] public int pointCount = 0;/// <summary>/// 画线过程中点与点的最小距离/// </summary>float pointsMinDistance = 0.1f;float circleColliderRadius;/// <summary>/// 添加点/// </summary>/// <param name="newPoint"></param>public void AddPoint(Vector2 newPoint){if (pointCount >= 1 && Vector2.Distance(newPoint, GetLastPoint()) < pointsMinDistance)return;points.Add(newPoint);++pointCount;// 添加圆形碰撞var circleCollider = this.gameObject.AddComponent<CircleCollider2D>();circleCollider.offset = newPoint;circleCollider.radius = circleColliderRadius;// Line RendererlineRenderer.positionCount = pointCount;lineRenderer.SetPosition(pointCount - 1, newPoint);// 边界碰撞体的点if (pointCount > 1)edgeCollider.points = points.ToArray();}/// <summary>/// 获取最后一个点/// </summary>/// <returns></returns>public Vector2 GetLastPoint(){return lineRenderer.GetPosition(pointCount - 1);}/// <summary>/// 是否启用物理特性/// </summary>public void UsePhysics(bool usePhysics){rigidBody.isKinematic = !usePhysics;}/// <summary>/// 设置线颜色/// </summary>/// <param name="colorGradient"></param>public void SetLineColor(Gradient colorGradient){lineRenderer.colorGradient = colorGradient;}/// <summary>/// 设置画线的点与点之间的最小距离/// </summary>/// <param name="distance"></param>public void SetPointsMinDistance(float distance){pointsMinDistance = distance;}/// <summary>/// 设置线宽度/// </summary>/// <param name="width"></param>public void SetLineWidth(float width){lineRenderer.startWidth = width;lineRenderer.endWidth = width;circleColliderRadius = width / 2f;edgeCollider.edgeRadius = circleColliderRadius;}}

2、LinesDrawer.cs

using UnityEngine;/// <summary>/// 画线控制器/// </summary>public class LinesDrawer : MonoBehaviour{public GameObject linePrefab;public LayerMask cantDrawOverLayer;int cantDrawOverLayerIndex;[Space(30)]public Gradient lineColor;public float linePointsMinDistance;public float lineWidth;Line currentLine;Camera cam;private void Start(){cam = Camera.main;cantDrawOverLayerIndex = LayerMask.NameToLayer("CantDrawOver");}private void Update(){if (Input.GetMouseButtonDown(0))BeginDraw();if (null != currentLine)Draw();if (Input.GetMouseButtonUp(0))EndDraw();}// 画线逻辑-----------------------------------------------------------------------// 开始画线void BeginDraw(){// 实例化线预设currentLine = Instantiate(linePrefab, this.transform).GetComponent<Line>();// 设置参数currentLine.UsePhysics(false);currentLine.SetLineColor(lineColor);currentLine.SetPointsMinDistance(linePointsMinDistance);currentLine.SetLineWidth(lineWidth);}// 画线进行中void Draw(){var pos = cam.ScreenToWorldPoint(Input.mousePosition);// 防止线与线之间交叉RaycastHit2D hit = Physics2D.CircleCast(pos, lineWidth / 3f, Vector2.zero, 1f, cantDrawOverLayer);if (hit)EndDraw();elsecurrentLine.AddPoint(pos);}// 画线结束void EndDraw(){if (null == currentLine) return;if (currentLine.pointCount < 2){Destroy(currentLine.gameObject);}else{currentLine.gameObject.layer = cantDrawOverLayerIndex;currentLine.UsePhysics(true);currentLine = null;}}}

五、场景

将原来的Line保存为预设,并挂上Line脚本,赋值对应的变量。

添加一个LayerCantDrawOver,目的是防止画线的时候线与线交叉(也可以防止线与其他被标记为CantDrawOver层的物体交叉)。

在场景中创建一个空物体,重命名为LineDrawer,并挂上LineDrawer脚本,赋值对应的参数。

六、最终运行效果

【游戏开发实战】TapTap物理画线游戏 教你使用Unity实现2D物理画线功能 看到我为你画的彩虹了吗

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。