This is the 26th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Recommended reading

  • CSDN home page
  • GitHub open source address
  • Unity3D plugin sharing
  • Jane’s address book
  • My personal blog
  • QQ group: 1040082875

Hello everyone, I am a Buddhist engineer ☆ quiet small magic dragon ☆, update Unity development skills from time to time, think useful remember one key three link oh.

One, foreword

The attributes and usage methods of each UGUI component, such as Text, Button, Image, Toggle, InputField, ScrollView, etc.

Then share some principles of UGUI, such as UGUI rendering mode, UGUI zoom calculation, UGUI tracing point positioning, UGUI automatic layout and so on.

I believe you will have a more comprehensive understanding of UGUI after reading.

Next, I’ll share an example of the UGUI UI component being applied.

This is the eighth article in this series: 【Unity3D-UGUI Application 】 (1) Use Text to achieve progress waiting animation (2) Use Image to achieve progress bar animation (unity3D-UGUI application) (3) Use UGUI to achieve hierarchy menu 【 UNity3D-UGUI Application 】 (6) Screen adaptation (multi-allocation rate adaptation) 【Unity3D-UGUI Application Chapter 】 (7) UGUI window free drag and drop (8) Image to draw lines, draw triangles, draw squares, draw circles

2. Use Image to draw lines

First, look at the renderings:Implementation: (1) Build a simple UI scene:Make the Panel cover the entire screen, then set the width and height of the Image to 1, and set the width and height with the code below.

(2) Write the code drawline.cs

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

/// <summary>
///Mount on Panel
/// </summary>
public class DrawLine : MonoBehaviour.IPointerDownHandler.IDragHandler
{
    public Image image;// Line Image
    public Vector2 rectA;/ / starting point
    public Vector2 rectB;/ / the end

    // Line function
    void DrawStraightLine(Image image, Vector2 a, Vector2 b)
    {
        float distance = Vector2.Distance(a, b);                                    / / distance
        float angle = Vector2.SignedAngle(a - b, Vector2.left);                     / / Angle
        image.GetComponent<RectTransform>().anchoredPosition = (a + b) / 2;
        image.GetComponent<RectTransform>().sizeDelta = new Vector2(distance, 5);   // Length, width
        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); }}Copy the code

A starting point, an end point, and then call the UGUI interface to achieve click, drag and drop interface code.

(3) Mount the script in the Panel, and then drag the Image to the corresponding card slot.(4) Run the program

3. Use Image to draw triangles

First look at the renderings:Based on the previous example, the modification code is complete.

Since a triangle needs to have three points and three lines, we need to copy two more images from the previous instance:Modify drawline.cs code:

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

/// <summary>
///Mount on Panel
/// </summary>
public class DrawLine1 : MonoBehaviour.IPointerDownHandler.IDragHandler.IPointerUpHandler
{
    public Image image;// Line Image
    public Image image1;// Line Image
    public Image image2;// Line Image
    private Vector2 rectOne;// First point
    private Vector2 rectTwo;// The second point
    private Vector2 rectThree;// The third point
    private int lineIndex = 0;

    // Line function
    void DrawStraightLine(Image image, Vector2 a, Vector2 b)
    {
        float distance = Vector2.Distance(a, b);                                    / / distance
        float angle = Vector2.SignedAngle(a - b, Vector2.left);                     / / Angle
        image.GetComponent<RectTransform>().anchoredPosition = (a + b) / 2;
        image.GetComponent<RectTransform>().sizeDelta = new Vector2(distance, 5);   // Length, width
        image.transform.localRotation = Quaternion.AngleAxis(-angle, Vector3.forward);
    }

    void DrawStraightLine1(Image image, Vector2 a, Vector2 b)
    {
        float distance = Vector2.Distance(a, b);                                    / / distance
        float angle = Vector2.SignedAngle(a - b, Vector2.left);                     / / Angle
        image1.GetComponent<RectTransform>().anchoredPosition = (a + b) / 2;
        image1.GetComponent<RectTransform>().sizeDelta = new Vector2(distance, 5);   // Length, width
        image1.transform.localRotation = Quaternion.AngleAxis(-angle, Vector3.forward);
    }

    void DrawStraightLine2(Image image, Vector2 a, Vector2 b)
    {
        float distance = Vector2.Distance(a, b);                                    / / distance
        float angle = Vector2.SignedAngle(a - b, Vector2.left);                     / / Angle
        image2.GetComponent<RectTransform>().anchoredPosition = (a + b) / 2;
        image2.GetComponent<RectTransform>().sizeDelta = new Vector2(distance, 5);   // Length, width
        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); }}}Copy the code

Under different click and drag states, draw different lines to complete the drawing of the triangle.

Attach this script to the Panel object and drag in different images:Run the program:

4. Use Image to draw quadrilateral and square

First look at the renderings:This is also a continuation of the first instance.

When the two points are connected to a straight line, turn off the mouse and work out the coordinates of other points according to the distance between the two points and generate the quadrilateral, as shown in the figure:Modify drawline.cs code:

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

/// <summary>
///Mount on Panel
/// </summary>
public class DrawLine2 : MonoBehaviour.IPointerDownHandler.IDragHandler.IPointerUpHandler
{
    public Image image;// Line Image
    public Image image1;// Line Image
    public Image image2;// Line Image
    public Image image3;// Line Image
    private Vector2 rectOne;// First point
    private Vector2 rectTwo;// The second point
    private Vector2 rectThree;// The third point
    private Vector2 rectFour;// The fourth point

    // Line function
    void DrawStraightLine(Image image, Vector2 a, Vector2 b)
    {
        float distance = Vector2.Distance(a, b);                                    / / distance
        float angle = Vector2.SignedAngle(a - b, Vector2.left);                     / / Angle
        image.GetComponent<RectTransform>().anchoredPosition = (a + b) / 2;
        image.GetComponent<RectTransform>().sizeDelta = new Vector2(distance, 5);   // Length, width
        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);                                    / / distance
        float angle = Vector2.SignedAngle(a - b, Vector2.left);                     / / Angle
        image.GetComponent<RectTransform>().anchoredPosition = (a + b) / 2;
        image.GetComponent<RectTransform>().sizeDelta = new Vector2(distance, 5);   // Length, width
        image.transform.localRotation = Quaternion.AngleAxis(-angle, Vector3.forward);

        float distance1 = Vector2.Distance(b, c);                                    / / distance
        float angle1 = Vector2.SignedAngle(b - c, Vector2.left);                     / / Angle
        image1.GetComponent<RectTransform>().anchoredPosition = (b + c) / 2;
        image1.GetComponent<RectTransform>().sizeDelta = new Vector2(distance1, 5);   // Length, width
        image1.transform.localRotation = Quaternion.AngleAxis(-angle1, Vector3.forward);

        float distance2 = Vector2.Distance(c, d);                                    / / distance
        float angle2 = Vector2.SignedAngle(c - d, Vector2.left);                     / / Angle
        image2.GetComponent<RectTransform>().anchoredPosition = (c + d) / 2;
        image2.GetComponent<RectTransform>().sizeDelta = new Vector2(distance2, 5);   // Length, width
        image2.transform.localRotation = Quaternion.AngleAxis(-angle2, Vector3.forward);

        float distance3 = Vector2.Distance(d, a);                                    / / distance
        float angle3 = Vector2.SignedAngle(d - a, Vector2.left);                     / / Angle
        image3.GetComponent<RectTransform>().anchoredPosition = (d + a) / 2;
        image3.GetComponent<RectTransform>().sizeDelta = new Vector2(distance3, 5);   // Length, width
        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 = newVector2(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); }}Copy the code

Since the quadrilateral needs four lines, we need to copy four images, then attach the script to the Panel and drag the Image into the corresponding card slot:Run the program:

Use UGUI VertexHelper to draw circles

First look at the renderings:Implementation:

Create a new script, ChartUtilsPie. Cs:

using UnityEngine;
using UnityEngine.UI;

public static class ChartUtilsPie
{
    // Drawing a circle is drawing a triangle
    public static void DrawCircle(VertexHelper vh, Vector2 circlepoint, float r, int segments, float startdegree, float enddegree)
    {
        float startangle = startdegree * Mathf.Deg2Rad;// represents the number of degrees *1 radians
        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 = newVector2(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; }}/ / draw the triangle
    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); }}Copy the code

This script is the one that mainly draws circles.

By drawing many triangles, end to end, to form a circle.

The central point is also the center of the circle. Then the two points of the triangle and the line formed by the two points are the arcs of the circle.So, theoretically, the more triangles there are the rounder the circle will be.

The DrawCircle function evaluates the three points that form the triangle.

The center point of the triangle, namely the circle point, has been determined. Then, according to the center point and then the radius, a number of points passing through the center of the circle can be obtained. The formula of the points passing through the center of the circle is:

X =a+r cosθ y=b+r sinθ (θ∈ [0,2 π)) (a,b) is the coordinates of the center of the circle, r is the radius of the circle, θ is the parameter, and (x,y) is the coordinates of the passing point

Find the coordinates of P1 and p2 like this:

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));

And then p1 is equal to p2, head to tail, and the point on the next triangle is equal to the point on the last triangle.

Then create a new script 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){}}Copy the code

Create a new script drawcircle. cs:

using UnityEngine;
using UnityEngine.UI;

public class DrawCircle : PieImageBase{[Header("Radius of the circle")]
    public float radius = 80;
    [Header("The total degree of a circle.")]
    public float totaldegree = 360;
    [Header("How many sections of the circle are drawn?")]
    public int segments = 0;
    [Header("Circle")]
    private Vector2 circlepoint = Vector2.zero;

    protected override void DrawCircleShow(VertexHelper vh)
    {
        vh.Clear();
        ChartUtilsPie.DrawCircle(vh, circlepoint, radius, segments,0, totaldegree); }}Copy the code

Transfer the radius of the circle, the center of the circle, the degree of the circle, and how many degrees the circle is divided into.

When the circle is divided into five parts, it is equivalent to using five triangles to make a circle, which becomes a pentagon:The larger the value, the rounder the circle:There is also the total degree, modify the total degree, the circle also changes:To sum up, you need to create three new scripts:Then, create a new Panel to cover the full screen, create a new empty object under the Panel, and attach the DrawCircle script:Because it is real-time rendering, you can see the effect in real time: