private void ExportUpdate()
    {
        SECTR_Chunk myChunk = (SECTR_Chunk)target;

        if (myChunk)
        {
            SECTR_Sector mySector = myChunk.GetComponent <SECTR_Sector>();
            if (mySector)
            {
                switch (modiferMode)
                {
                case ModifierMode.Export:
                    SECTR_StreamExport.ExportToChunk(mySector);
                    break;

                case ModifierMode.Import:
                    SECTR_StreamExport.ImportFromChunk(mySector);
                    break;

                case ModifierMode.Revert:
                    SECTR_StreamExport.DeleteExportedSector(mySector);
                    myChunk.enabled = true;
                    break;

                case ModifierMode.None:
                default:
                    break;
                }
            }
            modiferMode = ModifierMode.None;
        }
        EditorApplication.update -= ExportUpdate;
    }
    private void ChunkChanged(SECTR_Chunk source, bool loaded)
    {
        int numSectors = Sectors.Count;

        for (int sectorIndex = 0; sectorIndex < numSectors; ++sectorIndex)
        {
            SECTR_Sector sector = Sectors[sectorIndex];
            if (sector)
            {
                SECTR_Chunk chunk = sector.GetComponent <SECTR_Chunk>();
                if (chunk && chunk != source)
                {
                    // We need to temporarily remove our callback so
                    // that we don't get infinite loops.
                    chunk.ReferenceChange -= ChunkChanged;
                    if (loaded)
                    {
                        chunk.AddReference();
                    }
                    else
                    {
                        chunk.RemoveReference();
                    }
                    chunk.ReferenceChange += ChunkChanged;
                }
            }
        }
    }
 private void _TrySceneActivation()
 {
     if (chunkActivating == null &&
         asyncLoadOp != null && !asyncLoadOp.allowSceneActivation && asyncLoadOp.progress >= 0.9f &&
         activationQueue.Count > 0 && activationQueue.First.Value == this)
     {
         chunkActivating = this;
         asyncLoadOp.allowSceneActivation = true;
     }
 }
 private bool _IsSectorLoaded(SECTR_Sector sector)
 {
     if (sector && sector.Frozen)
     {
         SECTR_Chunk chunk = sector.GetComponent <SECTR_Chunk>();
         if (chunk && !chunk.IsLoaded())
         {
             return(false);
         }
     }
     return(true);
 }
    // Add and removes references to current and neighboring sectors
    // as this component moves around the world.
    private void _MembershipChanged(List <SECTR_Sector> left, List <SECTR_Sector> joined)
    {
        // Add ref to all of the new objects first so that we don't unload and then immeditately load again.
        if (joined != null)
        {
            int numJoined = joined.Count;
            for (int sectorIndex = 0; sectorIndex < numJoined; ++sectorIndex)
            {
                SECTR_Sector sector = joined[sectorIndex];
                if (sector && !currentSectors.Contains(sector))
                {
                    SECTR_Graph.BreadthWalk(ref neighbors, sector, 0, MaxDepth);
                    int numNeighbors = neighbors.Count;
                    for (int neighborIndex = 0; neighborIndex < numNeighbors; ++neighborIndex)
                    {
                        SECTR_Chunk neighborChunk = neighbors[neighborIndex].Sector.GetComponent <SECTR_Chunk>();
                        if (neighborChunk)
                        {
                            neighborChunk.AddReference();
                        }
                    }
                    currentSectors.Add(sector);
                }
            }
        }

        // Dec ref any sectors we're no longer in.
        if (left != null)
        {
            int numLeft = left.Count;
            for (int sectorIndex = 0; sectorIndex < numLeft; ++sectorIndex)
            {
                SECTR_Sector sector = left[sectorIndex];
                // We have to be careful about double-removing on shutdown b/c we don't control
                // order of destruction.
                if (sector && currentSectors.Contains(sector))
                {
                    SECTR_Graph.BreadthWalk(ref neighbors, sector, 0, MaxDepth);
                    int numNeighbors = neighbors.Count;
                    for (int neighborIndex = 0; neighborIndex < numNeighbors; ++neighborIndex)
                    {
                        SECTR_Chunk neighborChunk = neighbors[neighborIndex].Sector.GetComponent <SECTR_Chunk>();
                        if (neighborChunk)
                        {
                            neighborChunk.RemoveReference();
                        }
                    }
                    currentSectors.Remove(sector);
                }
            }
        }
    }
    protected override void OnTriggerEnter(Collider other)
    {
        base.OnTriggerEnter(other);
        if (Portal && ((LoadLayers & 1 << other.gameObject.layer) != 0))
        {
            SECTR_Chunk oppositeChunk = _GetOppositeChunk(other.transform.position);
            if (oppositeChunk)
            {
                LoadRequest loadRequest;
                SECTR_Chunk postUnload = null;
                if (loadRequests.TryGetValue(other, out loadRequest))
                {
                    if (loadRequest.chunkToUnload)
                    {
                        postUnload = loadRequest.chunkToUnload;
                        loadRequest.chunkToUnload = null;
                    }
                }
                else
                {
                    loadRequest = new LoadRequest();
                }

                if (FadeBeforeLoad && !oppositeChunk.IsLoaded())
                {
                    loadRequest.fadeMode = FadeMode.FadeOut;
                }

                loadRequest.enteredFront = oppositeChunk.Sector == Portal.BackSector;
                loadRequest.enteredBack  = oppositeChunk.Sector == Portal.FrontSector;
                if (FadeBeforeLoad)
                {
                    loadRequest.chunkToLoad = oppositeChunk;
                }
                else
                {
                    oppositeChunk.AddReference();
                    loadRequest.loadedChunk = oppositeChunk;
                }
                loadRequests[other] = loadRequest;

                if (postUnload)
                {
                    postUnload.RemoveReference();
                }
            }
        }
    }
    void Start()
    {
        cachedMember.ForceUpdate(true);
        int numSectors = cachedMember.Sectors.Count;

        for (int sectorIndex = 0; sectorIndex < numSectors; ++sectorIndex)
        {
            SECTR_Sector sector = cachedMember.Sectors[sectorIndex];
            SECTR_Chunk  chunk  = sector.GetComponent <SECTR_Chunk>();
            if (chunk)
            {
                chunk.AddReference();
            }
        }

        LockSelf(true);
    }
    void OnDisable()
    {
        int numSectors = Sectors.Count;

        for (int sectorIndex = 0; sectorIndex < numSectors; ++sectorIndex)
        {
            SECTR_Sector sector = Sectors[sectorIndex];
            if (sector)
            {
                SECTR_Chunk chunk = sector.GetComponent <SECTR_Chunk>();
                if (chunk)
                {
                    chunk.ReferenceChange -= ChunkChanged;
                }
            }
        }
    }
    void OnDisable()
    {
        int numSectors = sectors.Count;

        for (int sectorIndex = 0; sectorIndex < numSectors; ++sectorIndex)
        {
            SECTR_Sector sector = sectors[sectorIndex];
            if (sector)
            {
                SECTR_Chunk chunk = sector.GetComponent <SECTR_Chunk>();
                if (chunk)
                {
                    chunk.RemoveReference();
                }
            }
        }
        sectors.Clear();
        updated = false;
    }
Esempio n. 10
0
 private void _RefChunks()
 {
     if (!chunksReferenced)
     {
         int numChunks = Sectors.Count;
         for (int chunkIndex = 0; chunkIndex < numChunks; ++chunkIndex)
         {
             SECTR_Sector sector = Sectors[chunkIndex];
             if (sector)
             {
                 SECTR_Chunk chunk = sector.GetComponent <SECTR_Chunk>();
                 if (chunk)
                 {
                     chunk.AddReference();
                 }
             }
         }
         chunksReferenced = true;
     }
 }
    protected override void OnTriggerExit(Collider other)
    {
        base.OnTriggerExit(other);

        if (Portal && ((LoadLayers & 1 << other.gameObject.layer) != 0))
        {
            SECTR_Chunk oppositeChunk = _GetOppositeChunk(other.transform.position);
            if (oppositeChunk)
            {
                LoadRequest loadRequest = loadRequests[other];
                if (FadeBeforeLoad && loadRequest.fadeMode == FadeMode.FadeOut)
                {
                    loadRequest.fadeMode = FadeMode.FadeIn;
                }

                bool exitedBack  = oppositeChunk.Sector == Portal.FrontSector;
                bool exitedFront = oppositeChunk.Sector == Portal.BackSector;
                if (loadRequest.loadedChunk && ((loadRequest.enteredFront && exitedFront) || (loadRequest.enteredBack && exitedBack)))
                {
                    loadRequest.chunkToUnload = loadRequest.loadedChunk;
                }
                else if ((loadRequest.enteredFront && exitedBack) || (loadRequest.enteredBack && exitedFront))
                {
                    loadRequest.chunkToUnload = oppositeChunk;
                }
                else
                {
                    loadRequest.chunkToUnload = loadRequest.loadedChunk;
                }

                if (loadRequests.Count > 1 || IsClosed())
                {
                    if (loadRequest.chunkToUnload)
                    {
                        loadRequest.chunkToUnload.RemoveReference();
                    }
                    loadRequests.Remove(other);
                }
            }
        }
    }
    private void _DestoryChunk(bool createProxy, bool fromDisable)
    {
        if (cachedSector.TopTerrain || cachedSector.BottomTerrain || cachedSector.RightTerrain || cachedSector.LeftTerrain)
        {
            cachedSector.DisonnectTerrainNeighbors();
        }
#if UNITY_5_LATE
#pragma warning disable CS0618 // Typ lub sk³adowa jest przestarza³a
        Application.UnloadLevel(ScenePath);
#pragma warning restore CS0618 // Typ lub sk³adowa jest przestarza³a
#else
        GameObject.Destroy(chunkRoot);
#endif
        chunkRoot     = null;
        chunkSector   = null;
        recenterChunk = false;
        if (asyncLoadOp != null)
        {
            if (chunkActivating == this)
            {
                chunkActivating = null;
            }
            activationQueue.Remove(this);
            asyncLoadOp = null;
        }
        if (fromDisable || quitting)
        {
            _UnloadResources();
        }
        else if (!requestedDeferredUnload)
        {
            requestedDeferredUnload = true;
            StartCoroutine("_DeferredUnload");
        }
        loadState = LoadState.Unloaded;
        if (createProxy && ProxyMesh)
        {
            _CreateProxy();
        }
    }
    void FixedUpdate()
    {
        switch (loadState)
        {
        case LoadState.Loading:
            _TrySceneActivation();
            if (asyncLoadOp == null || asyncLoadOp.isDone)
            {
                if (asyncLoadOp != null)
                {
                    chunkActivating = null;
                    activationQueue.RemoveFirst();
                    asyncLoadOp = null;
                }
                loadState = LoadState.Loaded;
                // Run update again to try to parent the chunk right away.
                FixedUpdate();
            }
            break;

        case LoadState.Loaded:
            // Unity takes a frame to create the objects, so fix them up here.
            _SetupChunk();
            break;

        case LoadState.Active:
            // Do nothing.
            break;

        case LoadState.Unloading:
            _TrySceneActivation();
            _FindChunkRoot();
            if (chunkRoot)
            {
                _DestoryChunk(true, false);
            }
            break;
        }
    }
Esempio n. 14
0
    /// 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;
        }
    }
    void Update()
    {
        Vector3 position     = transform.position;
        Bounds  loadBounds   = new Bounds(position, LoadSize);
        Bounds  unloadBounds = new Bounds(position, LoadSize * (1f + UnloadBuffer));

        SECTR_Sector.GetContaining(ref loadSectors, loadBounds);
        SECTR_Sector.GetContaining(ref unloadSectors, unloadBounds);

        int sectorIndex = 0;
        int numSectors  = sectors.Count;

        while (sectorIndex < numSectors)
        {
            SECTR_Sector oldSector = sectors[sectorIndex];
            if (loadSectors.Contains(oldSector))
            {
                loadSectors.Remove(oldSector);
                ++sectorIndex;
            }
            else if (!unloadSectors.Contains(oldSector))
            {
                SECTR_Chunk oldChunk = oldSector.GetComponent <SECTR_Chunk>();
                if (oldChunk)
                {
                    oldChunk.RemoveReference();
                }
                sectors.RemoveAt(sectorIndex);
                --numSectors;
            }
            else
            {
                ++sectorIndex;
            }
        }

        numSectors = loadSectors.Count;
        int layerMaskValue = LayersToLoad.value;

        if (numSectors > 0)
        {
            for (sectorIndex = 0; sectorIndex < numSectors; ++sectorIndex)
            {
                SECTR_Sector newSector = loadSectors[sectorIndex];
                if (newSector.Frozen && ((layerMaskValue & (1 << newSector.gameObject.layer)) != 0))
                {
                    SECTR_Chunk newChunk = newSector.GetComponent <SECTR_Chunk>();
                    if (newChunk)
                    {
                        newChunk.AddReference();
                    }
                    sectors.Add(newSector);
                }
            }
        }

        if (locked && Loaded)
        {
            LockSelf(false);
        }

        updated = true;
    }
Esempio n. 17
0
    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();
    }
Esempio n. 18
0
    /// Re-adds the data from the specified Sector to the current scene. Safe to call from command line.
    /// <param name="sector">The Sector to import.</param>
    /// <returns>Returns true if Sector was successfully imported, false otherwise.</returns>
    public static bool ImportFromChunk(SECTR_Sector sector)
    {
        if (sector == null)
        {
            Debug.LogError("Cannot import invalid Sector.");
            return(false);
        }

        if (!sector.Frozen)
        {
            Debug.Log("Skipping import of unfrozen Sector");
            return(true);
        }

        if (!sector.gameObject.isStatic)
        {
            Debug.Log("Skipping import of dynamic Sector " + sector.name + ".");
            return(true);
        }

        SECTR_Chunk chunk = sector.GetComponent <SECTR_Chunk>();

        if (chunk)
        {
            EditorApplication.OpenSceneAdditive(chunk.NodeName);
            GameObject newNode = GameObject.Find(chunk.NodeName);
            if (newNode == null)
            {
                Debug.LogError("Exported data does not match scene. Skipping import of " + sector.name + ".");
                return(false);
            }

            SECTR_ChunkRef chunkRef = newNode.GetComponent <SECTR_ChunkRef>();
            if (chunkRef && chunkRef.RealSector)
            {
                newNode = chunkRef.RealSector.gameObject;
                if (chunkRef.Recentered)
                {
                    newNode.transform.parent        = sector.transform;
                    newNode.transform.localPosition = Vector3.zero;
                    newNode.transform.localRotation = Quaternion.identity;
                    newNode.transform.localScale    = Vector3.one;
                }
                newNode.transform.parent = null;
                GameObject.DestroyImmediate(chunkRef.gameObject);
            }

            while (newNode.transform.childCount > 0)
            {
                newNode.transform.GetChild(0).parent = sector.transform;
            }


            // Merge lightmaps into the scene
#if !UNITY_STREAM_ENLIGHTEN
            SECTR_LightmapRef newRef = newNode.GetComponent <SECTR_LightmapRef>();
            if (newRef)
            {
                int            numLightmaps = LightmapSettings.lightmaps.Length;
                LightmapData[] newLightmaps = new LightmapData[numLightmaps];
                for (int lightmapIndex = 0; lightmapIndex < numLightmaps; ++lightmapIndex)
                {
                    newLightmaps[lightmapIndex] = LightmapSettings.lightmaps[lightmapIndex];
                }
                foreach (SECTR_LightmapRef.RefData refData in newRef.LightmapRefs)
                {
                    if (refData.index >= 0 && refData.index < numLightmaps)
                    {
                        LightmapData newData = new LightmapData();
                        newData.lightmapNear        = refData.NearLightmap;
                        newData.lightmapFar         = refData.FarLightmap;
                        newLightmaps[refData.index] = newData;
                    }
                }
                LightmapSettings.lightmaps = newLightmaps;

#if !UNITY_4
                foreach (SECTR_LightmapRef.RenderData indexData in newRef.LightmapRenderers)
                {
                    if (indexData.renderer)
                    {
                        indexData.renderer.lightmapIndex       = indexData.rendererLightmapIndex;
                        indexData.renderer.lightmapScaleOffset = indexData.rendererLightmapScaleOffset;
                        GameObjectUtility.SetStaticEditorFlags(indexData.renderer.gameObject, GameObjectUtility.GetStaticEditorFlags(indexData.renderer.gameObject) | StaticEditorFlags.BatchingStatic);
                    }
                    if (indexData.terrain)
                    {
                        indexData.terrain.lightmapIndex = indexData.terrainLightmapIndex;
                    }
                }
#endif

                GameObject.DestroyImmediate(newRef);
            }
#endif


            // Copy terrain component specially because the generic routine doesn't work for some reason.
            Terrain terrain = newNode.GetComponent <Terrain>();
            if (terrain)
            {
                Terrain terrainClone = sector.gameObject.AddComponent <Terrain>();
                terrainClone.terrainData             = terrain.terrainData;
                terrainClone.basemapDistance         = terrain.basemapDistance;
                terrainClone.castShadows             = terrain.castShadows;
                terrainClone.detailObjectDensity     = terrain.detailObjectDensity;
                terrainClone.detailObjectDistance    = terrain.detailObjectDistance;
                terrainClone.heightmapMaximumLOD     = terrain.heightmapMaximumLOD;
                terrainClone.heightmapPixelError     = terrain.heightmapPixelError;
                terrainClone.lightmapIndex           = terrain.lightmapIndex;
                terrainClone.treeBillboardDistance   = terrain.treeBillboardDistance;
                terrainClone.treeCrossFadeLength     = terrain.treeCrossFadeLength;
                terrainClone.treeDistance            = terrain.treeDistance;
                terrainClone.treeMaximumFullLODCount = terrain.treeMaximumFullLODCount;
                terrainClone.Flush();
            }

            // Destroy the placeholder Member if there is one.
            // It's theoretically possible to have multiple members, so remove them all.
            SECTR_Member[] oldMembers    = newNode.GetComponents <SECTR_Member>();
            int            numOldMembers = oldMembers.Length;
            for (int oldIndex = 0; oldIndex < numOldMembers; ++oldIndex)
            {
                GameObject.DestroyImmediate(oldMembers[oldIndex]);
            }

            // Copy all remaining components over
            Component[] remainingComponents = newNode.GetComponents <Component>();
            int         numRemaining        = remainingComponents.Length;
            for (int componentIndex = 0; componentIndex < numRemaining; ++componentIndex)
            {
                Component component = remainingComponents[componentIndex];
                if (component != newNode.transform && component.GetType() != typeof(Terrain))
                {
                    Component componentClone = sector.gameObject.AddComponent(component.GetType());
                    EditorUtility.CopySerialized(component, componentClone);
                }
            }

            // Enable a TerrainComposer node if there is one.
            MonoBehaviour terrainNeighbors = sector.GetComponent("TerrainNeighbors") as MonoBehaviour;
            if (terrainNeighbors)
            {
                terrainNeighbors.enabled = true;
            }

            GameObject.DestroyImmediate(newNode);
            sector.Frozen = false;
            sector.ForceUpdate(true);
            chunk.enabled = false;
            return(true);
        }
        return(false);
    }
Esempio n. 19
0
    /// Exports the specific Sector into an external level file, deleting the current scene copy in the process. Safe to call from command line.
    /// <param name="sector">The Sector to export.</param>
    /// <returns>Returns true if Sector was successfully exported, false otherwise.</returns>
    public static bool ExportToChunk(SECTR_Sector sector)
    {
        if (string.IsNullOrEmpty(EditorApplication.currentScene))
        {
            Debug.LogError("Scene must be saved befor export.");
            return(false);
        }

        if (sector == null)
        {
            Debug.LogError("Cannot export null Sector.");
            return(false);
        }

        if (!sector.gameObject.activeInHierarchy)
        {
            Debug.LogError("Cannot export inactive Sectors.");
            return(false);
        }

        if (!sector.gameObject.isStatic)
        {
            Debug.Log("Skipping export of dynamic sector" + sector.name + ".");
            return(true);
        }

        if (sector.Frozen)
        {
            // Already exported
            Debug.Log("Skipping frozen sector " + sector.name);
            return(true);
        }

        string sceneDir;
        string sceneName;
        string exportDir = SECTR_Asset.MakeExportFolder("Chunks", false, out sceneDir, out sceneName);

        if (string.IsNullOrEmpty(exportDir))
        {
            Debug.LogError("Could not create Chunks folder.");
            return(false);
        }

        // Delete the previous export, if there is one.
        // Prevents duplicate names piling up.
        SECTR_Chunk oldChunk = sector.GetComponent <SECTR_Chunk>();

        if (oldChunk)
        {
            AssetDatabase.DeleteAsset(oldChunk.NodeName);
            SECTR_VC.WaitForVC();
        }

        // Sectors are not guaranteed to be uniquely named, so always generate a unique name.
        string originalSectorName = sector.name;
        string newAssetPath       = AssetDatabase.GenerateUniqueAssetPath(exportDir + sceneName + "_" + originalSectorName + ".unity");

        sector.name = newAssetPath;

        // Make sure the current scene is saved, preserving all changes.
        EditorApplication.SaveScene();
        SECTR_VC.WaitForVC();

        string originalScene = EditorApplication.currentScene;
        List <EditorBuildSettingsScene> sceneSettings = new List <EditorBuildSettingsScene>(EditorBuildSettings.scenes);

        // SaveScene can cause crashes w/ version control, so we work around it with a copy.
        AssetDatabase.CopyAsset(originalScene, newAssetPath);
        SECTR_VC.WaitForVC();

        EditorApplication.OpenScene(newAssetPath);
        SECTR_VC.WaitForVC();

        sector = _FindSectorByName(newAssetPath);

        // Make sure to force update all members so that membership info is correct.
        List <SECTR_Member> allMembers = FindAllOfType <SECTR_Member>();

        for (int memberIndex = 0; memberIndex < allMembers.Count; ++memberIndex)
        {
            allMembers[memberIndex].ForceUpdate(true);
        }

        // Multi-sector members need to stay in the master scene.
        foreach (SECTR_Member member in allMembers)
        {
            if (member.Sectors.Count > 1 && member.transform.IsChildOf(sector.transform))
            {
                bool unparentMember = true;

                // Only affect the first member in the hierarchy below the sector
                Transform parent = member.transform.parent;
                while (parent != sector.transform)
                {
                    if (parent.GetComponent <SECTR_Member>() != null)
                    {
                        unparentMember = false;
                        break;
                    }
                    parent = parent.parent;
                }

                if (unparentMember)
                {
                    if (PrefabUtility.GetPrefabType(sector.gameObject) != PrefabType.None)
                    {
                        Debug.LogWarning("Export is unparenting shared member " + member.name + " from prefab Sector " + sector.name + ". This will break the prefab.");
                    }
                    member.transform.parent = null;
                }
            }
        }

        // Unparent the sector from anything
        sector.transform.parent = null;

        // Any children of this sector should be exported.
        // The rest should be destroyed.
        List <Transform> allXforms = FindAllOfType <Transform>();

#if !UNITY_STREAM_ENLIGHTEN
        List <int> referencedLightmaps = new List <int>(LightmapSettings.lightmaps.Length);
#endif
        foreach (Transform transform in allXforms)
        {
            if (transform && transform.IsChildOf(sector.transform))
            {
#if !UNITY_STREAM_ENLIGHTEN
                Renderer childRenderer = transform.GetComponent <Renderer>();
                if (childRenderer && childRenderer.lightmapIndex >= 0 && !referencedLightmaps.Contains(childRenderer.lightmapIndex))
                {
                    referencedLightmaps.Add(childRenderer.lightmapIndex);
                }

                Terrain childTerrain = transform.GetComponent <Terrain>();;
                if (childTerrain && childTerrain.lightmapIndex >= 0 && !referencedLightmaps.Contains(childTerrain.lightmapIndex))
                {
                    referencedLightmaps.Add(childTerrain.lightmapIndex);
                }
#endif
            }
            else if (transform)
            {
                GameObject.DestroyImmediate(transform.gameObject);
            }
        }

#if !UNITY_STREAM_ENLIGHTEN
        if (referencedLightmaps.Count > 0)
        {
            SECTR_LightmapRef newRef = sector.GetComponent <SECTR_LightmapRef>();
            if (!newRef)
            {
                newRef = sector.gameObject.AddComponent <SECTR_LightmapRef>();
            }
            newRef.ReferenceLightmaps(referencedLightmaps);
        }

        // Nuke global data like nav meshes and lightmaps
        // Lightmap indexes will be preserved on export.
        NavMeshBuilder.ClearAllNavMeshes();
#if !UNITY_4
        SerializedObject   serialObj    = new SerializedObject(GameObject.FindObjectOfType <LightmapSettings>());
        SerializedProperty snapshotProp = serialObj.FindProperty("m_LightmapSnapshot");
        snapshotProp.objectReferenceValue = null;
        serialObj.ApplyModifiedProperties();
#endif
        LightmapSettings.lightmaps   = new LightmapData[0];
        LightmapSettings.lightProbes = new LightProbes();
#endif

        GameObject     dummyParent = new GameObject(newAssetPath);
        SECTR_ChunkRef chunkRef    = dummyParent.AddComponent <SECTR_ChunkRef>();
        chunkRef.RealSector     = sector.transform;
        sector.transform.parent = dummyParent.transform;

        // If the sector has a chunk marked for re-use, perform some special work.
        SECTR_Chunk originalChunk = sector.GetComponent <SECTR_Chunk>();
        if (originalChunk && originalChunk.ExportForReuse)
        {
            chunkRef.Recentered            = true;
            sector.transform.localPosition = Vector3.zero;
            sector.transform.localRotation = Quaternion.identity;
            sector.transform.localScale    = Vector3.one;
            sector.gameObject.SetActive(false);
        }

        // Rename the real chunk root with a clear name.
        sector.name = originalSectorName + "_Chunk";

        // Strip off any functional objects that will be preserved in the root scene.
        // Destroy the chunk first because it has dependencies on Sector.
        GameObject.DestroyImmediate(originalChunk);
        Component[] components = sector.GetComponents <Component>();
        foreach (Component component in components)
        {
            if (component.GetType().IsSubclassOf(typeof(MonoBehaviour)) &&
                component.GetType() != typeof(Terrain) && component.GetType() != typeof(SECTR_LightmapRef))
            {
                GameObject.DestroyImmediate(component);
            }
        }

        // Re-add a member that will persist all of the references and save us work post load.
        SECTR_Member refMember = chunkRef.RealSector.gameObject.AddComponent <SECTR_Member>();
        refMember.NeverJoin        = true;
        refMember.BoundsUpdateMode = SECTR_Member.BoundsUpdateModes.Static;
        refMember.ForceUpdate(true);

        // Save scene and append it to the build settings.
        EditorApplication.SaveScene();
        SECTR_VC.WaitForVC();

        EditorBuildSettingsScene sectorSceneSettings = new EditorBuildSettingsScene(newAssetPath, true);
        bool sceneExists = false;
        foreach (EditorBuildSettingsScene oldScene in sceneSettings)
        {
            if (oldScene.path == newAssetPath)
            {
                sceneExists      = true;
                oldScene.enabled = true;
                break;
            }
        }
        if (!sceneExists)
        {
            sceneSettings.Add(sectorSceneSettings);
        }
        string[] pathParts  = newAssetPath.Split('/');
        string   sectorPath = pathParts[pathParts.Length - 1].Replace(".unity", "");

        // Update the master scene with exported info.
        EditorApplication.OpenScene(originalScene);
        SECTR_VC.WaitForVC();

        sector      = _FindSectorByName(newAssetPath);
        sector.name = originalSectorName;

        DeleteExportedSector(sector);

        // Make sure Sectors has a Chunk
        SECTR_Chunk newChunk = sector.GetComponent <SECTR_Chunk>();
        if (!newChunk)
        {
            newChunk = sector.gameObject.AddComponent <SECTR_Chunk>();
        }
        newChunk.ScenePath = sectorPath;
        newChunk.NodeName  = newAssetPath;
        newChunk.enabled   = true;

        // Disable a TerrainComposer node if there is one.
        MonoBehaviour terrainNeighbors = sector.GetComponent("TerrainNeighbors") as MonoBehaviour;

        if (terrainNeighbors)
        {
            terrainNeighbors.enabled = false;
        }

        // Save off the accumulated build settings
        EditorBuildSettings.scenes = sceneSettings.ToArray();
        AssetDatabase.Refresh();

        EditorApplication.SaveScene();
        SECTR_VC.WaitForVC();

        return(true);
    }