天天看點

真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
           

謝謝閱讀

繼續閱讀