天天看点

真Unity3d_分享一个自定义 Mesh 绘制自绘制实例顶点优化三角面“优化”UV优化最后,完整代码:

自绘制实例

真Unity3d_分享一个自定义 Mesh 绘制自绘制实例顶点优化三角面“优化”UV优化最后,完整代码:

好处就是通过拖动,能实时看到模型变化,并且是实例化(可保存)

整个结构是好的,构思也是好的,实现也实现了

网上例子还不少,就几个三角面,乍看好像也没啥作用,工作中也不会用到,面试官也不会问到

但这时创造自己3D引擎的第一步

掌握了这个例子,就懂的了如何创建三角面,顶点和UV

下面图,有错,请辩证查看和理解

完整“优化”代码会贴在最后

真Unity3d_分享一个自定义 Mesh 绘制自绘制实例顶点优化三角面“优化”UV优化最后,完整代码:

顶点优化

其实发现网上有2~3个博客是抄这个代码的,原来的代码反而找不到了,

//一个小学生写的。。。。。。MD(这方法会把自己的节点也算进去,会多了1+)。。。。。。。。。
        //var ts = this.GetComponentsInChildren<Transform>();
        //估计他自己也是抄网上, 然后实现不下去了
        //(现在已经纠正)
           

改成:

var ts_len = transform.childCount;
           

未优化前的代码有个谬误就是坑了我很久,怎么3个子节点会有4个顶点???

三角面“优化”

解决了上面的谬误了,我们继续

//var tris = new int[] { 0, 1, 2, 0, 1, 3, 1, 2, 3 };
           

改成

var tris = new int[] { 0, 1, 2, 0, 2, 3 };
           

这里有2个原则需要知道:(我也是搞这个例子才懂的)

1.三角面按顺时针绘制,相对的,逆时针绘制的是背面

2.顶点数和UV数1:1对应,但是三角面不是,如何确定一个模型外皮三角面??美术每天都干这个,不了解原理也无所谓

3.不确定美术是不是很了解,但是程序是真的不了解

举个栗子

如果 trangles = 0,1,2

真Unity3d_分享一个自定义 Mesh 绘制自绘制实例顶点优化三角面“优化”UV优化最后,完整代码:

如果三角面 trangles = 0,2,3 则透明,需要镜头转到背面才能看到

真Unity3d_分享一个自定义 Mesh 绘制自绘制实例顶点优化三角面“优化”UV优化最后,完整代码:

回到上面的代码:

//var tris = new int[] { 0, 1, 2, 0, 1, 3, 1, 2, 3 };        
        var tris = new int[] { 0, 1, 2, 0, 2, 3 };
           

第一句,无论镜头从哪个角度看,基本上不可能同时看到3个面(有点不合常人逻辑),对理解有3D世界有帮助,但入门困难

真Unity3d_分享一个自定义 Mesh 绘制自绘制实例顶点优化三角面“优化”UV优化最后,完整代码:
真Unity3d_分享一个自定义 Mesh 绘制自绘制实例顶点优化三角面“优化”UV优化最后,完整代码:

第二句,简单的隆起的小山丘,解决

真Unity3d_分享一个自定义 Mesh 绘制自绘制实例顶点优化三角面“优化”UV优化最后,完整代码:

UV优化

最后我们再加上贴图

好像5,6年前,UNITY就推荐用sharedMesh, sharedMaterial

不要问为什么。。。。。

MeshFilter filter = this.GetComponent<MeshFilter>();
        MeshRenderer render = this.GetComponent<MeshRenderer>();
        var mesh = filter.sharedMesh;
           

最后,完整代码:

/* 自定义Mesh绘制
 * 
 * - 已添加贴图
 * 
 * created by Sidney Lu———————2020:
 * CSDN:
 * https://blog.csdn.net/avi9111/article/details/105747834
 * GITEE:
 * https://gitee.com/avi9111/UnityUtils
 * 
 * 开发中:
 * uv自动展开
 * 贴图列子
 * 模型列表
 * 自定义顶点数
 * 保存模型
 * 
 */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
public class GenMeshByGameObject : MonoBehaviour
{
    public Material mat;
    private int genCount = 4;
    private void Awake()
    {
        FullFill(genCount);
    }
    private void OnEnable()
    {
        GetComponent<MeshRenderer>().sharedMaterial = mat;
    }
    public void FullFill() {
        FullFill(genCount);
    }
    public void FullFill(int totalCount)
    {
        int count = totalCount - transform.childCount;
        for (int i = 0; i < count; i++)
        {
            GameObject gen = new GameObject();
            gen.name = "mesh" + (transform.childCount + 1);
            gen.transform.SetParent(transform, false);
        }
        
    }
    void OnDrawGizmos()
    {
        MeshFilter filter = this.GetComponent<MeshFilter>();
        MeshRenderer render = this.GetComponent<MeshRenderer>();
        var mesh = filter.sharedMesh;

        //一个小学生写的。。。。。。MD(这方法会把自己的节点也算进去,会多了1+)。。。。。。。。。
        //var ts = this.GetComponentsInChildren<Transform>();
        //估计他自己也是抄网上, 然后实现不下去了
        //(现在已经纠正)
        var ts_len = transform.childCount;
        Vector3[] vers = new Vector3[ts_len];

        for (int i = 0; i < ts_len; i++)
        {
            vers[i] = transform.GetChild(i).position;
        }

        //var tris = new int[] { 0, 1, 2, 0, 1, 3, 1, 2, 3 };
        var tris = new int[] { 0, 1, 2, 0, 2, 3 };
        //一个小学生还害我写一大堆,下面这段代码是错误的
        //uv(顶点到贴图的映射)数量 == vertex(顶点)数量,
        //所以这两兄弟必然需要是相等
        //下下的代码才是正确,而且是最简单的
        //var uvs = new Vector2[6];
        //uvs[0] = new Vector2(0, 0);
        //uvs[1] = new Vector2(1, 0);
        //uvs[2] = new Vector2(1, 1);
        //uvs[3] = new Vector2(0, 0);
        //uvs[4] = new Vector2(1, 1);
        //uvs[5] = new Vector2(0, 1);
        var uvs = new Vector2[] {
        new Vector2(0,0)
        ,new Vector2(1,1)
        ,new Vector2(0,1)
        ,new Vector2(1,0)};
 
        //   mesh.Clear();
        mesh.vertices = vers;
        mesh.triangles = tris;
        mesh.uv = uvs;
        mesh.RecalculateNormals();
        mesh.RecalculateBounds();

       

        //MeshCollider的作用是????
        //this.GetComponent<MeshCollider>().sharedMesh = mesh;
        // var uvs = new[] { };
        filter.sharedMesh = mesh;



    }
}


#if UNITY_EDITOR
[CustomEditor(typeof(GenMeshByGameObject))]
public class GenMeshByGameObjectInspector : Editor
{
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        if (GUILayout.Button("Gen"))
        {
            GenMeshByGameObject _t = target as GenMeshByGameObject;
            _t.FullFill();

        }
    }
}
#endif
           

谢谢阅读

继续阅读