應對UV問題——Unity中自動展UV小工具

Unity中自動展UV小工具

有時候別人給的unity工程中,有些模型是生成的或者是導入時沒有展好uv的,非常頭疼,又懶得導出到DCC工具去整理uv,所以做了一個簡單的展uv的小工具。效果如下:
展uv效果
這裏我做了三種展uv的方式:
**1.平面式。**可以選擇X\Y\Z平面去進行uv映射,比較適合一些簡單的幾何體例如牆、地板或者玻璃什麼的。
**2.立方體式。**這種比較適合一些比較硬表面的物體,例如桌子、欄杆什麼的。這種方式基於Object Space的法線信息去判斷該點應該屬於哪一個uv平面,所以在面臨比較大的曲面會有一些問題,而且我沒有做平鋪,所以會有一些uv重疊。
**3.使用Lightmap uv。**這一點是我受到紅強的啓發,我想既然unity可以自動幫我們整理出第二套用於光照貼圖的uv,爲什麼不用呢,所以我就取出光照貼圖的uv,去賦予mesh的第一套uv。這個方案的好處是簡單省事,而且基本沒有uv重疊,適用於所有模型。唯一需要注意的一點是需要在fbx 導入的時候勾選“Generate Lightmap uv”。

最後是代碼部分,記得把它放在Assets目錄下的Editor文件夾裏,規範操作。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class unfold : EditorWindow
{

    [MenuItem("Gq_Tools/Unfold")]
    public static void ShowWin()
    {
        EditorWindow.CreateInstance<unfold>().Show();
    }
    private void OnGUI()
    {
        GUILayout.Space(10);
        GUILayout.BeginHorizontal("box");
        GUILayout.Space(10);
        if (GUILayout.Button("Planar-X unfold"))//UI上畫一個按鈕
        {
            //MonoBehaviour.print("do");
            Unfold0("X");
        }
        if (GUILayout.Button("Planar-Y unfold"))//UI上畫一個按鈕
        {
            //MonoBehaviour.print("do");
            Unfold0("Y");
        }
        if (GUILayout.Button("Planar-Z unfold"))//UI上畫一個按鈕
        {
            //MonoBehaviour.print("do");
            Unfold0("Z");
        }
        GUILayout.EndHorizontal();
        GUILayout.Space(10);
        GUILayout.BeginHorizontal("box");
        if (GUILayout.Button("Cubic unfold"))//UI上畫一個按鈕
        {
            //MonoBehaviour.print("do");
            Unfold1();
        }
        GUILayout.EndHorizontal();
        GUILayout.Space(10);
        GUILayout.BeginHorizontal("box");
        if (GUILayout.Button("unfold by lightmap UV"))//UI上畫一個按鈕
        {
            //MonoBehaviour.print("do");
            Unfold2();
        }
        GUILayout.EndHorizontal();
    }
    //Planar Unfold
    void Unfold0(string inStr)
    {
        var objs = Selection.objects;
        if (inStr == "X")
        {
            foreach (var obj in objs)//for每個選中的物體
            {
                var go = obj as GameObject;
                Mesh mesh = go.GetComponent<MeshFilter>().sharedMesh;
                Vector3[] vertices = mesh.vertices;
                Vector2[] uvs = new Vector2[vertices.Length];

                //Planar Unfold
                for (int i = 0; i < uvs.Length; i++)
                {
                    uvs[i] = new Vector2( vertices[i].y, vertices[i].z);
                }
                mesh.uv = uvs;
            }
        }
        if (inStr == "Y")
        {
            foreach (var obj in objs)//for每個選中的物體
            {
                var go = obj as GameObject;
                Mesh mesh = go.GetComponent<MeshFilter>().sharedMesh;
                Vector3[] vertices = mesh.vertices;
                Vector2[] uvs = new Vector2[vertices.Length];

                //Planar Unfold
                for (int i = 0; i < uvs.Length; i++)
                {
                    uvs[i] = new Vector2(vertices[i].x,vertices[i].z);
                }
                mesh.uv = uvs;
            }
        }
        if (inStr == "Z")
        {
            foreach (var obj in objs)//for每個選中的物體
            {
                var go = obj as GameObject;
                Mesh mesh = go.GetComponent<MeshFilter>().sharedMesh;
                Vector3[] vertices = mesh.vertices;
                Vector2[] uvs = new Vector2[vertices.Length];

                //Planar Unfold
                for (int i = 0; i < uvs.Length; i++)
                {
                    uvs[i] = new Vector2(vertices[i].x, vertices[i].y);
                }
                mesh.uv = uvs;
            }
        }
    }
    //Cubic Unfold
    void Unfold1()
    {
        var objs = Selection.objects;
        foreach (var obj in objs)//for每個選中的物體
        {
            var go = obj as GameObject;
            Mesh mesh = go.GetComponent<MeshFilter>().sharedMesh;
            Vector3[] vertices = mesh.vertices;
            Vector2[] uvs = new Vector2[vertices.Length];
            Vector3[] normals = mesh.normals;

            //Cubic Unfold
            for (int i = 0; i < normals.Length; i++)
            {
                //X-Plane
                if (Mathf.Abs(normals[i].x) > Mathf.Abs(normals[i].y) && Mathf.Abs(normals[i].x) > Mathf.Abs(normals[i].z))
                {
                    uvs[i] = new Vector2(vertices[i].y, vertices[i].z);
                }
                //Y-Plane
                if (Mathf.Abs(normals[i].y) > Mathf.Abs(normals[i].x) && Mathf.Abs(normals[i].y) > Mathf.Abs(normals[i].z))
                {
                    uvs[i] = new Vector2(vertices[i].x, vertices[i].z);
                }
                //Z-Plane
                if (Mathf.Abs(normals[i].z) > Mathf.Abs(normals[i].x) && Mathf.Abs(normals[i].z) > Mathf.Abs(normals[i].y))
                {
                    uvs[i] = new Vector2(vertices[i].x, vertices[i].y);
                }
            }
            mesh.uv = uvs;
        }
    }
    //use lightmap UV
    void Unfold2()
    {
        var objs = Selection.objects;
        foreach (var obj in objs)//對於每個選中的物體
        {
            var go = obj as GameObject;
            Mesh mesh = go.GetComponent<MeshFilter>().sharedMesh;
            mesh.uv = mesh.uv2;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章