美术希望在3D UI中显示自定义的网格,比如显示一个带弧形的UI。纯3D确实是可以做的,但是涉及到UI事件或者裁切就无法统一。
由于默认的UI是矩形,UI的显示与相应区域就是RectTransform的size,如果我们使用自定义Mesh的UI那么显示区域就要单独调整,比如单独设置显示的旋转、缩放、平移。
如下图所示,显示区域和响应区域是不一样的。
如下图所示,MeshImage就是我封装的UI组件,这时候调整overridePostion、 overrideRotation 、overrideScale 来修改3D模型的显示区域。
而修改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摄像机整体的透视关系就都出来了。
还有一点默认UI的shader是不写深度的,如果模型有厚度就要写深度了,自己改下shader就行。
最后欢迎大家一起讨论。
- 本文固定链接: https://www.xuanyusong.com/archives/4763
- 转载请注明: 雨松MOMO于 雨松MOMO程序研究院 发表
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!





博主,能问一下,我导入的模型然后创建人物,为什么可以穿透墙体,加钢体和碰撞监测器什么的都没有用,有什么解决方法吗
你的墙体没有加Collider