Untiy自定义UI组件

==转载标明出处==

MaskableGraphic(可遮罩图形):

MaskableGraphic是Unity中多种UI组件的父类,比如Image、Text等。Untiy官网中关于MaskableGraphic的介绍只有一句:
A Graphic that is capable of being masked out.
一个可以遮盖的图形
1.关键属性maskable,当它等于false代表不可遮掩,等于true代表可以被其他组件遮盖。

2.关键方法OnPopulateMesh,在继承了MaskableGraphic的子类中重写该方法,向OnPopulateMesh方法中传入对应的VertexHelper类型(5.0以前的版本4.X是传入Mesh类型)的数据,即可构建出自己想要的组件。

3.VertexHelper是一个包含了网格数据中的顶点数据和三角面对应顶点的序号,不了解网格数据的同鞋可以去查看一下Mesh类型后者查看我的其他网格类型博文。

一个简单例子:在XY坐标轴绘制函数图

实现逻辑:

1.定义XY轴和箭头常量

1.1先定义一下XY轴的一些常量,写在一个单独的类中并序列化,这样可以在Inspector面板上显示常量并方便调节常量。

//序列化该类型
[Serializable]
public class FunctionalGraphBase
{/// <summary>/// 是否显示X轴/// </summary>public bool ShowXAxis = true;/// <summary>/// 是否显示Y轴/// </summary>public bool ShowYAxis = true;/// <summary>/// 是否显示刻度/// </summary>public bool ShowScale = false;/// <summary>/// 是否显示XY轴单位/// </summary>public bool ShowXYAxisUnit = true;/// <summary>/// X轴单位/// </summary>public string XAxisUnit = "X";/// <summary>/// Y轴单位/// </summary>public string YAxisUnit = "Y";/// <summary>/// XY轴刻度/// </summary>[Range(0.1f,100f)]public float XYAxisScale = 50f;/// <summary>/// XY轴宽度/// </summary>[Range(0.1f , 100f)]public float XYAxisWidth = 5.0f;/// <summary>/// XY轴颜色/// </summary>public Color XYAxisColor = Color.gray;/// <summary>/// 是否显示XY轴的箭头/// </summary>public bool ShowXYAxisArrow = true;/// <summary>/// 箭头尺寸/// </summary>public float ArrowSzie = 3.0f;
}
2.定义函数表达式常量

2.1 定义一个函数公式类型,Func委托是可以输出零到多个参数,并必须有一个返回值的委托类型,第一个float代表输入x值,返回值代表y值

比如:

Mathf.Sin : y = Mathf.Sin(x);
Mathf.Cos : y = Mathf.Cos(x);
直线函数 : y = 2*x + 3;

2.2 类型中定义改函数图的另外两个属性,一个是线条颜色,一个是线条宽度

public class FunctionFormula
{/// <summary>/// 函数表达式/// </summary>public Func<float,float> Formula;/// <summary>/// 函数图对应线条颜色/// </summary>public Color FormulaColor;public float FormulaWidth;public FunctionFormula(){}public FunctionFormula( Func<float , float> formula ,Color formulaColor ,float width ){Formula = formula;FormulaColor = formulaColor;FormulaWidth = width;}
}
3.绘制

箭头绘制原理图:

public class FunctionalGraph : MaskableGraphic
{public FunctionalGraphBase GraphBase = new FunctionalGraphBase();public List<FunctionFormula> Formulas = new List<FunctionFormula>();private RectTransform _myRect;/// <summary>/// 初始化函数信息,添加了五个函数公式/// </summary>private void Init(){_myRect = this.rectTransform;Formulas.Add(new FunctionFormula(Mathf.Sin , Color.red , 3.0f));Formulas.Add(new FunctionFormula(Mathf.Cos , Color.green , 2.0f));Formulas.Add(new FunctionFormula(Mathf.Sign , Color.blue , 2.0f));Formulas.Add(new FunctionFormula(Mathf.Sqrt , Color.magenta , 2.0f));Formulas.Add(new FunctionFormula(xValue => xValue * 1.3f + 1 , Color.yellow , 2.0f));}/// <summary>/// 重写这个类以绘制UI,首先初始化数据和清空已有的顶点数据/// </summary>/// <param name="vh"></param>protected override void OnPopulateMesh(VertexHelper vh){Init();vh.Clear();#region 基础框架的绘制//绘制X轴,获取X轴左右两个顶点,绘制一个矩形if (GraphBase.ShowXAxis){float lenght = _myRect.sizeDelta.x;Vector2 leftPoint = new Vector2(-lenght / 2.0f , 0);Vector2 rightPoint = new Vector2(lenght / 2.0f , 0);vh.AddUIVertexQuad(GetQuad(leftPoint , rightPoint , GraphBase.XYAxisColor , GraphBase.XYAxisWidth));// 绘制X轴的箭头// 箭头的绘制和矩形一样,只要传入四个顶点即可,见三角形的绘制详解图利用ABCD四个点绘制if (GraphBase.ShowXYAxisArrow){float arrowUnit = GraphBase.ArrowSzie / 2.0f;Vector2 firstPoint = rightPoint + new Vector2(0 , arrowUnit);Vector2 secondPoint = rightPoint;Vector2 thirdPoint = rightPoint + new Vector2(0 , -arrowUnit);Vector2 fourPoint = rightPoint + new Vector2(Mathf.Sqrt(3)* arrowUnit , 0);vh.AddUIVertexQuad(GetQuad(firstPoint,secondPoint,thirdPoint,fourPoint,GraphBase.XYAxisColor));}}//绘制Y轴,获取Y轴上下两个顶点,绘制一个矩形if (GraphBase.ShowYAxis){float height = _myRect.sizeDelta.y;Vector2 downPoint = new Vector2(0 , -height / 2.0f);Vector2 upPoint = new Vector2(0 , height / 2.0f);vh.AddUIVertexQuad(GetQuad(downPoint , upPoint , GraphBase.XYAxisColor , GraphBase.XYAxisWidth));// 绘制Y轴的箭头if ( GraphBase.ShowXYAxisArrow ){float arrowUnit = GraphBase.ArrowSzie / 2.0f;Vector2 firstPoint = upPoint + new Vector2(arrowUnit , 0);Vector2 secondPoint = upPoint;Vector2 thirdPoint = upPoint + new Vector2(-arrowUnit , 0);Vector2 fourPoint = upPoint + new Vector2(0 , Mathf.Sqrt(3) * arrowUnit);vh.AddUIVertexQuad(GetQuad(firstPoint , secondPoint , thirdPoint , fourPoint , GraphBase.XYAxisColor));}}#endregion#region 函数图的绘制//遍历函数公式,然后每隔一次像素绘制一个矩形foreach ( var functionFormula in Formulas ){Vector2 startPos = GetFormulaPoint(functionFormula.Formula , -_myRect.sizeDelta.x / 2.0f );//从X轴的负方向轴开始向正方向轴绘制for ( float x = -_myRect.sizeDelta.x / 2.0f + 1 ; x < _myRect.sizeDelta.x / 2.0f ; x++ ){Vector2 endPos = GetFormulaPoint(functionFormula.Formula , x );vh.AddUIVertexQuad(GetQuad(startPos , endPos , functionFormula.FormulaColor , functionFormula.FormulaWidth));//这里把当前绘制的结束点设置为下一次绘制的起始点startPos = endPos;}}#endregion}//通过两个端点绘制矩形private UIVertex[] GetQuad( Vector2 startPos , Vector2 endPos , Color color0 , float lineWidth = 2.0f ){float dis = Vector2.Distance(startPos , endPos);float y = lineWidth * 0.5f * ( endPos.x - startPos.x ) / dis;float x = lineWidth * 0.5f * ( endPos.y - startPos.y ) / dis;if ( y <= 0 ) y = -y;else x = -x;UIVertex[] vertex = new UIVertex[4];vertex[0].position = new Vector3(startPos.x + x , startPos.y + y);vertex[1].position = new Vector3(endPos.x + x , endPos.y + y);vertex[2].position = new Vector3(endPos.x - x , endPos.y - y);vertex[3].position = new Vector3(startPos.x - x , startPos.y - y);for ( int i = 0 ; i < vertex.Length ; i++ ) vertex[i].color = color0;return vertex;}//通过四个顶点绘制矩形private UIVertex[] GetQuad( Vector2 first , Vector2 second , Vector2 third , Vector2 four , Color color0 ){UIVertex[] vertexs = new UIVertex[4];vertexs[0] = GetUIVertex(first , color0);vertexs[1] = GetUIVertex(second , color0);vertexs[2] = GetUIVertex(third , color0);vertexs[3] = GetUIVertex(four , color0);return vertexs;}//构造UIVertexprivate UIVertex GetUIVertex( Vector2 point , Color color0 ){UIVertex vertex = new UIVertex{position = point ,color = color0 ,uv0 = new Vector2(0 , 0)};return vertex;}//利用Func委托,计算出每一个绘制点private Vector2 GetFormulaPoint( Func<float , float> formula ,float xValue ){return new Vector2(xValue , formula(xValue / GraphBase.XYAxisScale) *50 );}
}

高级用法多种可自定义的UI组件





其他折线图,曲线图等。

以上展示的组件都只需要在UI空物体上添加一个脚本即可实现,纯代码实现不需要其他资源,而且每一个组件在不调用GUI.Text进行文字绘制的情况下,只占用一个Batch,极大的减少了CPU交付GPU绘制的次数,提升效率。以上的其他UI组件,会在后续的博文中更新,并附上全部源码。

==转载标明出处==
CSDN博客:http://blog.csdn.net/qq_29579137 查看更多别的博文

Unity自定义UI组件(一)函数图篇(上)相关推荐

  1. Unity自定义UI组件(十一) 雷达图、属性图

    前言 借用梦想世界宠物属性图 想必大家都在游戏中见过属性图用于展示多种属性的数值,可以较为直观的对比某种属性的缺陷或者是哪种属性有优势.在三维可视化领域也会遇到类似的属性对比,用属性图来展示最为合适. ...

  2. Unity自定义UI组件(七)渐变工具、渐变色图片、渐变遮罩

    欢迎阅读Unity自定义UI组件(七)渐变工具.渐变色图片.渐变遮罩 前言 在Unity中UGUI只为我们提供了最为基础的Image和RawImage两种可展示图片的组件,但是这两种组件要展示一些特殊 ...

  3. Unity自定义UI组件(六)日历、日期拾取器

    前言 考虑到工业项目中可能会利用到类似日历的工具,就比如选取某个时间节点,所以我结合UGUI源码开发了日历工具和日期拾取器工具,简单易用,接口齐全,可中文显示,外观可自定义.只需要导入脚本,即可在Hi ...

  4. Android开发自定义UI组件

    Android开发自定义UI组件实现红色小球跟随手指移动 要写实现自定义UI组件,要创建一个BallView类,继承View类,在BallView类中创建画笔,然后重写OnDraw()方法和OnTou ...

  5. c++图形中如何判断鼠标点击在一条直线上_中考数学常考题型精讲精练系列:函数图象上点的存在性问题中的距离与面积...

    函数图象上点的存在性问题中的距离与面积(下)第1段 函数图象上点的存在性问题中的距离与面积(下)第2,3段 函数图象上点的存在性问题中的距离与面积(下)第4段 判断函数的图像是中考的重要考点,主要有以 ...

  6. Unity中UI组件

    一.Canvers(画布组件),Canvers下面是添加Button和Image组件 Rect Transform 1.Position:坐标位置 2.Width/Height 高宽尺寸 3.Anch ...

  7. SpringMvc+饿了么UI组件+七牛云做图片上传

    前言 我之前也有用过SpringBoot+OSS做过云存储,可以去看我的文章https://blog.csdn.net/Curtisjia/article/details/109339980,当时我做 ...

  8. element UI el-upload多张图 隐藏上传空间

    先包裹displayNone一个class名 然后通过css隐藏 <div class="displayNone"><el-uploadaction=" ...

  9. Unity之UI和登陆界面与暂停界面

    Unity----UI和登陆界面与暂停界面 接触了Unity制作不管是程序还是游戏都避免不了UI的制作,但是在网上搜的UI制作的学习过程,额-一言难尽,就像是拼图一样在那一块块搜索然后再将它拼装起来, ...

最新文章

  1. Oracle数据库备份与还原命令
  2. [C#]关于Access的“INSERT INTO 语句的语法错误”问题
  3. 深入理解SELinux SEAndroid
  4. 前端传递json,后端应该怎样接收呢?
  5. plsql 查看表空间使用情况
  6. 五、pygame做一个简单的五子棋游戏
  7. 微信收款播报器提示服务器断开,微信收款语音提醒开启后收不到语音提醒怎么办? 专家详解...
  8. Mugeda(木疙瘩)H5案例课—房地产楼书H5制作-岑远科-专题视频课程
  9. 设备状态监测及故障预警,你了解多少?
  10. java 读取 解析微软Project .mpp 文件
  11. 神之bug 嵌套RecyclerView谜之滚动
  12. 热敏电阻和压敏电阻的区别与特性
  13. 解决方案和项目的区别_(实习招聘)PwC面试官问Advisory和Consulting有什么区别,怎么答?...
  14. Hibernate 中setResultTransformer使用
  15. [帮助理解PO文件]KDE中国/I18N/L10N
  16. VC Socket编程源码
  17. Google桌面搜索中文版印象(转)
  18. mysql使用注意事项
  19. 服务端渲染(SSR) 通用技术解决方案
  20. 初识数据结构:链表实现图书信息管理系统(C语言,仅供参考)

热门文章

  1. Mac 上 “USB 10/100 LAN”有一个自分配的IP地址,将无法接入互联网。
  2. 记录更改内核的拥塞控制算法
  3. 双十二购买护眼台灯亮度多少合适?灯光亮度多少对眼睛比较好呢
  4. 二月 Z 星月度速览 | Milvus 图形化管理工具 Attu、开箱即用的 Embedding 流水线 Towhee……...
  5. 《2021网络空间测绘年报》解读|应用风险分析
  6. SSM+MYSQL 中药方剂管理与查询小程序源码71796
  7. Docker 部署jenkins最新版本
  8. 总结渗透测试的信息收集之知己知彼百战不殆
  9. 【面试题】图片懒加载
  10. 记录给Lenovo T460机械硬盘升级为SSD的过程