9

Unity3D研究院之给UI添加Mesh形状(一百二十)

 3 years ago
source link: https://www.xuanyusong.com/archives/4763
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Unity3D研究院之给UI添加Mesh形状(一百二十)

美术希望在3D UI中显示自定义的网格,比如显示一个带弧形的UI。纯3D确实是可以做的,但是涉及到UI事件或者裁切就无法统一。

由于默认的UI是矩形,UI的显示与相应区域就是RectTransform的size,如果我们使用自定义Mesh的UI那么显示区域就要单独调整,比如单独设置显示的旋转、缩放、平移。

如下图所示,显示区域和响应区域是不一样的。

Unity3D研究院之给UI添加Mesh形状(一百二十) - 雨松MOMO程序研究院 - 1

如下图所示,MeshImage就是我封装的UI组件,这时候调整overridePostion、 overrideRotation 、overrideScale 来修改3D模型的显示区域。

Unity3D研究院之给UI添加Mesh形状(一百二十) - 雨松MOMO程序研究院 - 2

而修改RectTransform则修改它的整体响应区域。

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摄像机整体的透视关系就都出来了。

Unity3D研究院之给UI添加Mesh形状(一百二十) - 雨松MOMO程序研究院 - 3

还有一点默认UI的shader是不写深度的,如果模型有厚度就要写深度了,自己改下shader就行。

Unity3D研究院之给UI添加Mesh形状(一百二十) - 雨松MOMO程序研究院 - 4

最后欢迎大家一起讨论。

作者:雨松MOMO
专注移动互联网,Unity3D游戏开发

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK