当前位置: 首页 > news >正文

UGUI 绘制线段

描述

点击鼠标左键在屏幕上绘制线段

准备

  1. VertexHelper 网格绘制工具类
  2. 向量、叉乘
  3. RectTransformUtility.ScreenPointToLocalPointInRectangle
  4. SetVerticesDirty
  5. OnPopulateMesh

思路

  1. 鼠标按下,记录线段起点;
  2. 鼠标持续按下,记录鼠标当前帧的移动向量;
  3. 使用叉乘获取垂直与移动向量的单位向量;
  4. 根据设置的宽度获取四个顶点;设置顶点脏数据,更新网格

示例

新建脚本,继承MaskableGraphic;
创建一个Image,移除Image组件,添加新建脚本。
脚本内容如下:

引入命名空间

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

属性

private List<List<UIVertex>> vertexList = new List<List<UIVertex>>();//缓存线段上的网格顶点
private Vector3 lastPoint;//上一帧的点击点
private Vector3 lastLeftPoint;
private Vector3 lastRightPoint;
bool isNewLine;//绘制新的线段
[SerializeField] private float lineWidth = 4f;//线段宽度

方法 绘制网格

protected override void OnPopulateMesh(VertexHelper vh)//绘制网格
{vh.Clear();for (int i = 0; i < vertexList.Count; i++)vh.AddUIVertexQuad(vertexList[i].ToArray());
}

方法 屏幕坐标转为本地坐标

Vector2 ScreenPointToLocalPoint(Vector2 mousePoint)
{var Rect = GetComponent<RectTransform>();Vector2 result = Vector2.zero;switch (canvas.renderMode){case RenderMode.ScreenSpaceOverlay:RectTransformUtility.ScreenPointToLocalPointInRectangle(Rect, mousePoint, null, out result);break;case RenderMode.ScreenSpaceCamera:RectTransformUtility.ScreenPointToLocalPointInRectangle(Rect, mousePoint, canvas.worldCamera, out result);break;case RenderMode.WorldSpace:RectTransformUtility.ScreenPointToLocalPointInRectangle(Rect, mousePoint, canvas.worldCamera, out result);break;}return result;
}

方法 设置网格顶点

private void Update()
{if (Input.GetMouseButtonDown(0))//按下鼠标坐标表示 绘制新的线段{lastPoint = ScreenPointToLocalPoint(Input.mousePosition);//屏幕点转换到当前recttransform上的点isNewLine = true;vertexList.Clear();//清除上一次绘制的线段 若要保留 可不清除}else{if (Input.GetMouseButton(0)){Vector3 currentPoint = ScreenPointToLocalPoint(Input.mousePosition);Vector3 dir = currentPoint - lastPoint;//移动向量if (dir.magnitude < 10)//移动量过小 不绘制网格return;Vector3 normal = Vector3.Cross(dir.normalized, transform.forward);//移动向量和当前ui的朝向 进行叉乘if (isNewLine){isNewLine = false;lastLeftPoint = lastPoint + normal * lineWidth;//绘制新的线段时 作为左侧起点lastRightPoint = lastPoint - normal * lineWidth;}Vector3 leftPoint = currentPoint + normal * lineWidth;//当前线段的左侧终点Vector3 rightPoint = currentPoint - normal * lineWidth;List<UIVertex> ver = new List<UIVertex>();UIVertex uIVertex = new UIVertex();//网格顶点列表uIVertex.position = lastLeftPoint;uIVertex.color = color;ver.Add(uIVertex);UIVertex uIVertex2 = new UIVertex();uIVertex2.position = lastRightPoint;uIVertex2.color = color;ver.Add(uIVertex2);UIVertex uIVertex3 = new UIVertex();uIVertex3.position = rightPoint;uIVertex3.color = color;ver.Add(uIVertex3);UIVertex uIVertex4 = new UIVertex();uIVertex4.position = leftPoint;uIVertex4.color = color;ver.Add(uIVertex4);vertexList.Add(ver);lastLeftPoint = leftPoint;//更新起点 当前帧的终点作为下一帧的起点lastRightPoint = rightPoint;lastPoint = currentPoint;SetVerticesDirty();//设置顶点脏数据 更新网格}}
}
http://www.lryc.cn/news/175234.html

相关文章:

  • 详细学习Mybatis(2)
  • LinkedList与链表
  • 纳米软件芯片自动化测试系统测试电源芯片稳压反馈的方法
  • 微信小程序之项目基本结构、页面的基础及宿主环境
  • C/C++鸡尾酒疗法 2023年5月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析
  • 人工智能及大模型简介
  • 基于springboot消防员招录系统
  • 手把手教你制作登录、注册界面 SpringBoot+Vue.js(cookie的灵活运用,验证码功能)
  • C++ Qt零基础入门进阶与企业级项目实战教程与学习方法分享
  • TypeScript学习记录
  • vue内置组件Transition的详解
  • 中秋节听夜曲,Android OpenGL 呈现周董专属的玉兔主题音乐播放器
  • 008_第一代软件系统架构
  • oracle客户端的安装(SQL Developer)
  • Mysql索引优化1
  • Spring常考知识点(IOC、事务、容器等)
  • Leetcode 2867. Count Valid Paths in a Tree
  • Jtti:Ubuntu下如何创建XFS文件系统的LVM
  • 做销售管理分析需要看哪些关键指标?
  • 【Python】自动完成手写字体图片贴入以及盖章工具
  • 基于Xml方式Bean的配置-初始化方法和销毁方法
  • 实时更新进度条:JavaScript中的定时器和异步编程技巧
  • 【简单图论】CF898 div4 H
  • 【大虾送书第十一期】适合新手自学的网络安全基础技能“蓝宝书”:《CTF那些事儿》
  • IDEA安装离线插件后重启无法打开
  • 论软件的可靠性设计
  • AG35学习笔记(一):debug串口抓取模组log、debug串口测试AT指令、echo命令通过串口发送16进制数据
  • Python进阶学习----一闭三器
  • C/S架构学习之TCP客户端
  • 系统集成|第十二章(笔记)