This commit is contained in:
2025-11-14 18:44:06 +08:00
parent 10156da245
commit 22e867d077
7013 changed files with 2572882 additions and 1804 deletions

View File

@@ -0,0 +1,91 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace MeshCombineStudio
{
[CustomEditor(typeof(CombinedLODManager))]
public class CombinedLODManagerEditor : Editor
{
SerializedProperty drawGizmos, distances, lodMode, lodDistanceMode, showLod, lodCulled, lodCullDistance;
SerializedProperty[] distanceElements;
float editorSkinMulti;
private void OnEnable()
{
editorSkinMulti = EditorGUIUtility.isProSkin ? 1 : 0.35f;
drawGizmos = serializedObject.FindProperty("drawGizmos");
lodMode = serializedObject.FindProperty("lodMode");
lodDistanceMode = serializedObject.FindProperty("lodDistanceMode");
showLod = serializedObject.FindProperty("showLod");
distances = serializedObject.FindProperty("distances");
lodCulled = serializedObject.FindProperty("lodCulled");
lodCullDistance = serializedObject.FindProperty("lodCullDistance");
}
public override void OnInspectorGUI()
{
// DrawDefaultInspector();
CombinedLODManager combinedLODManager = (CombinedLODManager)target;
serializedObject.Update();
GUI.color = Color.yellow * editorSkinMulti;
EditorGUILayout.BeginVertical("Box");
GUI.color = Color.white;
GUIDraw.LabelWidthUnderline(new GUIContent("LOD Settings", ""), 14);
EditorGUILayout.PropertyField(drawGizmos);
EditorGUILayout.PropertyField(lodMode);
GUI.changed = false;
EditorGUILayout.PropertyField(lodDistanceMode);
if (GUI.changed)
{
MeshCombiner meshCombiner = combinedLODManager.GetComponent<MeshCombiner>();
if (meshCombiner != null)
{
serializedObject.ApplyModifiedProperties();
combinedLODManager.UpdateDistances(meshCombiner);
return;
}
}
EditorGUILayout.PropertyField(lodCulled);
if (lodCulled.boolValue)
{
EditorGUILayout.PropertyField(lodCullDistance);
if (lodCullDistance.floatValue < 0) lodCullDistance.floatValue = 0;
}
if (lodMode.enumValueIndex == 1)
{
EditorGUILayout.PropertyField(showLod);
if (showLod.intValue < 0) showLod.intValue = 0;
if (showLod.intValue >= distances.arraySize) showLod.intValue = distances.arraySize - 1;
}
else
{
GUI.changed = false;
GUIDraw.PropertyArray(distances, new GUIContent(""), false, false);
if (GUI.changed) lodDistanceMode.enumValueIndex = 1;
if (distanceElements == null || distanceElements.Length != distances.arraySize) distanceElements = new SerializedProperty[distances.arraySize];
for (int i = 0; i < distances.arraySize; i++)
{
distanceElements[i] = distances.GetArrayElementAtIndex(i);
if (i == 0) distanceElements[i].floatValue = 0;
else if (distanceElements[i].floatValue < distanceElements[i - 1].floatValue) distanceElements[i].floatValue = distanceElements[i - 1].floatValue + 0.1f;
}
}
EditorGUILayout.EndVertical();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7ef7cd9e299c4944eb153da2a7c31475
timeCreated: 1505285793
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,22 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace MeshCombineStudio
{
public class DetectMeshImportSettingsChange : AssetPostprocessor
{
void OnPreprocessModel()
{
// ModelImporter importer = (ModelImporter)assetImporter;
// List<MeshCombiner> instances = MeshCombiner.instances;
// Debug.Log("MeshCombiner instances " + instances.Count);
MeshCombineJobManager.ResetMeshCache();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7699aab1f48b4bf4bac9ecf5ceece31d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace MeshCombineStudio
{
static public class GUIDraw
{
static public void DrawSpacer(float spaceBegin = 5, float height = 5, float spaceEnd = 5)
{
GUILayout.Space(spaceBegin - 1);
EditorGUILayout.BeginHorizontal();
GUI.color = new Color(0.5f, 0.5f, 0.5f, 1);
GUILayout.Button("", GUILayout.Height(height));
EditorGUILayout.EndHorizontal();
GUILayout.Space(spaceEnd);
GUI.color = Color.white;
}
static public void Label(string label, int fontSize)
{
int fontSizeOld = EditorStyles.label.fontSize;
EditorStyles.boldLabel.fontSize = fontSize;
EditorGUILayout.LabelField(label, EditorStyles.boldLabel, GUILayout.Height(fontSize + 6));
EditorStyles.boldLabel.fontSize = fontSizeOld;
}
static public void LabelWidthUnderline(GUIContent guiContent, int fontSize, bool boldLabel = true)
{
int fontSizeOld = EditorStyles.label.fontSize;
EditorStyles.boldLabel.fontSize = fontSize;
EditorGUILayout.LabelField(guiContent, boldLabel ? EditorStyles.boldLabel : EditorStyles.label, GUILayout.Height(fontSize + 6));
EditorStyles.boldLabel.fontSize = fontSizeOld;
DrawUnderLine();
GUILayout.Space(5);
}
static public void DrawUnderLine(float offsetY = 0)
{
Rect rect = GUILayoutUtility.GetLastRect();
if (EditorGUIUtility.isProSkin) GUI.color = Color.grey; else GUI.color = Color.black;
GUI.DrawTexture(new Rect(rect.x, rect.yMax + offsetY, rect.width, 1), Texture2D.whiteTexture);
GUI.color = Color.white;
}
static public void PropertyArray(SerializedProperty property, GUIContent arrayName, bool drawUnderLine = true, bool editArrayLength = true)
{
EditorGUILayout.BeginHorizontal();
EditorGUI.indentLevel++;
GUILayout.Space(0);
Rect rect = GUILayoutUtility.GetLastRect();
property.isExpanded = EditorGUI.Foldout(new Rect(rect.x, rect.y + 3, 25, 18), property.isExpanded, "");
EditorGUILayout.PrefixLabel(new GUIContent(arrayName.text + " Size", arrayName.tooltip));
if (property.isExpanded)
{
if (editArrayLength)
{
EditorGUI.indentLevel -= 2;
property.arraySize = EditorGUILayout.IntField("", property.arraySize);
EditorGUI.indentLevel += 2;
}
EditorGUILayout.EndHorizontal();
EditorGUI.indentLevel++;
for (int i = 0; i < property.arraySize; i++)
{
SerializedProperty elementProperty = property.GetArrayElementAtIndex(i);
EditorGUILayout.PropertyField(elementProperty);
}
EditorGUI.indentLevel--;
}
else EditorGUILayout.EndHorizontal();
EditorGUI.indentLevel--;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: adcd9501ac7d57d48bad76228fb8ec8c
timeCreated: 1505286253
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,72 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace MeshCombineStudio
{
[CustomEditor(typeof(LODGroupSetup))]
public class LODGroupSetupEditor : Editor
{
LODGroupSetup lodGroupSetup;
LOD[] oldLods;
void OnEnable()
{
lodGroupSetup = (LODGroupSetup)target;
oldLods = lodGroupSetup.lodGroup.GetLODs();
UnityEditor.EditorApplication.update += MyUpdate;
}
void OnDisable()
{
UnityEditor.EditorApplication.update -= MyUpdate;
}
void MyUpdate()
{
lodGroupSetup.lodGroup.size = lodGroupSetup.meshCombiner.cellSize;
LOD[] lods = lodGroupSetup.lodGroup.GetLODs();
if (lods.Length != oldLods.Length)
{
Debug.LogError("Mesh Combine Studio -> Please don't change the amount of LODs, this is just a dummy LOD Group to apply settings to the LOD Groups in all children.");
lodGroupSetup.lodGroup.SetLODs(oldLods);
return;
}
bool hasChanged = false;
for (int i = 0; i < lods.Length; i++)
{
if (lods[i].renderers.Length != 0)
{
Debug.LogError("Mesh Combine Studio -> Please don't add any renderes, this is just a dummy LOD Group to apply settings to the LOD Groups in all children.");
lods[i].renderers = null;
lodGroupSetup.lodGroup.SetLODs(lods);
return;
}
if (lods[i].screenRelativeTransitionHeight != oldLods[i].screenRelativeTransitionHeight) { hasChanged = true; break; }
}
if (hasChanged)
{
lodGroupSetup.ApplySetup();
oldLods = lods;
}
}
public override void OnInspectorGUI()
{
GUIDraw.DrawSpacer();
GUI.color = Color.red;
EditorGUILayout.BeginVertical("Box");
GUI.color = Color.white;
GUIDraw.Label("Modifications to this LOD Group will apply to all children", 12);
EditorGUILayout.EndVertical();
GUIDraw.DrawSpacer();
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 3ef171e414f62184eba74f7056cb8999
timeCreated: 1510472214
licenseType: Store
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace MeshCombineStudio
{
[CustomEditor(typeof(MeshCombineJobManager))]
public class MeshCombineJobManagerEditor : Editor
{
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: a1741cca49091f8468bea22cf3e838a4
timeCreated: 1509644157
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 43b032503a6ec4e43a5ead762b8ff8b6
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,167 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.IO;
using System.Text;
namespace MeshCombineStudio
{
public class ObjExporterScript
{
private static int StartIndex = 0;
public static void Start()
{
StartIndex = 0;
}
public static void End()
{
StartIndex = 0;
}
public static string MeshToString(MeshRenderer mr, MeshFilter mf, Transform t)
{
// Vector3 s = t.localScale;
// Vector3 p = t.localPosition;
Quaternion r = t.localRotation;
int numVertices = 0;
Mesh m = mf.sharedMesh;
if (m == null) return "####Error####";
Material[] mats = mr.sharedMaterials;
StringBuilder sb = new StringBuilder();
foreach (Vector3 vv in m.vertices)
{
Vector3 v = t.TransformPoint(vv);
numVertices++;
sb.Append(string.Format("v {0} {1} {2}\n", v.x, v.y, -v.z));
}
sb.Append("\n");
foreach (Vector3 nn in m.normals)
{
Vector3 v = r * nn;
sb.Append(string.Format("vn {0} {1} {2}\n", -v.x, -v.y, v.z));
}
sb.Append("\n");
foreach (Vector3 v in m.uv)
{
sb.Append(string.Format("vt {0} {1}\n", v.x, v.y));
}
for (int material = 0; material < m.subMeshCount; material++)
{
sb.Append("\n");
sb.Append("usemtl ").Append(mats[material].name).Append("\n");
sb.Append("usemap ").Append(mats[material].name).Append("\n");
int[] triangles = m.GetTriangles(material);
for (int i = 0; i < triangles.Length; i += 3)
{
sb.Append(string.Format("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}\n",
triangles[i] + 1 + StartIndex, triangles[i + 1] + 1 + StartIndex, triangles[i + 2] + 1 + StartIndex));
}
}
StartIndex += numVertices;
return sb.ToString();
}
}
public class ObjExporter : ScriptableObject
{
[MenuItem("GameObject/Export/Wavefront OBJ")]
static void DoExportWSubmeshes()
{
DoExport(true);
}
[MenuItem("GameObject/Export/Wavefront OBJ (No Submeshes)")]
static void DoExportWOSubmeshes()
{
DoExport(false);
}
static void DoExport(bool makeSubmeshes)
{
if (Selection.gameObjects.Length == 0)
{
Debug.Log("Didn't Export Any Meshes; Nothing was selected!");
return;
}
string meshName = Selection.gameObjects[0].name;
string fileName = EditorUtility.SaveFilePanel("Export .obj file", "", meshName, "obj");
ObjExporterScript.Start();
StringBuilder meshString = new StringBuilder();
meshString.Append("#" + meshName + ".obj"
+ "\n#" + System.DateTime.Now.ToLongDateString()
+ "\n#" + System.DateTime.Now.ToLongTimeString()
+ "\n#-------"
+ "\n\n");
Transform t = Selection.gameObjects[0].transform;
Vector3 originalPosition = t.position;
t.position = Vector3.zero;
if (!makeSubmeshes)
{
meshString.Append("g ").Append(t.name).Append("\n");
}
meshString.Append(processTransform(t, makeSubmeshes));
WriteToFile(meshString.ToString(), fileName);
t.position = originalPosition;
ObjExporterScript.End();
Debug.Log("Exported Mesh: " + fileName);
}
static string processTransform(Transform t, bool makeSubmeshes)
{
StringBuilder meshString = new StringBuilder();
meshString.Append("#" + t.name
+ "\n#-------"
+ "\n");
if (makeSubmeshes)
{
meshString.Append("g ").Append(t.name).Append("\n");
}
MeshFilter mf = t.GetComponent<MeshFilter>();
if (mf)
{
MeshRenderer mr = t.GetComponent<MeshRenderer>();
if (mr != null)
{
meshString.Append(ObjExporterScript.MeshToString(mr, mf, t));
}
}
for (int i = 0; i < t.childCount; i++)
{
meshString.Append(processTransform(t.GetChild(i), makeSubmeshes));
}
return meshString.ToString();
}
static void WriteToFile(string s, string filename)
{
using (StreamWriter sw = new StreamWriter(filename))
{
sw.Write(s);
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9a501084de9636c4b98254524aa63fc2
timeCreated: 1504780640
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
namespace MeshCombineStudio
{
[CustomEditor (typeof(ReadMe))]
public class ReadMeEditor : Editor
{
public override void OnInspectorGUI()
{
ReadMe r = (ReadMe)target;
Event eventCurrent = Event.current;
GUI.changed = false;
if (eventCurrent.control && eventCurrent.shift && eventCurrent.keyCode == KeyCode.E && eventCurrent.type == EventType.KeyDown)
{
r.buttonEdit = !r.buttonEdit;
GUI.changed = true;
}
GUILayout.Space(5);
if (r.buttonEdit)
{
EditorGUILayout.LabelField("EDIT MODE");
r.readme = EditorGUILayout.TextArea(r.readme);
}
else
{
EditorGUILayout.TextArea(r.readme);
}
if (GUI.changed) EditorUtility.SetDirty(target);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 695a9de9c2be7154b8c6d6ea5065d7be
timeCreated: 1511099118
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: