美术希望在3D UI中显示自定义的网格,比如显示一个带弧形的UI。纯3D确实是可以做的,但是涉及到UI事件或者裁切就无法统一。
由于默认的UI是矩形,UI的显示与相应区域就是RectTransform的size,如果我们使用自定义Mesh的UI那么显示区域就要单独调整,比如单独设置显示的旋转、缩放、平移。
如下图所示,显示区域和响应区域是不一样的。
如下图所示,MeshImage就是我封装的UI组件,这时候调整overridePostion、 overrideRotation 、overrideScale 来修改3D模型的显示区域。
而修改RectTransform则修改它的整体响应区域。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
using UnityEngine; using UnityEngine.UI; [RequireComponent(typeof(CanvasRenderer))] public class MeshImage : MaskableGraphic { public Vector3 overridePostion; public Vector3 overrideRotation; public Vector3 overrideScale = new Vector3(100f, 100f, 100f); public Texture texture; public Mesh mesh; public override Texture mainTexture { get { return texture; } } protected override void OnPopulateMesh(VertexHelper vh) { if (mesh != null) { vh.Clear(); //提取Mesh信息 int[] triangles = mesh.triangles; Vector3[] vertices = mesh.vertices; Vector3[] normals = mesh.normals; Vector2[] UVs = mesh.uv; //处理缩放矩阵 Matrix4x4 matrix4X4 = Matrix4x4.identity; matrix4X4.m00 = overrideScale.x; matrix4X4.m11 = overrideScale.y; matrix4X4.m22 = overrideScale.z; for (int i = 0; i < vertices.Length; i++) { //组合UI顶点信息 UIVertex temp = new UIVertex(); temp.position = matrix4X4.MultiplyPoint3x4((Quaternion.Euler(overrideRotation) * vertices[i]) + overridePostion); temp.uv0 = UVs[i]; temp.normal = normals[i]; temp.color = (Color32)color; vh.AddVert(temp); } //设置三角形索引 for (int i = 0; i < triangles.Length; i += 3) { vh.AddTriangle(triangles[i], triangles[i + 1], triangles[i + 2]); } } } //只有编辑器才会执行 //修改面板属性重新刷新 protected override void OnValidate() { base.OnValidate(); SetMaterialDirty(); SetVerticesDirty(); } } |
原理就是将Mesh的顶点信息取出来,并且组合到UI顶点中,配合3D摄像机整体的透视关系就都出来了。
还有一点默认UI的shader是不写深度的,如果模型有厚度就要写深度了,自己改下shader就行。
最后欢迎大家一起讨论。
- 本文固定链接: https://www.xuanyusong.com/archives/4763
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!
博主,能问一下,我导入的模型然后创建人物,为什么可以穿透墙体,加钢体和碰撞监测器什么的都没有用,有什么解决方法吗
你的墙体没有加Collider