Unity mesh 畫線 line

image.png
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class MyLine : MaskableGraphic
{
    public Color[] LineColor = new Color[] { new Color(0, 1, 0, 0.5f), Color.red, Color.blue };

    public Vector3 p1;
    public Vector3 p2;

    public Vector3[] points;
    public float LineWidth = 1;

    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();

        if (points.Length < 2)
        {
            return;
        }
        //獲取繞Z軸旋轉(zhuǎn)90度的矩陣 這樣就可以得到垂直于這條線段的點(diǎn) 就能根據(jù)寬度繪制mesh點(diǎn)
        var mr = GetMatrixRotateZ(90);
        var ml = GetMatrixRotateZ(-90);

        for (int i = 0; i < points.Length - 1; i++)
        {
            Vector3 p0r = RotatePoint(points[i], points[i + 1], mr);
            Vector3 p0l = RotatePoint(points[i], points[i + 1], ml);
            Vector3 p1r = RotatePoint(points[i + 1], points[i], mr);
            Vector3 p1l = RotatePoint(points[i + 1], points[i], ml);

            //添加點(diǎn)
            vh.AddVert(p0r, LineColor[0], Vector2.zero);
            vh.AddVert(p0l, LineColor[0], Vector2.zero);
            vh.AddVert(p1r, LineColor[1], Vector2.zero);
            vh.AddVert(p1l, LineColor[1], Vector2.zero);

            int baseIndex = i * 4;
            //添加面
            vh.AddTriangle(baseIndex + 0, baseIndex + 2, baseIndex + 1);
            vh.AddTriangle(baseIndex + 0, baseIndex + 3, baseIndex + 2);
        }


        //下面注釋是只有兩個(gè)點(diǎn) 不使用循環(huán)寫法

        //Vector3 pp1 = mr * (p1 - p2).normalized;
        //Vector3 pp2 = ml * (p1 - p2).normalized;
        //Vector3 pp3 = mr * (p2 - p1).normalized;
        //Vector3 pp4 = ml * (p2 - p1).normalized;

        //pp1 *= LineWidth;
        //pp2 *= LineWidth;
        //pp3 *= LineWidth;
        //pp4 *= LineWidth;

        //pp1 += p1;
        //pp2 += p1;
        //pp3 += p2;
        //pp4 += p2;

        //vh.AddVert(pp1, c[0], Vector2.zero);
        //vh.AddVert(pp2, c[0], Vector2.zero);
        //vh.AddVert(pp3, c[1], Vector2.zero);
        //vh.AddVert(pp4, c[1], Vector2.zero);

        //vh.AddTriangle(0, 2, 1);
        //vh.AddTriangle(0, 3, 2);

    }


    public Vector3 RotatePoint(Vector3 p1, Vector3 p2, Matrix4x4 m)
    {
        //p1 - p2 得到兩點(diǎn)連線指向p1的向量 標(biāo)準(zhǔn)化后長度為1 左乘矩陣后得到垂直向量
        Vector3 pp1 = m * (p1 - p2).normalized;
        //由于原向量標(biāo)準(zhǔn)化了 所以旋轉(zhuǎn)后的向量長度還是1 所以直接乘上寬度
        pp1 *= LineWidth;
        //向量相加 得到點(diǎn)的坐標(biāo)(Vector3 既可以是坐標(biāo) 也可以是方向 注意區(qū)分算出來的結(jié)果是坐標(biāo)還是方向)
        pp1 += p1;
        return pp1;
    }

    //構(gòu)造一個(gè) 旋轉(zhuǎn)矩陣
    public Matrix4x4 GetMatrixRotateZ(float angle = 90)
    {
        angle = angle * Mathf.Deg2Rad;

        var rotateZMatrix = Matrix4x4.identity;

        rotateZMatrix.m00 = Mathf.Cos(angle);
        rotateZMatrix.m01 = Mathf.Sin(angle);

        rotateZMatrix.m10 = -Mathf.Sin(angle);
        rotateZMatrix.m11 = Mathf.Cos(angle);
        return rotateZMatrix;
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 這里介紹一個(gè)通過路徑點(diǎn),動(dòng)態(tài)自定義生成Mesh,來做到畫線效果的一種實(shí)現(xiàn)方式: 首先通過點(diǎn)來定義線的形狀。然后用A...
    ealton閱讀 1,990評(píng)論 1 2
  • 上圖是一個(gè)由任意凸多邊形構(gòu)成的導(dǎo)航網(wǎng)格,白線包圍區(qū)域代表著不可進(jìn)入的障礙區(qū)域,紅線包圍區(qū)域則可以進(jìn)入或穿越。網(wǎng)格中...
    _ArayA_閱讀 818評(píng)論 0 1
  • 當(dāng)一個(gè)國家由多邊形輪廓組合而成時(shí),我們?nèi)绾螌⑺D(zhuǎn)換成三角面模型呢? 國家球面Mesh生成思路: 多邊形輪廓內(nèi)生成一...
    忽而禿頭閱讀 5,651評(píng)論 0 1
  • 經(jīng)實(shí)驗(yàn),這種方式是目前能做到最好的方式了。 原理: 在點(diǎn)擊的地方畫出LineRender,分別計(jì)算出各個(gè)點(diǎn)的最大、...
    持刀的要遲到了閱讀 884評(píng)論 0 0
  • 最近做項(xiàng)目的時(shí)候,有一個(gè)需要從攝像機(jī)發(fā)出一條射線,當(dāng)射線檢測到有碰撞物體的時(shí)候,點(diǎn)擊鼠標(biāo)左鍵開始畫線。我是創(chuàng)立了一...
    KPort閱讀 7,453評(píng)論 0 3

友情鏈接更多精彩內(nèi)容