열차 목업의 내부 확인용 프로젝트
smchoi
2024-06-14 23cbbc76b6204691dd06f93f2108993f9ca79020
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/****************************************
    Simple Mesh Combine
    Copyright Unluck Software    
     www.chemicalbliss.com                                                                                                                                                                                     
*****************************************/
//Add script to the parent gameObject, then click combine
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
[AddComponentMenu("Simple Mesh Combine")]
 
public class SimpleMeshCombine : MonoBehaviour
{
    public GameObject[] combinedGameOjects;     //Stores gameObjects that has been merged, mesh renderer disabled
    public GameObject combined;                 //Stores the combined mesh gameObject
    public string meshName = "Combined_Meshes"; //Asset name when saving as prefab
    public bool _canGenerateLightmapUV;
    public int vCount;
    public bool generateLightmapUV;
    public float lightmapScale = 1f;
 
    public GameObject copyTarget;
    public bool destroyOldColliders;
    public bool keepStructure = true;
 
    public Mesh autoOverwrite;
 
    public bool setStatic = true;
 
    public bool increaseVertexCount;
 
    public bool setMeshPivottoParentPivot;
 
    public void EnableRenderers(bool e) {
        for (int i = 0; i < combinedGameOjects.Length; i++) {
            if (combinedGameOjects[i] == null) break;
            Renderer renderer = combinedGameOjects[i].GetComponent<Renderer>();
            if (renderer != null) renderer.enabled = e;
        }
    }
    //Returns a meshFilter[] list of all renderer enabled meshfilters(so that it does not merge disabled meshes, useful when there are invisible box colliders)
    public MeshFilter[] FindEnabledMeshes() {
        MeshFilter[] renderers = null;
        int count = 0;
        renderers = transform.GetComponentsInChildren<MeshFilter>();
        //count all the enabled meshrenderers in children        
        for (int i = 0; i < renderers.Length; i++) {
            if ((renderers[i].GetComponent<MeshRenderer>() != null) && renderers[i].GetComponent<MeshRenderer>().enabled)
                count++;
        }
        MeshFilter[] meshfilters = new MeshFilter[count];//creates a new array with the correct length
        count = 0;
        //adds all enabled meshes to the array
        for (int ii = 0; ii < renderers.Length; ii++) {
            if ((renderers[ii].GetComponent<MeshRenderer>() != null) && renderers[ii].GetComponent<MeshRenderer>().enabled) {
                meshfilters[count] = renderers[ii];
                count++;
            }
        }
        return meshfilters;
    }
 
    public void ReleaseMeshes() {
        EnableRenderers(true);
        if (combined != null) Destroy(combined);
        combinedGameOjects = null;
        vCount = 0;
    }
 
    public void CombineMeshes() {
        Vector3 savePos = transform.position;
        if (setMeshPivottoParentPivot)
        {
            transform.position = Vector3.zero;
        }
 
        GameObject combo = new GameObject();
        combo.name = "_Combined Mesh [" + name + "]";
        combo.gameObject.AddComponent<MeshFilter>();
        combo.gameObject.AddComponent<MeshRenderer>();
        MeshFilter[] meshFilters = null;
        meshFilters = FindEnabledMeshes();
        ArrayList materials = new ArrayList();
        ArrayList combineInstanceArrays = new ArrayList();
        combinedGameOjects = new GameObject[meshFilters.Length];
        for (int i = 0; i < meshFilters.Length; i++) {
            combinedGameOjects[i] = meshFilters[i].gameObject;
            MeshRenderer meshRenderer = meshFilters[i].GetComponent<MeshRenderer>();
            meshFilters[i].transform.gameObject.GetComponent<Renderer>().enabled = false;
            if (meshFilters[i].sharedMesh == null) {
#if UNITY_EDITOR
                Debug.LogWarning("SimpleMeshCombine : " + meshFilters[i].gameObject + " [Mesh Filter] has no [Mesh], mesh will not be included in combine..");
#endif
                break;
            }
            for (int o = 0; o < meshFilters[i].sharedMesh.subMeshCount; o++) {
                if (meshRenderer == null) {
#if UNITY_EDITOR
                    Debug.LogWarning("SimpleMeshCombine : " + meshFilters[i].gameObject + "has a [Mesh Filter] but no [Mesh Renderer], mesh will not be included in combine.");
#endif
                    break;
                }
                if (o < meshRenderer.sharedMaterials.Length && o < meshFilters[i].sharedMesh.subMeshCount) {
                    int materialArrayIndex = Contains(materials, meshRenderer.sharedMaterials[o]);
                    if (materialArrayIndex == -1) {
                        materials.Add(meshRenderer.sharedMaterials[o]);
                        materialArrayIndex = materials.Count - 1;
                    }
                    combineInstanceArrays.Add(new ArrayList());
                    CombineInstance combineInstance = new CombineInstance();
                    combineInstance.transform = meshRenderer.transform.localToWorldMatrix;
                    //Fix for Unity 2017 Bug
#if UNITY_2017
                    if (meshFilters[i].sharedMesh.subMeshCount > 1) combineInstance.mesh = SubMeshFix.GetSubmesh(meshFilters[i].sharedMesh,o);
                    else {
                        combineInstance.mesh = meshFilters[i].sharedMesh;
                    }
#else
                    combineInstance.mesh = meshFilters[i].sharedMesh;
                    combineInstance.subMeshIndex = o;
#endif
                    (combineInstanceArrays[materialArrayIndex] as ArrayList).Add(combineInstance);
                }
 
 
#if UNITY_EDITOR
                else {
                    Debug.LogWarning("Simple Mesh Combine: GameObject [ " + meshRenderer.gameObject.name + " ] is missing a material (Mesh or sub-mesh ignored from combine)");
                }
#endif
            }
#if UNITY_EDITOR
            EditorUtility.DisplayProgressBar("Combining", "", (float)i);
#endif
        }
 
        Mesh[] meshes = new Mesh[materials.Count];
        CombineInstance[] combineInstances = new CombineInstance[materials.Count];
        for (int m = 0; m < materials.Count; m++) {
            CombineInstance[] combineInstanceArray = (combineInstanceArrays[m] as ArrayList).ToArray(typeof(CombineInstance)) as CombineInstance[];
            meshes[m] = new Mesh();
#if UNITY_2017_4 || UNITY_2017_5 || UNITY_2017_6 || UNITY_2017_7 || UNITY_2017_8 || UNITY_2017_9 || UNITY_2018 || UNITY_2019 || UNITY_2020 || UNITY_2021 || UNITY_2022 || UNITY_2023 || UNITY_2024 || UNITY_2025 || UNITY_2026 || UNITY_2027 || UNITY_2028 || UNITY_2029 || UNITY_2030
            if (increaseVertexCount) {
                meshes[m].indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
            }
#endif
            meshes[m].CombineMeshes(combineInstanceArray, true, true);
            combineInstances[m] = new CombineInstance();
            combineInstances[m].mesh = meshes[m];
            combineInstances[m].subMeshIndex = 0;
        }
        Mesh ms = combo.GetComponent<MeshFilter>().sharedMesh = new Mesh();
#if UNITY_2017_4 || UNITY_2017_5 || UNITY_2017_6 || UNITY_2017_7 || UNITY_2017_8 || UNITY_2017_9 || UNITY_2018 || UNITY_2019 || UNITY_2020 || UNITY_2021 || UNITY_2022 || UNITY_2023 || UNITY_2024 || UNITY_2025 || UNITY_2026 || UNITY_2027 || UNITY_2028 || UNITY_2029 || UNITY_2030
        if (increaseVertexCount) {
            ms.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
        //        Debug.Log("32Bit mesh");
        }
 
#endif
        ms.Clear();
        ms.CombineMeshes(combineInstances, false, false);
        combo.GetComponent<MeshFilter>().sharedMesh = ms;
 
        foreach (Mesh mesh in meshes) {
            mesh.Clear();
            DestroyImmediate(mesh);
        }
        MeshRenderer meshRendererCombine = combo.GetComponent<MeshFilter>().GetComponent<MeshRenderer>();
        if (meshRendererCombine == null) meshRendererCombine = gameObject.AddComponent<MeshRenderer>();
        Material[] materialsArray = materials.ToArray(typeof(Material)) as Material[];
        meshRendererCombine.materials = materialsArray;
        combined = combo.gameObject;
        EnableRenderers(false);
        combo.transform.parent = transform;
#if UNITY_EDITOR
        if (generateLightmapUV) {
            Unwrapping.GenerateSecondaryUVSet(combo.GetComponent<MeshFilter>().sharedMesh);
            SerializedObject so = new SerializedObject (combo.GetComponent<MeshRenderer>());
            so.FindProperty("m_ScaleInLightmap").floatValue = lightmapScale;
            so.ApplyModifiedProperties();
        }
#endif
        combo.GetComponent<MeshFilter>().sharedMesh.RecalculateBounds();
        vCount = combo.GetComponent<MeshFilter>().sharedMesh.vertexCount;
        //if (vCount > 65536) {
        //    //Debug.LogWarning("Vertex Count: " + vCount + "- Vertex Count too high, please divide mesh combine into more groups. Max 65536 for each mesh");
        //    _canGenerateLightmapUV = false;
        //} else {
        //    _canGenerateLightmapUV = true;
        //}
        if (setStatic) combined.isStatic = true;
 
#if UNITY_EDITOR
        EditorUtility.ClearProgressBar();
#endif
        if (setMeshPivottoParentPivot)
        {
            transform.position = savePos;
        }
 
    }
 
    public int Contains(ArrayList l, Material n) {
        for (int i = 0; i < l.Count; i++) {
            if ((l[i] as Material) == n) {
                return i;
            }
        }
        return -1;
    }
}