public override void OnInspectorGUI() { RevertLodMerge _target = (RevertLodMerge)target; if (_target.original == null) { try { Undo.DestroyObjectImmediate(this); } catch { } return; } else { SerializedProperty original_s = serializedObject.FindProperty("original"); SerializedProperty texutrePath_s = serializedObject.FindProperty("texutrePath"); SerializedProperty materialPath_s = serializedObject.FindProperty("materialPath"); GUI.enabled = false; EditorGUILayout.PropertyField(original_s, new GUIContent("Original Grp Reference")); EditorGUILayout.PropertyField(texutrePath_s, new GUIContent("texutrePath Reference")); EditorGUILayout.PropertyField(materialPath_s, new GUIContent("materialPath Reference")); GUI.enabled = true; GUI.color = new Color(1, 0.3f, 0.3f); if (GUILayout.Button("Revert")) { LodMerge lodMerge = (LodMerge)EditorWindow.GetWindow(typeof(LodMerge), true); lodMerge.Revert(_target); } } }
public void Revert(RevertLodMerge _revert) { Undo.RecordObject(_revert.original, "setActive"); _revert.original.SetActive(true); Selection.activeGameObject = _revert.original; Undo.DestroyObjectImmediate(_revert.gameObject); if (_revert.texutrePath != string.Empty) { AssetDatabase.DeleteAsset(_revert.texutrePath); } if (_revert.materialPath != string.Empty) { AssetDatabase.DeleteAsset(_revert.materialPath); } for (int i = 0; i < _revert.meshPath.Count; i++) { if (_revert.meshPath[i] != string.Empty) { AssetDatabase.DeleteAsset(_revert.meshPath[i]); } } }
void OnGUI() { state = (State)EditorGUILayout.EnumPopup(state); //if (state == State.Merge) //{ EditorGUILayout.HelpBox("If using LOD 0-3 setup, name your child with the suffix: 'LOD0', 'LOD1', 'LOD2' respectfully.", MessageType.Info); GUILayout.BeginHorizontal(); sizeUnit = EditorGUILayout.IntField("sizeUnit", sizeUnit); if (GUILayout.Button("10")) { sizeUnit = 10; } if (GUILayout.Button("50")) { sizeUnit = 50; } if (GUILayout.Button("100")) { sizeUnit = 100; } if (GUILayout.Button("500")) { sizeUnit = 500; } GUILayout.EndHorizontal(); if (sizeUnit < 5) { sizeUnit = 5; } GUILayout.Label(amountX + " x " + amountY); //spacer EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); // //} if (_tr != null) { lockSelection = EditorGUILayout.Toggle("lockSelection", lockSelection); } if (_tr == null || (Selection.activeTransform == null || Selection.activeTransform.transform.childCount < 2)) { EditorGUILayout.HelpBox("Select 'Root GO' in scene to merge meshes. Requires an empty root GO container", MessageType.Info); } else { if (GUILayout.Button("Merge within: " + _tr.name)) { Undo.RecordObject(_tr, "setActive"); _tr.gameObject.SetActive(true); _tr.tag = "EditorOnly"; DoesMerge(_tr); } } if (Selection.activeTransform != null && Selection.activeTransform.GetComponent <RevertLodMerge>() != null) { RevertLodMerge _revert = Selection.activeTransform.GetComponent <RevertLodMerge>(); if (_revert.original != null) { GUI.color = new Color(1, 0.3f, 0.3f); if (GUILayout.Button("Revert")) { Revert(_revert); } } else { Undo.DestroyObjectImmediate(_revert); } } GUI.color = Color.white; //atlas ui if (state == State.AtlasPack) { //sizeUnit = 9999; //spacer EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); lodMergeSO = (LodMergeSO)EditorGUILayout.ObjectField(lodMergeSO, typeof(LodMergeSO), false); EditorGUILayout.HelpBox("Name the GameObject unique names to prevent texture overwrites!", MessageType.Info); GUILayout.BeginVertical(EditorStyles.helpBox); GUILayout.BeginHorizontal(); atlasTextureSize = EditorGUILayout.IntField("atlasTextureSize", atlasTextureSize); if (GUILayout.Button("128")) { atlasTextureSize = 128; } if (GUILayout.Button("256")) { atlasTextureSize = 256; } if (GUILayout.Button("512")) { atlasTextureSize = 512; } if (GUILayout.Button("1024")) { atlasTextureSize = 1024; } GUILayout.EndHorizontal(); GUILayout.Box(atlas, GUILayout.Width(Screen.width / 2), GUILayout.Height(Screen.height / 2), GUILayout.MaxWidth(atlasTextureSize), GUILayout.MaxHeight(atlasTextureSize)); GUILayout.EndVertical(); } }
//phase B Merge=========================================== void AtlasCombine() { //atlas setup atlasTextures.Clear(); //make all textures found readable for (int i = 0; i < gridNodes.Count; i++) { for (int ii = 0; ii < gridNodes[i].mat.Count; ii++) { Texture2D _mainTex = GetMainTexture(gridNodes[i].mat[ii].mat); //get the main texture if (_mainTex != null) { string path = AssetDatabase.GetAssetPath(_mainTex); TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(path); importer.isReadable = true; AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); atlasTextures.Add(_mainTex); } } } //make texture ------------------------------------------------------------------------------------------ Texture2D preBakeAtlas = new Texture2D(atlasTextureSize, atlasTextureSize); rects = preBakeAtlas.PackTextures(atlasTextures.ToArray(), 0, atlasTextureSize, false); //TO DO please make a list of texture name to reference back what each rect i are so I can reference to my grid support. Avoid unknow material uv set//////////////////////////////////////!!! //Encode the packed texture to PNG byte[] bytes = preBakeAtlas.EncodeToTGA(); //Save the packed texture to the datapath of your choice string SelectedName = _tr.name; string SetFolderPath = Path.GetDirectoryName(EditorSceneManager.GetActiveScene().path) + "/AtlasCombine/" + EditorSceneManager.GetActiveScene().name; var folder = Directory.CreateDirectory(SetFolderPath); string SetTexturePath = SetFolderPath + "/" + SelectedName + ".tga"; string SetMathPath = SetFolderPath + "/" + SelectedName + "_AtlasMat" + ".mat"; //texture File.WriteAllBytes(SetTexturePath, bytes); AssetDatabase.ImportAsset(SetTexturePath, ImportAssetOptions.ForceUpdate); atlas = (Texture2D)AssetDatabase.LoadAssetAtPath(SetTexturePath, typeof(Texture2D)); //mat Material atlasMat = new Material(GetShader()); atlasMat.mainTexture = atlas; AssetDatabase.CreateAsset(atlasMat, SetMathPath); AssetDatabase.ImportAsset(SetMathPath, ImportAssetOptions.ForceUpdate); //destroy prebake DestroyImmediate(preBakeAtlas); //cleanup atlas. revert all textures found to unreadable for (int i = 0; i < gridNodes.Count; i++) { for (int ii = 0; ii < gridNodes[i].mat.Count; ii++) { Texture2D _mainTex = GetMainTexture(gridNodes[i].mat[ii].mat); string path = AssetDatabase.GetAssetPath(_mainTex); TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(path); importer.isReadable = false; AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); } } //setup GameObject newRootGO; newRootGO = new GameObject("Combine_" + _tr.name); Undo.RegisterCreatedObjectUndo(newRootGO, "created GO"); Undo.RecordObject(newRootGO.transform, "Move GO"); newRootGO.transform.position = _tr.position; RevertLodMerge _revertLODMerge = newRootGO.gameObject.AddComponent <RevertLodMerge>(); _revertLODMerge.original = _tr.gameObject; _revertLODMerge.texutrePath = SetTexturePath; _revertLODMerge.materialPath = SetMathPath; //organizing if (_tr.parent != null) { newRootGO.transform.SetParent(_tr.parent); } newRootGO.transform.SetSiblingIndex(_tr.GetSiblingIndex()); //---------------------------- int ExistMatInGridCount = 0; for (int i = 0; i < gridNodes.Count; i++) { if (gridNodes[i].mat != null && gridNodes[i].mat.Count > 0) { ExistMatInGridCount += 1; } } for (int i = 0; i < gridNodes.Count; i++) { List <CombineInstance> combine = new List <CombineInstance>(); for (int ii = 0; ii < gridNodes[i].mat.Count; ii++) { //List<CombineInstance> combine = new List<CombineInstance>(); int meshR_i = 0; int TotalMeshR_Count = gridNodes[i].mat[ii].meshR.Count; int uv_x = 0; int uv_y = 0; int OptimizedRowColumn = (int)Math.Ceiling(Mathf.Sqrt(TotalMeshR_Count)); Debug.Log("OptimizedRowColumn" + OptimizedRowColumn); float perPerc = ((float)1 / (float)OptimizedRowColumn); while (meshR_i < TotalMeshR_Count) { CombineInstance _combine = new CombineInstance(); Mesh newMesh = Instantiate(gridNodes[i].mat[ii].meshR[meshR_i].sharedMesh); newMesh.name = "_processingMesh_"; _combine.mesh = newMesh; _combine.transform = gridNodes[i].mat[ii].meshR[meshR_i].transform.localToWorldMatrix; int ThisRectID = -1; for (int x = 0; x < atlasTextures.Count; x++) { if (atlasTextures[x] == gridNodes[i].mat[ii].mat.mainTexture) { ThisRectID = x; } } ///uv0 if (ThisRectID > -1) { Vector2[] lightMapUV0 = newMesh.uv; int thisUV0_i = 0; while (thisUV0_i < lightMapUV0.Length) { Debug.Log("rect + " + ThisRectID + " " + rects[ThisRectID]); lightMapUV0[thisUV0_i] = (lightMapUV0[thisUV0_i] * new Vector2(rects[ThisRectID].width, rects[ThisRectID].height)) + (new Vector2(rects[ThisRectID].x, rects[ThisRectID].y)); thisUV0_i += 1; } newMesh.SetUVs(0, lightMapUV0); } combine.Add(_combine); meshR_i += 1; } } GameObject newGO; newGO = new GameObject("_Combine_Atlas_"); if (combine.Count > 0) { //Mesh Mesh atlasMesh = new Mesh(); string SetMeshPath = SetFolderPath + "/" + SelectedName + "_AtlasMesh_" + i + ".asset"; AssetDatabase.CreateAsset(atlasMesh, SetMeshPath); AssetDatabase.ImportAsset(SetMeshPath, ImportAssetOptions.ForceUpdate); _revertLODMerge.meshPath.Add(SetMeshPath); atlasMesh.name = "_Combine_Atlas_Mesh"; MeshFilter mf = newGO.AddComponent <MeshFilter>(); atlasMesh.CombineMeshes(combine.ToArray(), true, true); atlasMesh.uv2 = new Vector2[0]; Unwrapping.GenerateSecondaryUVSet(atlasMesh); mf.sharedMesh = atlasMesh; MeshRenderer thisMr = newGO.AddComponent <MeshRenderer>(); thisMr.sharedMaterial = atlasMat; newGO.transform.SetParent(newRootGO.transform); } else { if (newGO != null) { Undo.DestroyObjectImmediate(newGO); //DestroyImmediate(newGO); } } } //------------------------- end Undo.RecordObject(_tr.gameObject, "setActive"); _tr.gameObject.SetActive(false); Selection.activeGameObject = newRootGO; }