首页 > 其他分享 >使用MaskableGraphic画线段-生成Mesh方式

使用MaskableGraphic画线段-生成Mesh方式

时间:2023-06-18 15:44:25浏览次数:40  
标签:Vector3 GetUIVertex 线段 MaskableGraphic vertexQuadList Mesh var vectQuad1 array

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class UGUIPoplateMesh : MaskableGraphic, IPointerEnterHandler, IPointerExitHandler
{
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();

        for (int i = 0; i < vertexQuadList.Count; i++)
        {
            vh.AddUIVertexQuad(vertexQuadList[i]);
        }
    }

    List<UIVertex[]> vertexQuadList = new List<UIVertex[]>();
    Vector2 lastPoint = Vector2.zero;
    Vector2 lastLineVect = Vector2.zero;
    Vector3 lastNormal = Vector2.zero;
    bool isPointerInCavnas = false;
    bool isNewLine = false;
    bool isFirstPoint = true;
    public Camera uiCamera;
    public float width = 2f;
    
    protected override void Awake()
    {
        base.Awake();
        vertexQuadList.Clear();
    }

    void Update()
    {
        if(!isPointerInCavnas)
            return;

        if(Input.GetMouseButtonUp(2))
        {
            vertexQuadList.Clear();
            SetVerticesDirty();
            isFirstPoint = true;
            return;
        }

        if(Input.GetMouseButton(0))
        {
            var curPoint = GetScreenToLocalPoint(Input.mousePosition);
            if(isFirstPoint)
            {
                lastPoint = curPoint;
                isFirstPoint = false;
                isNewLine = true;
                return;
            }

            var vect = curPoint - lastPoint;

            if(vect.magnitude < 16)
                return;

            var normal3 = Vector3.Cross(vect, Vector3.forward).normalized;
            var normal = new Vector2(normal3.x, normal3.y);


            var lastUpPoint = lastPoint + normal * width;
            var lastDownPoint = lastPoint - normal * width;
            
            var curUpPoint = curPoint + normal * width;
            var curDownPoint = curPoint - normal * width;

            if(vertexQuadList.Count > 0)
            {
                // 获取上一个线段与当前绘制的线段的角度
                var angle = Vector3.Angle(lastLineVect, vect);
                // 如果不是平行的 在这之间补一个三角形
                if(angle != 0 || angle != 180)
                {
                    var array = vertexQuadList[vertexQuadList.Count - 1];

                    // 获取上边是否相交和相交的点
                    bool upinter = FindIntersectionPoint(array[0].position, array[3].position, lastUpPoint, curUpPoint, out var upinterPoint);
                    // 获取下边是否相交和相交的点
                    bool downinter = FindIntersectionPoint(array[1].position, array[2].position, lastDownPoint, curDownPoint, out var downinterPoint);

                    // 根据相交点判断如何找补三角形
                    if(upinter)
                    {
                        array[2].position = upinterPoint - width * lastNormal * 2;
                        array[3].position = upinterPoint;

                        lastUpPoint = upinterPoint;
                        lastDownPoint = upinterPoint - width * normal3 * 2;

                        
                        var vectQuad1 = new UIVertex[4];
                        vectQuad1[0] = GetUIVertex(upinterPoint);
                        vectQuad1[1] = GetUIVertex(array[2].position);
                        vectQuad1[2] = GetUIVertex(lastDownPoint);
                        vectQuad1[3] = GetUIVertex(upinterPoint);
                        vertexQuadList.Add(vectQuad1);
                    }
                    else if(downinter)
                    {
                        array[3].position = downinterPoint + width * lastNormal * 2;
                        array[2].position = downinterPoint;

                        lastUpPoint = downinterPoint + width * normal3 * 2;
                        lastDownPoint = downinterPoint;

                        
                        var vectQuad1 = new UIVertex[4];
                        vectQuad1[0] = GetUIVertex(array[3].position);
                        vectQuad1[1] = GetUIVertex(downinterPoint);
                        vectQuad1[2] = GetUIVertex(lastUpPoint);
                        vectQuad1[3] = GetUIVertex(array[3].position);
                        vertexQuadList.Add(vectQuad1);
                    }
                }
            }
            

            var vectQuad = new UIVertex[4];
            vectQuad[0] = GetUIVertex(lastUpPoint);
            vectQuad[1] = GetUIVertex(lastDownPoint);
            vectQuad[2] = GetUIVertex(curDownPoint);
            vectQuad[3] = GetUIVertex(curUpPoint);
            vertexQuadList.Add(vectQuad);
            
            lastNormal = normal;
            lastLineVect = vect.normalized;
            lastPoint = curPoint;
            lastUpPoint = curUpPoint;
            lastDownPoint = curDownPoint;
            CLog.Log(1, lastUpPoint, lastDownPoint);
            SetVerticesDirty();
        }   
    }

    bool FindIntersectionPoint(Vector3 A, Vector3 B, Vector3 C, Vector3 D , out Vector3 res)
    {
        Vector3 AB = B - A;
        Vector3 CD = D - C;
        res = Vector3.zero;
        float t1, t2;
        if (Vector3.Cross(AB, CD) == Vector3.zero)
        {
            // 矢量平行或共线,没有相交点
            Debug.Log("Vectors are parallel or collinear, no intersection point.");
            return false;
        }
        else
        {
            t1 = Vector3.Cross(C - A, CD).magnitude / Vector3.Cross(AB, CD).magnitude;
            t2 = Vector3.Cross(A - C, AB).magnitude / Vector3.Cross(CD, AB).magnitude;

            if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1)
            {
                // 有相交点
                res = A + t1 * AB;
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    UIVertex GetUIVertex(Vector2 pos)
    {
        var uIVertex = new UIVertex();
        uIVertex.color = color;
        uIVertex.position = pos;
        return uIVertex;
    }



    Vector2 GetScreenToLocalPoint(Vector3 v3)
    {
        RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, v3, uiCamera, out var point);
        return point;
    }

    void IPointerEnterHandler.OnPointerEnter(PointerEventData eventData)
    {
        isPointerInCavnas = true;
    }

    void IPointerExitHandler.OnPointerExit(PointerEventData eventData)
    {        
        isPointerInCavnas = false;
    }
}


标签:Vector3,GetUIVertex,线段,MaskableGraphic,vertexQuadList,Mesh,var,vectQuad1,array
From: https://www.cnblogs.com/itcod/p/17489194.html

相关文章

  • 凌乱的yyy / 线段覆盖
    题目背景快noip了,yyy很紧张!题目描述现在各大oj上有\(n\)个比赛,每个比赛的开始、结束的时间点是知道的。yyy认为,参加越多的比赛,noip就能考的越好(假的)。所以,他想知道他最多能参加几个比赛。由于yyy是蒟蒻,如果要参加一个比赛必须善始善终,而且不能同时参加\(2\)个......
  • Luogu3792 由乃与大母神原型和偶像崇拜 - 线段树 - set -
    题目链接:https://www.luogu.com.cn/problem/P3792题解:一点小小的空间震撼(ML:125MB)首先询问可以转化成:区间\([l,r]\)的\(max-min+1=r-l+1\)并且区间内没有重复元素。可以考虑对每个点\(i\)记一个前驱结点\(pr_i\),表示\(a_{pr_i}=a_i\),且\(pr_i\)是\(i\)前面离\(i\)......
  • Ubuntu - Add a Flameshot Icon for taking screenshot directly to Applications men
    Allapplications'desktopentriescanbefoundin/usr/share/applications.Youcancreateadesktopentryunder~/.local/share/applicationstomakeyourownicon.zzh@ZZHPC:/usr/share/applications$sudocporg.flameshot.Flameshot.desktop~/.local/sh......
  • Fix navmesh countour
    Fixnavmeshcountour(JinQing’sColumn,Jan.,2023)Afterchangingsomeparametersofwatershedregionpartitionalgorithm,mytestmeshgeneratedanoddregionshape,whichcausedawrongcontour.Wrongcontour:Wrongnavmesh:Thereare2regions,thebigre......
  • 【unity】TextMeshPro文本抖动效果
    文本抖动效果前言在部分电子游戏中,当角色处于狂喜、紧张或恐惧等激动情绪时,角色对话框中的文字会触发抖动等效果,这为游戏增色不少,如下。当我在网上查找相关资料时,没找到相关的实现,也可能是我搜索的关键词不对。总之今天来实现一下这个效果。实现思路目标效果是:在同一帧的动......
  • 线段树
    引入线段树是算法竞赛中常用的用来维护区间信息的数据结构。树状数组可以在$O(\logn)$的时间内实现单点修改、区间查询(求和、求最值、求异或等);而线段树还可以在$O(\logn)$时间内实现区间修改操作,例如将$[L,R]$区间范围内的值都加上一个常数,乘以一个常数,或者都置为某个......
  • Canvas_绘制线段、圆形、文本、图像、视频、处理图像数据
    Canvas_绘制线段、圆形、文本、图像、视频、处理图像数据绘制线段varcanvas1=document.querySelector("#canvas1");varctx=canvas1.getContext("2d");//设置开始路径ctx.beginPath()//设置绘制的起始点ctx.moveTo(50,50);//设置经过某个位置ctx.lineTo(50,30......
  • 线段树学习笔记
    时隔多日,我终于又回来了!这几天我学习几个高级数据结构,来和大家分享一下线段树。线段树,名字好高级啊,是不是非常难学?我个人觉得吧,线段树只要明白原理,记熟模板,做题还是比较容易的。QwQOK,我们切入正题。NO.1whatis线段树看图理解一下(图片还是比较形象的)简单线段树结构图这......
  • UE4 自定义StaticMesh碰撞失效
    将画刷编辑的Actor转换成静态网格体后,原有的碰撞消失了,解决办法如下:首先在内容浏览器中找到需要更改碰撞配置的网格体双击进入静态网格编辑器页面,右侧找到细节面板找到碰撞-->碰撞复杂度-->选择将复杂碰撞用作简单碰撞保存即可......
  • 计算点二维A到线段B的垂线距离
    #include<iostream>#include<cmath>usingnamespacestd;//计算距离函数doubledistance(doublex1,doubley1,doublex2,doubley2){returnsqrt(pow(x1-x2,2)+pow(y1-y2,2));}//计算点A到线段B的垂线距离doubleperpendicularDistance(doubl......