/// Writes out the current scene's Sector/Portal graph as a .dot file /// which can be visualized in programs like GraphVis and the like. public static void WriteGraphDot() { if (!string.IsNullOrEmpty(EditorApplication.currentScene)) { string sceneDir; string sceneName; SECTR_Asset.GetCurrentSceneParts(out sceneDir, out sceneName); sceneName = sceneName.Replace(".unity", ""); string graphFile = SECTR_Graph.GetGraphAsDot(sceneName); string path = sceneDir + sceneName + "_SECTR_Graph.dot"; File.WriteAllText(SECTR_Asset.UnityToOSPath(path), graphFile); AssetDatabase.Refresh(); Selection.activeObject = AssetDatabase.LoadMainAssetAtPath(path); EditorUtility.FocusProjectWindow(); } }
/// Reverts all imported Sectors into the scene. Safe to call from the command line. public static void RevertSceneChunks() { int numSectors = SECTR_Sector.All.Count; for (int sectorIndex = 0; sectorIndex < numSectors; ++sectorIndex) { SECTR_Sector sector = SECTR_Sector.All[sectorIndex]; SECTR_Chunk chunk = sector.GetComponent <SECTR_Chunk>(); if (!sector.Frozen && chunk && System.IO.File.Exists(SECTR_Asset.UnityToOSPath(chunk.NodeName))) { EditorUtility.DisplayProgressBar("Reverting Scene Chunks", "Reverting " + sector.name, (float)sectorIndex / (float)numSectors); DeleteExportedSector(sector); } } if (SECTR_VC.CheckOut(EditorApplication.currentScene)) { EditorApplication.SaveScene(); SECTR_VC.WaitForVC(); } EditorUtility.ClearProgressBar(); }
public override void OnInspectorGUI() { SECTR_Chunk myChunk = (SECTR_Chunk)target; SECTR_Sector mySector = myChunk.GetComponent <SECTR_Sector>(); EditorGUILayout.BeginHorizontal(); bool editMode = !EditorApplication.isPlaying && !EditorApplication.isPaused; bool alreadyExported = myChunk && System.IO.File.Exists(SECTR_Asset.UnityToOSPath(myChunk.NodeName)); GUI.enabled = editMode; if (mySector.Frozen) { // Import if (alreadyExported && GUILayout.Button(new GUIContent("Import", "Imports this Sector into the scene."))) { modiferMode = ModifierMode.Import; } // Export GUI.enabled = false; GUILayout.Button(new GUIContent("Export", "Exports this Sector into a Chunk scene.")); GUI.enabled = editMode; } else { // Revert if (alreadyExported && GUILayout.Button(new GUIContent("Revert", "Discards changes to this Sector."))) { modiferMode = ModifierMode.Revert; } // Export if (GUILayout.Button(new GUIContent("Export", "Exports this Sector into a Chunk scene."))) { modiferMode = ModifierMode.Export; } } EditorGUILayout.EndHorizontal(); base.OnInspectorGUI(); if (!mySector.Frozen) { proxyFoldout = EditorGUILayout.Foldout(proxyFoldout, "Proxy Mesh Tool"); if (proxyFoldout) { EditorGUILayout.BeginVertical(); _BuildChildControls(myChunk.transform, true); if (GUILayout.Button("Create Proxy Mesh")) { Dictionary <Material, List <CombineInstance> > meshHash = new Dictionary <Material, List <CombineInstance> >(); Matrix4x4 chunkWorldToLocal = myChunk.transform.worldToLocalMatrix; foreach (Renderer renderer in checkState.Keys) { if (checkState[renderer]) { MeshFilter meshFilter = renderer.GetComponent <MeshFilter>(); int numSubMeshes = meshFilter.sharedMesh.subMeshCount; for (int submeshIndex = 0; submeshIndex < numSubMeshes; ++submeshIndex) { Material material = renderer.sharedMaterials[submeshIndex]; List <CombineInstance> materialMeshes = null; if (!meshHash.TryGetValue(material, out materialMeshes)) { materialMeshes = new List <CombineInstance>(); meshHash[material] = materialMeshes; } CombineInstance instance = new CombineInstance(); instance.transform = chunkWorldToLocal * renderer.transform.localToWorldMatrix; instance.mesh = renderer.GetComponent <MeshFilter>().sharedMesh; instance.subMeshIndex = submeshIndex; materialMeshes.Add(instance); } } } if (meshHash.Count > 0) { List <CombineInstance> combinedMeshes = new List <CombineInstance>(); List <Material> combinedMaterials = new List <Material>(); foreach (Material material in meshHash.Keys) { CombineInstance instance = new CombineInstance(); instance.mesh = new Mesh(); instance.mesh.CombineMeshes(meshHash[material].ToArray(), true, true); combinedMeshes.Add(instance); combinedMaterials.Add(material); } string sceneDir; string sceneName; string exportFolder = SECTR_Asset.MakeExportFolder("Proxies", false, out sceneDir, out sceneName); myChunk.ProxyMesh = SECTR_Asset.Create <Mesh>(exportFolder, myChunk.name + "_Proxy", new Mesh()); myChunk.ProxyMesh.CombineMeshes(combinedMeshes.ToArray(), false, false); myChunk.ProxyMaterials = combinedMaterials.ToArray(); int numCombined = combinedMeshes.Count; for (int combinedIndex = 0; combinedIndex < numCombined; ++combinedIndex) { Mesh.DestroyImmediate(combinedMeshes[combinedIndex].mesh); } SECTR_VC.WaitForVC(); } else { EditorUtility.DisplayDialog("Proxy Error", "Must have at least one mesh selected to create a proxy.", "Ok"); } } EditorGUILayout.EndVertical(); } } GUI.enabled = true; if (modiferMode != ModifierMode.None) { EditorApplication.update += ExportUpdate; } }
protected override void OnGUI() { base.OnGUI(); List <SECTR_Sector> sortedSectors = new List <SECTR_Sector>(SECTR_Sector.All); sortedSectors.Sort(delegate(SECTR_Sector a, SECTR_Sector b) { return(a.name.CompareTo(b.name)); }); int numSectors = sortedSectors.Count; bool sceneHasSectors = numSectors > 0; EditorGUILayout.BeginVertical(); DrawHeader("SECTORS", ref sectorSearch, 100, true); Rect r = EditorGUILayout.BeginVertical(); r.y -= lineHeight; scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition); bool wasEnabled = GUI.enabled; GUI.enabled = false; GUI.Button(r, sceneHasSectors ? "" : "Current Scene Has No Sectors"); GUI.enabled = wasEnabled; bool allExported = true; bool allImported = true; bool someImported = false; SECTR_Sector newSelectedSector = Selection.activeGameObject ? Selection.activeGameObject.GetComponent <SECTR_Sector>() : null;; bool mouseDown = Event.current.type == EventType.MouseDown && Event.current.button == 0; if (mouseDown) { newSelectedSector = null; } for (int sectorIndex = 0; sectorIndex < numSectors; ++sectorIndex) { SECTR_Sector sector = sortedSectors[sectorIndex]; if (sector.name.ToLower().Contains(sectorSearch.ToLower())) { bool selected = sector == selectedSector; Rect clipRect = EditorGUILayout.BeginHorizontal(); if (selected) { Rect selectionRect = clipRect; selectionRect.y += 1; selectionRect.height -= 1; GUI.Box(selectionRect, "", selectionBoxStyle); } if (sector.Frozen) { allImported = false; } else { if (sector.GetComponent <SECTR_Chunk>()) { someImported = true; } allExported = false; } elementStyle.normal.textColor = selected ? Color.white : UnselectedItemColor; elementStyle.alignment = TextAnchor.MiddleCenter; EditorGUILayout.LabelField(sector.name, elementStyle); EditorGUILayout.EndHorizontal(); if (sector.gameObject.isStatic) { float buttonWidth = 50; SECTR_Chunk chunk = sector.GetComponent <SECTR_Chunk>(); bool alreadyExported = chunk && System.IO.File.Exists(SECTR_Asset.UnityToOSPath(chunk.NodeName)); if (sector.Frozen) { // Import if (alreadyExported && GUI.Button(new Rect(0, clipRect.yMin, buttonWidth, clipRect.height), new GUIContent("Import", "Imports this Sector into the scene."))) { SECTR_StreamExport.ImportFromChunk(sector); break; } } else { // Revert if (alreadyExported && GUI.Button(new Rect(0, clipRect.yMin, buttonWidth, clipRect.height), new GUIContent("Revert", "Discards changes to this Sector."))) { SECTR_StreamExport.DeleteExportedSector(sector); chunk.enabled = true; break; } // Export if (GUI.Button(new Rect(clipRect.xMax - buttonWidth, clipRect.yMin, buttonWidth, clipRect.height), new GUIContent("Export", "Exports this Sector into a Chunk scene."))) { SECTR_StreamExport.ExportToChunk(sector); break; } } } if (mouseDown && clipRect.Contains(Event.current.mousePosition)) { newSelectedSector = sector; } } } if (newSelectedSector != selectedSector) { selectedSector = newSelectedSector; Selection.activeGameObject = selectedSector ? selectedSector.gameObject : null; if (SceneView.lastActiveSceneView) { SceneView.lastActiveSceneView.FrameSelected(); } Repaint(); } EditorGUILayout.EndScrollView(); EditorGUILayout.EndVertical(); string nullSearch = null; GUI.enabled = true; DrawHeader("EXPORT AND IMPORT", ref nullSearch, 0, true); wasEnabled = GUI.enabled; bool editMode = !EditorApplication.isPlaying && !EditorApplication.isPaused; GUI.enabled = sceneHasSectors && !allExported && wasEnabled && editMode; if (GUILayout.Button(new GUIContent("Export All Sectors", "Exports all static Sectors into Chunk scenes and prepares them for streaming."))) { SECTR_StreamExport.ExportSceneChunksUI(); Repaint(); } GUI.enabled = sceneHasSectors && !allImported && wasEnabled && editMode; if (GUILayout.Button(new GUIContent("Import All Sectors", "Imports all exported Chunks back into the scene."))) { SECTR_StreamExport.ImportSceneChunksUI(); Repaint(); } GUI.enabled = sceneHasSectors && !allExported && someImported && wasEnabled && editMode; if (GUILayout.Button(new GUIContent("Revert All Sectors", "Reverts all exported Chunks to their exported state."))) { SECTR_StreamExport.RevertSceneChunksUI(); Repaint(); } GUI.enabled = true; DrawHeader("LIGHTMAPPING", ref nullSearch, 0, true); #if UNITY_5_LATE GUI.enabled = sceneHasSectors && selectedSector && allExported && wasEnabled && editMode; if (GUILayout.Button(new GUIContent("Lightmap Selected Sector", "Lightmaps selected Sector in isolation."))) { if (EditorUtility.DisplayDialog("Confirm Lightmap Bake", "Are you sure you want to bake lightmaps for " + selectedSector.name + "? Its lighting will not be affected by any other Sectors.", "Yes", "No")) { string[] paths = new string[2]; paths[0] = EditorApplication.currentScene; paths[1] = selectedSector.GetComponent <SECTR_Chunk>().NodeName; Lightmapping.BakeMultipleScenes(paths); } } GUI.enabled = sceneHasSectors && allExported && wasEnabled && editMode; if (GUILayout.Button(new GUIContent("Lightmap All Sectors", "Lightmaps all exported Chunks."))) { if (EditorUtility.DisplayDialog("Confirm Lightmap Bake", "Are you sure you want to bake lightmaps for all subscenes? This may take quite a while.", "Yes", "No")) { string[] paths = new string[numSectors + 1]; paths[0] = EditorApplication.currentScene; for (int sectorIndex = 0; sectorIndex < numSectors; ++sectorIndex) { paths[sectorIndex + 1] = sortedSectors[sectorIndex].GetComponent <SECTR_Chunk>().NodeName; } Lightmapping.BakeMultipleScenes(paths); } } #endif GUI.enabled = true; DrawHeader("EXTRA", ref nullSearch, 0, true); GUI.enabled = sceneHasSectors; if (GUILayout.Button(new GUIContent("Export Sector Graph Visualization", "Writes out a .dot file of the Sector/Portal graph, which can be visualized in GraphViz."))) { SECTR_StreamExport.WriteGraphDot(); } GUI.enabled = wasEnabled; EditorGUILayout.EndVertical(); }