推薦閱讀
- CSDN主頁
- GitHub開源地址
- Unity3D插件分享
- 簡書地址
- 我的個人博客
- QQ群:1040082875
大家好,我是佛系工程師☆恬靜的小魔龍☆,不定時更新Unity開發技巧,覺得有用記得一鍵三連哦,
一、前言
前段時間分享了UGUI的每個組件的屬性和使用方法,比如Text、Button、Image、Toggle、InputField、ScrollView等等,
接著分享了UGUI的一些原理,比如說UGUI的渲染模式、UGUI的縮放計算、UGUI的描點定位、UGUI的自動布局等等,
相信大家看完后會對UGUI有一個比較全面的認識了,
下面,就繼續分享UGUI的UI組件進行應用的實體,
這是本系列文章的第八篇:
【Unity3D-UGUI應用篇】(一)使用Text實作進度等待影片
【Unity3D-UGUI應用篇】(二)使用Image實作進度條影片
【Unity3D-UGUI應用篇】(三)使用UGUI實作層級選單
【Unity3D-UGUI應用篇】(四)使用UGUI彈窗顯示模型及彈窗模型互動
【Unity3D-UGUI應用篇】(五)使用Button完成滑鼠移動到UI上面顯示文字功能
【Unity3D-UGUI應用篇】(六)螢屏自適應(多分配率適配)
【Unity3D-UGUI應用篇】(七)UGUI實作視窗的自由拖拽
【Unity3D-UGUI應用篇】(八)Image實作畫線、畫三角形、畫正方形、畫圓
二、使用Image畫線
首先,來看效果圖:

實作:
(1)搭建一個簡單的UI場景:

讓Panel覆寫整個螢屏,然后將Image寬高設定為1,在后面用代碼設定寬高,
(2)撰寫代碼DrawLine.cs
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
/// <summary>
/// 掛載在Panel上
/// </summary>
public class DrawLine : MonoBehaviour, IPointerDownHandler, IDragHandler
{
public Image image;//畫線的Image
public Vector2 rectA;//起點
public Vector2 rectB;//終點
//劃線功能
void DrawStraightLine(Image image, Vector2 a, Vector2 b)
{
float distance = Vector2.Distance(a, b); //求距離
float angle = Vector2.SignedAngle(a - b, Vector2.left); //求夾角
image.GetComponent<RectTransform>().anchoredPosition = (a + b) / 2;
image.GetComponent<RectTransform>().sizeDelta = new Vector2(distance, 5); //長度,寬度
image.transform.localRotation = Quaternion.AngleAxis(-angle, Vector3.forward);
}
public void OnPointerDown(PointerEventData eventData)
{
Vector2 startPoint = new Vector2(eventData.position.x - 960, eventData.position.y - 540);
rectA = startPoint;
}
public void OnDrag(PointerEventData eventData)
{
Vector2 endPoint = new Vector2(eventData.position.x - 960, eventData.position.y - 540);
rectB = endPoint;
DrawStraightLine(image, rectA, rectB);
}
}
一個起點,一個終點,然后呼叫UGUI的介面實作點擊、拖拽等介面代碼,
(3)將腳本掛載在Panel,然后將Image拖到對應卡槽中即可,

(4)運行程式

三、使用Image畫三角形
先看效果圖:

在上一個實體的基礎上,修改代碼完成,
因為三角形需要有三個點,三條線,所以需要在上一個實體基礎上再復制兩個Image出來:

修改DrawLine.cs代碼:
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
/// <summary>
/// 掛載在Panel上
/// </summary>
public class DrawLine1 : MonoBehaviour, IPointerDownHandler, IDragHandler,IPointerUpHandler
{
public Image image;//畫線的Image
public Image image1;//畫線的Image
public Image image2;//畫線的Image
private Vector2 rectOne;//第一個點
private Vector2 rectTwo;//第二個點
private Vector2 rectThree;//第三個點
private int lineIndex = 0;
//劃線功能
void DrawStraightLine(Image image, Vector2 a, Vector2 b)
{
float distance = Vector2.Distance(a, b); //求距離
float angle = Vector2.SignedAngle(a - b, Vector2.left); //求夾角
image.GetComponent<RectTransform>().anchoredPosition = (a + b) / 2;
image.GetComponent<RectTransform>().sizeDelta = new Vector2(distance, 5); //長度,寬度
image.transform.localRotation = Quaternion.AngleAxis(-angle, Vector3.forward);
}
void DrawStraightLine1(Image image, Vector2 a, Vector2 b)
{
float distance = Vector2.Distance(a, b); //求距離
float angle = Vector2.SignedAngle(a - b, Vector2.left); //求夾角
image1.GetComponent<RectTransform>().anchoredPosition = (a + b) / 2;
image1.GetComponent<RectTransform>().sizeDelta = new Vector2(distance, 5); //長度,寬度
image1.transform.localRotation = Quaternion.AngleAxis(-angle, Vector3.forward);
}
void DrawStraightLine2(Image image, Vector2 a, Vector2 b)
{
float distance = Vector2.Distance(a, b); //求距離
float angle = Vector2.SignedAngle(a - b, Vector2.left); //求夾角
image2.GetComponent<RectTransform>().anchoredPosition = (a + b) / 2;
image2.GetComponent<RectTransform>().sizeDelta = new Vector2(distance, 5); //長度,寬度
image2.transform.localRotation = Quaternion.AngleAxis(-angle, Vector3.forward);
}
public void OnPointerDown(PointerEventData eventData)
{
if (lineIndex == 0)
{
Vector2 startPoint = new Vector2(eventData.position.x - 960, eventData.position.y - 540);
rectOne = startPoint;
}
}
public void OnPointerUp(PointerEventData eventData)
{
if (lineIndex == 0)
{
lineIndex = 1;
}
else if (lineIndex == 1)
{
lineIndex = 2;
DrawStraightLine2(image, rectThree, rectOne);
}
}
public void OnDrag(PointerEventData eventData)
{
if (lineIndex == 0)
{
Vector2 endPoint = new Vector2(eventData.position.x - 960, eventData.position.y - 540);
rectTwo = endPoint;
DrawStraightLine(image, rectOne, rectTwo);
}
else if(lineIndex == 1)
{
Vector2 endPoint = new Vector2(eventData.position.x - 960, eventData.position.y - 540);
rectThree = endPoint;
DrawStraightLine1(image, rectTwo, rectThree);
}
}
}
在不同的點擊、拖拽狀態下,畫不同的線,完成三角形的繪制,
將這個腳本掛載在Panel物件上,并且拖進去不同的Image:

運行程式:

四、使用Image畫四邊形、正方形
先看效果圖:

這個也是在第一個實體的繼續上進行修改,
當兩個點連上一條直線,送開滑鼠,根據兩點的距離長度,求出其他點的位置坐標然后生成四邊形,如圖所示:

修改DrawLine.cs代碼:
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
/// <summary>
/// 掛載在Panel上
/// </summary>
public class DrawLine2 : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
public Image image;//畫線的Image
public Image image1;//畫線的Image
public Image image2;//畫線的Image
public Image image3;//畫線的Image
private Vector2 rectOne;//第一個點
private Vector2 rectTwo;//第二個點
private Vector2 rectThree;//第三個點
private Vector2 rectFour;//第四個點
//劃線功能
void DrawStraightLine(Image image, Vector2 a, Vector2 b)
{
float distance = Vector2.Distance(a, b); //求距離
float angle = Vector2.SignedAngle(a - b, Vector2.left); //求夾角
image.GetComponent<RectTransform>().anchoredPosition = (a + b) / 2;
image.GetComponent<RectTransform>().sizeDelta = new Vector2(distance, 5); //長度,寬度
image.transform.localRotation = Quaternion.AngleAxis(-angle, Vector3.forward);
}
void DrawStraightLine1(Image image, Vector2 a, Vector2 b,Vector2 c,Vector2 d)
{
float distance = Vector2.Distance(a, b); //求距離
float angle = Vector2.SignedAngle(a - b, Vector2.left); //求夾角
image.GetComponent<RectTransform>().anchoredPosition = (a + b) / 2;
image.GetComponent<RectTransform>().sizeDelta = new Vector2(distance, 5); //長度,寬度
image.transform.localRotation = Quaternion.AngleAxis(-angle, Vector3.forward);
float distance1 = Vector2.Distance(b, c); //求距離
float angle1 = Vector2.SignedAngle(b - c, Vector2.left); //求夾角
image1.GetComponent<RectTransform>().anchoredPosition = (b + c) / 2;
image1.GetComponent<RectTransform>().sizeDelta = new Vector2(distance1, 5); //長度,寬度
image1.transform.localRotation = Quaternion.AngleAxis(-angle1, Vector3.forward);
float distance2 = Vector2.Distance(c, d); //求距離
float angle2 = Vector2.SignedAngle(c - d, Vector2.left); //求夾角
image2.GetComponent<RectTransform>().anchoredPosition = (c + d) / 2;
image2.GetComponent<RectTransform>().sizeDelta = new Vector2(distance2, 5); //長度,寬度
image2.transform.localRotation = Quaternion.AngleAxis(-angle2, Vector3.forward);
float distance3 = Vector2.Distance(d, a); //求距離
float angle3 = Vector2.SignedAngle(d - a, Vector2.left); //求夾角
image3.GetComponent<RectTransform>().anchoredPosition = (d + a) / 2;
image3.GetComponent<RectTransform>().sizeDelta = new Vector2(distance3, 5); //長度,寬度
image3.transform.localRotation = Quaternion.AngleAxis(-angle3, Vector3.forward);
}
public void OnPointerDown(PointerEventData eventData)
{
Vector2 startPoint = new Vector2(eventData.position.x - 960, eventData.position.y - 540);
rectOne = startPoint;
}
public void OnPointerUp(PointerEventData eventData)
{
if (rectOne.y - rectTwo.y > 5)
{
float distance = Vector2.Distance(rectOne, rectTwo);
Vector2 c = new Vector2(rectOne.x + distance, rectOne.y);
Vector2 d = new Vector2(rectTwo.x + distance, rectTwo.y);
DrawStraightLine1(image, rectOne, rectTwo, d, c);
}
else
{
float distance = Vector2.Distance(rectOne, rectTwo);
Vector2 c = new Vector2(rectOne.x , rectOne.y- distance);
Vector2 d = new Vector2(rectTwo.x , rectTwo.y - distance);
DrawStraightLine1(image, rectOne, rectTwo, d, c);
}
}
public void OnDrag(PointerEventData eventData)
{
Vector2 endPoint = new Vector2(eventData.position.x - 960, eventData.position.y - 540);
rectTwo = endPoint;
DrawStraightLine(image, rectOne, rectTwo);
}
}
因為四邊形需要四條線,所以需要復制4個Image,然后將腳本附加到Panel身上,將Image拖入到對應的卡槽中:

運行程式:

五、使用UGUI VertexHelper畫圓
先看效果圖:

實作:
新建腳本ChartUtilsPie.cs:
using UnityEngine;
using UnityEngine.UI;
public static class ChartUtilsPie
{
//畫圓形 其實就是畫三角形
public static void DrawCircle(VertexHelper vh, Vector2 circlepoint, float r, int segments, float startdegree, float enddegree)
{
float startangle = startdegree * Mathf.Deg2Rad;//代表多少多少角度*1的弧度
float angle = (enddegree - startdegree) * Mathf.Deg2Rad / segments;
Vector2 p1, p2;
p1 = new Vector2(circlepoint.x + r * Mathf.Sin(startangle), circlepoint.y + r * Mathf.Cos(startangle));
for (int i = 1; i <= segments; i++)
{
p2 = new Vector2(circlepoint.x + r * Mathf.Sin(startangle + angle * i), circlepoint.y + r * Mathf.Cos(startangle + angle * i));
DrawTriangle(vh, circlepoint, p1, p2, Color.red);
p1 = p2;
}
}
//畫三角
public static void DrawTriangle(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Color32 color)
{
UIVertex vertex1 = new UIVertex();
vertex1.position = p1;
vertex1.color = color;
vertex1.uv0 = Vector2.zero;
UIVertex vertex2 = new UIVertex();
vertex2.position = p2;
vertex2.color = color;
vertex2.uv0 = Vector2.zero;
UIVertex vertex3 = new UIVertex();
vertex3.position = p3;
vertex3.color = color;
vertex3.uv0 = Vector2.zero;
int index = vh.currentIndexCount;
vh.AddVert(vertex1);
vh.AddVert(vertex2);
vh.AddVert(vertex3);
vh.AddTriangle(index, index + 1, index + 2);
}
}
這個腳本就是主要畫圓的腳本,
通過畫很多個三角形,首尾相連,組成一個圓形,
DrawTriangle畫三角的函式沒啥好說的,就是三個點,中心點也是圓的圓心,然后三角形的兩個點,以及兩個點連成的線就是圓的弧,實作程序如圖所示:

所以,理論上這個三角形越多這個圓就越圓,
DrawCircle這個函式就是計算生成三角形的三個點,
這個三角形的中心點也就是圓點已經確定了,那么就根據中心點,然后半徑,得到經過圓心的量個點,經過圓心的點的公式為:
x=a+r cosθ y=b+r sinθ(θ∈ [0,2π) ) (a,b) 為圓心坐標,r 為圓半徑,θ 為引數,(x,y) 為經過點的坐標
就這樣求出p1和p2的坐標值:
p1 = new Vector2(circlepoint.x + r * Mathf.Sin(startangle), circlepoint.y + r * Mathf.Cos(startangle));
p2 = new Vector2(circlepoint.x + r * Mathf.Sin(startangle + angle * i), circlepoint.y + r * Mathf.Cos(startangle + angle * i));
然后p1=p2,首尾相連,下一個三角形的點等于上一個三角形的點,
然后新建腳本PieImageBase.cs:
using UnityEngine.UI;
public class PieImageBase : MaskableGraphic
{
protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
DrawCircleShow(vh);
}
protected virtual void DrawCircleShow(VertexHelper vh)
{
}
}
新建腳本DrawCircle.cs:
using UnityEngine;
using UnityEngine.UI;
public class DrawCircle : PieImageBase
{
[Header("圓的半徑")]
public float radius = 80;
[Header("圓的總度數")]
public float totaldegree = 360;
[Header("圓分成多少段畫")]
public int segments = 0;
[Header("圓心")]
private Vector2 circlepoint = Vector2.zero;
protected override void DrawCircleShow(VertexHelper vh)
{
vh.Clear();
ChartUtilsPie.DrawCircle(vh, circlepoint, radius, segments,0, totaldegree);
}
}
傳遞圓的半徑、圓心、圓的度數、圓分成多少度段畫,
當圓分成5個畫的時候,就相當于用5個三角形做成圓,就變成五邊形了:

這個值越大,圓就越圓:

還有總度數,修改總度數,圓也跟著變化:

總結一下,需要新建三個腳本:

然后,新建一個Panel覆寫全屏,在Panel下新建一個空物件,附加DrawCircle腳本:

因為是實時渲染,可以實時看到效果:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/298446.html
標籤:其他
