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

Unity-微信截图功能简单复刻-03绘制空心矩形

思路-绘制空心矩形

拓展UGUI的Graphic类,实现拖拽接口。
开始拖拽时记录鼠标位置,
使用拖拽中的鼠标位置和记录的位置,计算矩形顶点,绘制矩形。
两个三角形合并为一个矩形,作为空心矩形的一条边,四个边合并为空心矩形。

示例-绘制空心矩形

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;public class TestDraw : Graphic, IBeginDragHandler, IDragHandler, IEndDragHandler
{UIVertex[] rectangle1 = new UIVertex[4];UIVertex[] rectangle2 = new UIVertex[4];UIVertex[] rectangle3 = new UIVertex[4];UIVertex[] rectangle4 = new UIVertex[4];[SerializeField] float width = 5f;Vector3 lastPoint;protected override void Awake(){Init(rectangle1);Init(rectangle2);Init(rectangle3);Init(rectangle4);void Init(UIVertex[] uIVertices){var length = uIVertices.Length;for (int i = 0; i < length; i++)uIVertices[i] = new UIVertex();}}protected override void OnPopulateMesh(VertexHelper vh){vh.Clear();vh.AddUIVertexQuad(rectangle1);vh.AddUIVertexQuad(rectangle2);vh.AddUIVertexQuad(rectangle3);vh.AddUIVertexQuad(rectangle4);}public void ClearDraw(){Clear(rectangle1);Clear(rectangle2);Clear(rectangle3);Clear(rectangle4);void Clear(UIVertex[] uIVertices){var length = uIVertices.Length;for (int i = 0; i < length; i++)uIVertices[i].position = Vector3.zero;}SetVerticesDirty();}public void OnBeginDrag(PointerEventData eventData){lastPoint = ScreenPointToLocalPoint(rectTransform, eventData.position);}public void OnDrag(PointerEventData eventData){Vector3 point = ScreenPointToLocalPoint(rectTransform, eventData.position);if (lastPoint.x < point.x && lastPoint.y < point.y)//起点在左下角{//水平方向投影向量           var horizontalNormal = Vector3.Project(point - lastPoint, Vector3.right);SetRectangleVertex(point - horizontalNormal, point, lastPoint + horizontalNormal, lastPoint);SetRectangleColor(color);SetVerticesDirty();}else if (lastPoint.x > point.x && lastPoint.y > point.y)//起点在右上角{var horizontalNormal = Vector3.Project(point - lastPoint, Vector3.right);SetRectangleVertex(lastPoint + horizontalNormal, lastPoint, point - horizontalNormal, point);SetRectangleColor(color);SetVerticesDirty();}else if (lastPoint.x > point.x && lastPoint.y < point.y)//起点在右下角{var horizontalNormal = Vector3.Project(point - lastPoint, Vector3.right);SetRectangleVertex(point, point - horizontalNormal, lastPoint, lastPoint + horizontalNormal);SetRectangleColor(color);SetVerticesDirty();}else if (lastPoint.x < point.x && lastPoint.y > point.y)//起点在左上角{var horizontalNormal = Vector3.Project(point - lastPoint, Vector3.right);SetRectangleVertex(lastPoint, lastPoint + horizontalNormal, point, point - horizontalNormal);SetRectangleColor(color);SetVerticesDirty();}}public void OnEndDrag(PointerEventData eventData){lastPoint = Vector3.zero;}void SetRectangleVertex(Vector3 topLeftUp, Vector3 topRigthUp, Vector3 bottomRightDown, Vector3 bottomLeftDown){//top矩形rectangle1[0].position = topLeftUp;rectangle1[1].position = topRigthUp;rectangle1[2].position = topRigthUp - Vector3.up * width;rectangle1[3].position = topLeftUp - Vector3.up * width;//bottom矩形rectangle2[0].position = bottomRightDown;rectangle2[1].position = bottomLeftDown;rectangle2[2].position = bottomLeftDown + Vector3.up * width;rectangle2[3].position = bottomRightDown + Vector3.up * width;//left矩形rectangle3[0].position = topLeftUp - Vector3.up * width;rectangle3[1].position = topLeftUp - Vector3.up * width + Vector3.right * width;rectangle3[2].position = bottomLeftDown + Vector3.up * width + Vector3.right * width;rectangle3[3].position = bottomLeftDown + Vector3.up * width;//right矩形rectangle4[0].position = topRigthUp - Vector3.up * width;rectangle4[1].position = bottomRightDown + Vector3.up * width;rectangle4[2].position = bottomRightDown + Vector3.up * width - Vector3.right * width;rectangle4[3].position = topRigthUp - Vector3.up * width - Vector3.right * width;}void SetRectangleColor(Color color){var length = rectangle1.Length;for (int i = 0; i < length; i++)rectangle1[i].color = color;length = rectangle2.Length;for (int i = 0; i < length; i++)rectangle2[i].color = color;length = rectangle3.Length;for (int i = 0; i < length; i++)rectangle3[i].color = color;length = rectangle4.Length;for (int i = 0; i < length; i++)rectangle4[i].color = color;}Vector2 ScreenPointToLocalPoint(RectTransform rect, Vector2 mousePoint){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;}void Update(){if (Input.GetKeyDown(KeyCode.Space))ClearDraw();}
}

场景结构

在这里插入图片描述
TestDraw对象挂载TestDraw脚本,该对象需要CanvsRenderer脚本,大小为屏幕大小

运行结果

在这里插入图片描述
上方为矩形网格
运行,拖拽鼠标显示矩形。
按下空格键,清除矩形。

知识点

三角形的绘制需要三个顶点,三角形使用顺时针的顺序进行绘制。

其他几何图形的绘制思路

线:多个矩形组合而成
箭头:一个三角形,一个矩形组合而成。
空心椭圆:获取两个圆上的顶点,按照顺序绘制三角形。
椭圆绘制思路:已知圆心,半径
将圆划分多份,利用三角函数和弧度获取x坐标,y坐标。
将x,y坐标缩放,可得到椭圆上的点。

相关文章:

  • 【软件工程】用飞书画各种图(流程图,架构图···)
  • k8s教程3:Kubernetes应用的部署和管理
  • Unity-微信截图功能简单复刻-02屏幕采样
  • 12芯束装光纤不同包层线颜色之间的排列顺序
  • Vue3后代传祖先组件通讯方法
  • 04.Spring 框架注解体系详解
  • L2-006 树的遍历
  • Logisim数字逻辑实训——寄存器设计与应用
  • 【datawhaleAI春训营第一期笔记】AI+航空安全
  • openbmb/MiniCPM-V-2_6 和 AIDC-AI/Ovis2-1B 的网络结构体对比
  • 专著出版能为评职助力吗?
  • IPTV电视信息发布直播点播系统:营造数字化个性化融合化多媒体IPTV电视信息发布平台
  • 数据结构学习笔记 :二叉搜索树与高效查找算法详解
  • 认知觉醒是什么? 如何做到 ? ( 持续更新ing )
  • FairMOT算法详解
  • 《软件设计师》复习笔记(12.3)——质量管理、风险管理
  • 《数据牢笼》-来自DeepSeek
  • iPaaS应用集成平台在交通运输行业有哪些应用场景
  • 第一期第16讲,17讲21:50
  • 淘宝商品搜索爬虫:Python 实现教程
  • 春山谷雨前,并手摘芳烟
  • 天工摘得全球首个人形机器人半马冠军:中国机器人产业正努力跑向人机共生社会
  • 中物联声明:反对美对华物流、海事和造船领域301调查措施
  • 山东临沂市市长张宝亮履新市委书记
  • 8个月女婴被指受虐后体重仅6斤?潮州警方:未发现虐待,父母有抚养意愿
  • 观察|雀巢咖啡加码中国布局,如何借势云南咖啡打造新增长极?