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);
    }
예제 #2
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);
    }
예제 #3
0
    void _ActivateLOD(int lodIndex)
    {
        toHide.Clear();
        toShow.Clear();

        if (activeLOD >= 0 && activeLOD < LODs.Count)
        {
            LODSet set        = LODs[activeLOD];
            int    numEntries = set.LODEntries.Count;
            for (int entryIndex = 0; entryIndex < numEntries; ++entryIndex)
            {
                LODEntry entry = set.LODEntries[entryIndex];
                if (entry.gameObject)
                {
                    toHide.Add(entry.gameObject);
                }
            }
        }

        if (lodIndex >= 0 && lodIndex < LODs.Count)
        {
            LODSet set        = LODs[lodIndex];
            int    numEntries = set.LODEntries.Count;
            for (int entryIndex = 0; entryIndex < numEntries; ++entryIndex)
            {
                LODEntry entry = set.LODEntries[entryIndex];
                if (entry.gameObject)
                {
                    toHide.Remove(entry.gameObject);
                    toShow.Add(entry);
                }
            }
        }

        int numHidden = toHide.Count;

        for (int hiddenIndex = 0; hiddenIndex < numHidden; ++hiddenIndex)
        {
            toHide[hiddenIndex].SetActive(false);
        }

        int numShown = toShow.Count;

        for (int showIndex = 0; showIndex < numShown; ++showIndex)
        {
            LODEntry entry = toShow[showIndex];
            entry.gameObject.SetActive(true);
            if (entry.lightmapSource)
            {
                Renderer entryRenderer = entry.gameObject.GetComponent <Renderer>();
                if (entryRenderer)
                {
                    entryRenderer.lightmapIndex = entry.lightmapSource.lightmapIndex;
#if UNITY_4_0 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6
                    entryRenderer.lightmapTilingOffset = entry.lightmapSource.lightmapTilingOffset;
#else
                    entryRenderer.lightmapScaleOffset = entry.lightmapSource.lightmapScaleOffset;
#endif
                }
            }
        }

        activeLOD = lodIndex;

        if (CullSiblings != 0 &&
            ((activeLOD == -1 && !siblingsDisabled) || (activeLOD != -1 && siblingsDisabled)))
        {
            siblingsDisabled = (activeLOD == -1);

            if ((CullSiblings & SiblinglFlags.Behaviors) != 0)
            {
                MonoBehaviour[] siblingBehaviors = gameObject.GetComponents <MonoBehaviour>();
                int             numBehaviors     = siblingBehaviors.Length;
                for (int behaviorIndex = 0; behaviorIndex < numBehaviors; ++behaviorIndex)
                {
                    MonoBehaviour behavior = siblingBehaviors[behaviorIndex];
                    if (behavior != this && behavior != cachedMember)
                    {
                        behavior.enabled = !siblingsDisabled;
                    }
                }
            }

            if ((CullSiblings & SiblinglFlags.Renderers) != 0)
            {
                Renderer[] siblingRenderers = gameObject.GetComponents <Renderer>();
                int        numRenderers     = siblingRenderers.Length;
                for (int rendererIndex = 0; rendererIndex < numRenderers; ++rendererIndex)
                {
                    siblingRenderers[rendererIndex].enabled = !siblingsDisabled;
                }
            }

            if ((CullSiblings & SiblinglFlags.Lights) != 0)
            {
                Light[] siblingLights = gameObject.GetComponents <Light>();
                int     numLights     = siblingLights.Length;
                for (int lightIndex = 0; lightIndex < numLights; ++lightIndex)
                {
                    siblingLights[lightIndex].enabled = !siblingsDisabled;
                }
            }

            if ((CullSiblings & SiblinglFlags.Colliders) != 0)
            {
                Collider[] siblingColliders = gameObject.GetComponents <Collider>();
                int        numColliders     = siblingColliders.Length;
                for (int colliderIndex = 0; colliderIndex < numColliders; ++colliderIndex)
                {
                    siblingColliders[colliderIndex].enabled = !siblingsDisabled;
                }
            }

            if ((CullSiblings & SiblinglFlags.RigidBodies) != 0)
            {
                Rigidbody[] siblingRBs = gameObject.GetComponents <Rigidbody>();
                int         numRBs     = siblingRBs.Length;
                for (int rbIndex = 0; rbIndex < numRBs; ++rbIndex)
                {
                    if (siblingsDisabled)
                    {
                        siblingRBs[rbIndex].Sleep();
                    }
                    else
                    {
                        siblingRBs[rbIndex].WakeUp();
                    }
                }
            }
        }

        cachedMember.ForceUpdate(true);
    }
    private void _SetupChunk()
    {
        _FindChunkRoot();
        if (chunkRoot)
        {
            // Activate the root if inactive (due to backwards compat or recentering
            if (!chunkRoot.activeSelf)
            {
                chunkRoot.SetActive(true);
            }

            // Recenter chunk under ourselves
            if (recenterChunk)
            {
                Transform chunkTransform = chunkRoot.transform;
                chunkTransform.localPosition = Vector3.zero;
                chunkTransform.localRotation = Quaternion.identity;
                chunkTransform.localScale    = Vector3.one;
            }

            // Hook up the child proxy
            SECTR_Member rootMember = chunkSector.GetComponent <SECTR_Member>();
            if (!rootMember)
            {
                rootMember = chunkSector.gameObject.AddComponent <SECTR_Member>();
                rootMember.BoundsUpdateMode = SECTR_Member.BoundsUpdateModes.Static;
                rootMember.ForceUpdate(true);
            }
            else if (recenterChunk)
            {
                rootMember.ForceUpdate(true);
            }
            cachedSector.ChildProxy = rootMember;

            // Unfreeze our sector
            cachedSector.Frozen = false;
            if (cachedSector.TopTerrain || cachedSector.BottomTerrain ||
                cachedSector.LeftTerrain || cachedSector.RightTerrain)
            {
                cachedSector.ConnectTerrainNeighbors();
                if (cachedSector.TopTerrain)
                {
                    cachedSector.TopTerrain.ConnectTerrainNeighbors();
                }
                if (cachedSector.BottomTerrain)
                {
                    cachedSector.BottomTerrain.ConnectTerrainNeighbors();
                }
                if (cachedSector.LeftTerrain)
                {
                    cachedSector.LeftTerrain.ConnectTerrainNeighbors();
                }
                if (cachedSector.RightTerrain)
                {
                    cachedSector.RightTerrain.ConnectTerrainNeighbors();
                }
            }

            // Remove the proxy if there is one
            if (proxy)
            {
                GameObject.Destroy(proxy);
            }

            loadState = LoadState.Active;
        }
    }