TapTap物理画线游戏,使用Unity实现2D物理画线功能
實現效果如下:
本工程已上傳到GitHub,感興趣的同學可自行下載學習。
GitHub地址:https://github.com/linxinfa/UnityPhysicsDrawLine
?
物理畫線的核心就是:物理+畫線。
物理:
想要有物理特性,最簡單的做法就是掛碰撞體(Collider)和剛體(Rigidbody)組件。
畫線:
可以使用LineRenderer組件來實現畫線功能。
1、創建物體掛組件
創建一個空物體,重命名為Line,掛上EdgeCollider2D、Rigidbody2D和LineRenderer組件。
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腳本,賦值對應的變量。
添加一個Layer:CantDrawOver,目的是防止畫線的時候線與線交叉(也可以防止線與其他被標記為CantDrawOver層的物體交叉)。
在場景中創建一個空物體,重命名為LineDrawer,并掛上LineDrawer腳本,賦值對應的參數。
六、最終運行效果
總結
以上是生活随笔為你收集整理的TapTap物理画线游戏,使用Unity实现2D物理画线功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 仿链家地图找房_iOS地图找房(类似链家
- 下一篇: 强网杯2019线上赛-misc