Files
KopMap/Assets/NatureManufacture Assets/WorldStreamer/Scritps/Streamer.cs
2025-09-02 18:55:19 +08:00

1053 lines
37 KiB
C#

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Linq;
using UnityEngine.SceneManagement;
#if AT_STREAMER2
using Atavism;
#endif
namespace WorldStreamer2
{
/// <summary>
/// Streams async scene tiles
/// </summary
#if AT_STREAMER2
public class Streamer : AtavismStreamer
#else
public class Streamer : MonoBehaviour
#endif
{
/// <summary>
/// Activates/deactivates streamer.
/// </summary>
[Tooltip("This checkbox deactivates streamer and unload or doesn't load it's data.")]
public bool streamerActive = true;
/// <summary>
/// The streamer tag.
/// </summary>
public static string STREAMERTAG = "SceneStreamer";
// [HideInInspector]
[Tooltip("Drag and drop here your scene collection prefab. You could find it in catalogue with scenes which were generated by scene splitter.")]
/// <summary>
/// The scene collection of tiles.
/// </summary>
public List<SceneCollectionManager> sceneCollectionManagers;
[Header("Settings")] [Tooltip("Frequancy in seconds in which you want to check if grid element is close /far enough to load/unload.")]
/// <summary>
/// How often streamer checks player position.
/// </summary>
public float positionCheckTime = 0.1f;
[Tooltip("Time in seconds after which grid element will be unloaded.")]
/// <summary>
/// Destroys unloaded tiles after seconds.
/// </summary>
public float destroyTileDelay = 2;
[Tooltip("Number of empty frames between loading actions.")]
/// <summary>
/// The async scene load wait frames.
/// </summary>
public int sceneLoadWaitFrames = 2;
[Space(10)] [Tooltip("If you want to fix small holes from LODs system at unity terrain borders, drag and drop object here from scene hierarchy that contains our \"Terrain Neighbours\" script.")]
/// <summary>
/// The terrain neighbours manager.
/// </summary>
public TerrainNeighbours terrainNeighbours;
[Space(10)] [Tooltip("Enable looping system, each layer is streamed independently, so if you want to synchronize them, they should have the same XYZ size. More info at manual.")]
/// <summary>
/// Is world looping on.
/// </summary>
public bool looping = false;
/// <summary>
/// Override scene split range limit
/// </summary>
public bool overideRangeLimit = true;
/// <summary>
/// Override scene limits in scene collections
/// </summary>
public bool overideScenesLimits = true;
[Space(10)]
[Header("Player Settings")]
[Tooltip("Drag and drop here, an object that system have to follow during streaming process.")]
/// <summary>
/// The player transform.
/// </summary>
[SerializeField]
private Transform _player;
public Transform player
{
get
{
if (spawnedPlayer && _player == null && !string.IsNullOrEmpty(playerTag))
{
GameObject playerGO = GameObject.FindGameObjectWithTag(playerTag);
if (playerGO != null)
_player = playerGO.transform;
}
return _player;
}
set => _player = value;
}
[Tooltip("Streamer will wait for player spawn and fill it automatically")]
/// <summary>
/// Streamer will wait for player spawn and fill it automatically
/// </summary>
public bool spawnedPlayer;
[HideInInspector] public string playerTag = "Player";
[HideInInspector]
/// <summary>
/// The show loading screen on start?
/// </summary>
public bool showLoadingScreen = true;
[HideInInspector]
/// <summary>
/// The loading screen UI.
/// </summary>
public UILoadingStreamer loadingStreamer;
[HideInInspector] public bool initialized = false;
[HideInInspector]
/// <summary>
/// The tiles to load.
/// </summary>
public int tilesToLoad = int.MaxValue;
[HideInInspector]
/// <summary>
/// The tiles loaded.
/// </summary>
public int tilesLoaded;
/// <summary>
/// Gets the loading progress.
/// </summary>
/// <value>The loading progress.</value>
public float LoadingProgress
{
get { return (tilesToLoad > 0) ? tilesLoaded / (float)tilesToLoad : 1; }
}
/// <summary>
/// The world mover.
/// </summary>
[HideInInspector] public WorldMover
worldMover;
[HideInInspector]
/// <summary>
/// The current move.
/// </summary>
public Vector3 currentMove = Vector3.zero;
[HideInInspector] public bool xLimitsOverrideIs = false;
[HideInInspector] public bool yLimitsOverrideIs = false;
[HideInInspector] public bool zLimitsOverrideIs = false;
[HideInInspector] public Vector2Int xLimitsOverride = new Vector2Int(-100000, 100000);
[HideInInspector] public Vector2Int yLimitsOverride = new Vector2Int(-100000, 100000);
[HideInInspector] public Vector2Int zLimitsOverride = new Vector2Int(-100000, 100000);
/// <summary>
/// The scenes to load.
/// </summary>
List<SceneSplit> scenesToLoad = new List<SceneSplit>();
/// <summary>
/// The scene load frame next.
/// </summary>
int sceneLoadFrameNext = 0;
/// <summary>
/// The scene load frames next waited.
/// </summary>
bool sceneLoadFramesNextWaited = false;
public static StreamerLoadingManager loadingManager;
static bool canUnload = true;
static float waitTillNextUnload = 20;
static bool unloadNext = false;
/// <summary>
/// Awakes this instance and resets player position;
/// </summary>
void Awake()
{
//if (spawnedPlayer)
//{
// player = null;
//}
#if AT_STREAMER2
if (ClientAPI.GetPlayerObject() != null)
{
GameObject go = ClientAPI.GetPlayerObject().GameObject;
if (go != null)
player = go.transform;
}
#endif
foreach (var sceneCollectionManager in sceneCollectionManagers)
{
sceneCollectionManager.ResetPosition();
}
}
/// <summary>
/// Start this instance, prepares scene collection into scene array, starts player position checker
/// </summary>
void Start()
{
Debug.Log($"loadingManager {loadingManager}");
if (loadingManager != null)
Debug.Log($"loadingManager streamer {loadingManager.Streamer}");
loadingManager = new StreamerLoadingManager() { Streamer = this };
Debug.Log($"New streamer loading manager {loadingManager.Streamer}");
if (sceneCollectionManagers != null && sceneCollectionManagers.Count > 0)
{
PrepareScenesArray();
StartCoroutine(PositionChecker());
canUnload = true;
}
/*else
{
enabled = false;
Debug.LogError("No scene collection in streamer");
}*/
}
#region prepare scene
/// <summary>
/// Prepares the scenes array from collection
/// </summary>
void PrepareScenesArray()
{
Vector2Int xLimits = Vector2Int.zero;
Vector2Int yLimits = Vector2Int.zero;
Vector2Int zLimits = Vector2Int.zero;
if (sceneCollectionManagers.Count > 1)
{
sceneCollectionManagers[0].GetSceneCollectionWolrdLimits(out xLimits, out yLimits, out zLimits);
}
if (xLimitsOverrideIs)
{
xLimits = xLimitsOverride;
}
if (yLimitsOverrideIs)
{
yLimits = yLimitsOverride;
}
if (zLimitsOverrideIs)
{
zLimits = zLimitsOverride;
}
Debug.Log(xLimits + " " + yLimits + " " + zLimits);
foreach (var sceneCollectionManager in sceneCollectionManagers)
{
sceneCollectionManager.unloadRangeConnectParent = null;
}
foreach (var sceneCollectionManager in sceneCollectionManagers)
{
if (sceneCollectionManager.useUnloadRangeConnect && sceneCollectionManager.unloadRangeConnect != null)
{
sceneCollectionManager.unloadRangeConnect.unloadRangeConnectParent = sceneCollectionManager;
}
if (overideScenesLimits && sceneCollectionManagers.Count > 1)
{
sceneCollectionManager.CalculateLoadingLimits(looping, looping && overideRangeLimit, looping && overideScenesLimits, xLimits, yLimits, zLimits);
sceneCollectionManager.PrepareScenesArray(overideRangeLimit, overideScenesLimits, xLimits, yLimits, zLimits);
}
else
{
sceneCollectionManager.CalculateLoadingLimits(looping, looping && overideRangeLimit);
sceneCollectionManager.PrepareScenesArray(looping && overideRangeLimit);
}
}
}
/// <summary>
/// Converts scene name into position
/// </summary>
/// <param name="sceneName">Scene name.</param>
/// <param name="posX">Position x.</param>
/// <param name="posY">Position y.</param>
/// <param name="posZ">Position z.</param>
public static void SceneNameToPos(SceneCollectionManager sceneCollectionManager, string sceneName, out int posX, out int posY, out int posZ)
{
posX = 0;
posY = 0;
posZ = 0;
string[] values = sceneName.Replace(sceneCollectionManager.prefixScene, "").Replace(".unity", "").Split(new char[]
{
'_'
}, System.StringSplitOptions.RemoveEmptyEntries);
foreach (var item in values)
{
if (item[0] == 'x')
{
posX = int.Parse(item.Replace("x", ""));
}
if (item[0] == 'y')
{
posY = int.Parse(item.Replace("y", ""));
}
if (item[0] == 'z')
{
posZ = int.Parse(item.Replace("z", ""));
}
}
}
#endregion
public static int mod(int x, int m)
{
return (x % m + m) % m;
}
#region scene loading
// called second
public void OnSceneLoaded(Scene scene, SceneSplit split)
{
GameObject[] rootGameObjects = scene.GetRootGameObjects();
if (rootGameObjects.Length > 0)
{
AddSceneGoMin(split, rootGameObjects[0]);
}
}
public void AddSceneGoMin(SceneSplit split, GameObject sceneGo)
{
SceneCollectionManager sceneCollectionManager = split.sceneCollectionManager;
int posX = 0;
int posY = 0;
int posZ = 0;
SceneNameToPos(split.sceneCollectionManager, split.sceneName, out posX, out posY, out posZ);
Vector3Int posInt = new Vector3Int(posX, posY, posZ);
SceneSplitManager sceneSplitManager = sceneGo.GetComponent<SceneSplitManager>();
tilesLoaded++;
float x = split.posX - posInt.x;
float y = split.posY - posInt.y;
float z = split.posZ - posInt.z;
Vector3 posSplit = new Vector3(sceneCollectionManager.xSize * x, sceneCollectionManager.ySize * y, sceneCollectionManager.zSize * z) + currentMove +
new Vector3(split.posXLimitMove, split.posYLimitMove, split.posZLimitMove);
if (split.sceneGo != null)
{
Debug.Log("Scene already loaded " + split.sceneName);
//return;
}
// Debug.Log("Added " + posInt + " " + posIntMoved);
BaseSplitSetup(split, sceneGo);
sceneGo.transform.position = posSplit;
sceneGo.name += $"split loaded on pos {posInt.x} {posInt.y} {posInt.z}";
SceneCollectionManager unloadSceneCollectionManager = null;
if (sceneCollectionManager.useUnloadRangeConnect && sceneCollectionManager.unloadRangeConnect != null)
{
unloadSceneCollectionManager = sceneCollectionManager.unloadRangeConnect;
}
if (sceneCollectionManager.unloadRangeConnectParent != null && sceneCollectionManager.unloadRangeConnectParent.useUnloadRangeConnect)
{
unloadSceneCollectionManager = sceneCollectionManager.unloadRangeConnectParent;
}
if (unloadSceneCollectionManager != null)
{
SceneSplit splitCheck;
float count = unloadSceneCollectionManager.loadedScenes.Count;
for (int i = 0; i < count; i++)
{
splitCheck = unloadSceneCollectionManager.loadedScenes[i];
if (splitCheck.loadingFinished)
{
if (split.basePosX == splitCheck.basePosX && split.basePosY == splitCheck.basePosY && split.basePosZ == splitCheck.basePosZ)
{
if (posSplit == splitCheck.sceneGo.transform.position)
{
//Debug.Log("----Unloaded " + split.sceneName);
UnloadScenesSync(splitCheck);
break;
}
}
}
}
}
}
public static void BaseSplitSetup(SceneSplit split, GameObject sceneGo)
{
split.sceneGo = sceneGo;
split.scene = sceneGo.scene;
split.loadingFinished = true;
split.sceneCollectionManager.currentlySceneLoading--;
}
#endregion
#region update functions
/// <summary>
/// Update this instance, starts load level async
/// </summary>
void Update()
{
LoadLevelAsyncManage();
loadingManager.Update();
}
/// <summary>
/// Manages async scene loading
/// </summary>
void LoadLevelAsyncManage()
{
//Debug.Log("--------------------------------" + scenesToLoad.Count);
if (scenesToLoad.Count > 0)
{
if (LoadingProgress < 1 || sceneLoadFramesNextWaited && sceneLoadFrameNext <= 0)
{
//Debug.Log(LoadingProgress);
sceneLoadFramesNextWaited = false;
sceneLoadFrameNext = sceneLoadWaitFrames;
scenesToLoad = scenesToLoad.OrderBy(x => x.sceneCollectionManager.priority).ToList();
int i = 0;
while (scenesToLoad.Count > 0 && i < scenesToLoad.Count)
{
SceneSplit split = scenesToLoad[i];
if (split.sceneCollectionManager.currentlySceneLoading < split.sceneCollectionManager.maxParallelSceneLoading)
{
//Debug.Log(split.sceneName);
scenesToLoad.Remove(split);
split.sceneCollectionManager.currentlySceneLoading++;
loadingManager.LoadSceneAsync(split);
i--;
}
i++;
}
}
else
{
sceneLoadFramesNextWaited = true;
sceneLoadFrameNext--;
}
}
}
/// <summary>
/// Coroutine checks player position
/// </summary>
/// <returns>The checker.</returns>
IEnumerator PositionChecker()
{
yield return new WaitForSeconds(positionCheckTime);
while (true)
{
if (spawnedPlayer && player == null && !string.IsNullOrEmpty(playerTag))
{
GameObject playerGO = GameObject.FindGameObjectWithTag(playerTag);
#if AT_STREAMER2
if(ClientAPI.GetPlayerObject() != null && playerGO==null)
playerGO = ClientAPI.GetPlayerObject().GameObject;
#endif
if (playerGO != null)
player = playerGO.transform;
}
if (streamerActive && player != null)
{
CheckPositionTiles();
}
else
{
#if !AT_STREAMER2
bool loadedScenes = false;
foreach (var sceneCollectionManager in sceneCollectionManagers)
{
if (sceneCollectionManager.loadedScenes.Count > 0)
{
loadedScenes = true;
sceneCollectionManager.ResetPosition();
}
}
if (loadedScenes)
UnloadAllScenes();
#endif
}
yield return new WaitForSeconds(positionCheckTime);
}
}
/// <summary>
/// Checks the position of player in tiles.
/// </summary>
public void CheckPositionTiles()
{
Vector3 pos = player.position;
pos -= currentMove;
bool changed = false;
foreach (var sceneCollectionManager in sceneCollectionManagers)
{
if (sceneCollectionManager.CheckPosition(pos))
changed = true;
}
if (changed)
{
SceneLoading();
Invoke(nameof(SceneUnloading), destroyTileDelay);
if (worldMover != null)
{
worldMover.CheckMoverDistance(sceneCollectionManagers[0].xPos, sceneCollectionManagers[0].yPos, sceneCollectionManagers[0].zPos);
}
}
}
#endregion
#region loading and unloading
/// <summary>
/// Loads tiles in range
/// </summary>
void SceneLoading()
{
//show splash screen
if (showLoadingScreen && loadingStreamer != null)
{
showLoadingScreen = false;
if (tilesLoaded >= tilesToLoad)
{
tilesToLoad = int.MaxValue;
tilesLoaded = 0;
}
}
int tilesToLoadNew = 0;
int count = 0;
foreach (var scm in sceneCollectionManagers)
{
if (!scm.active)
{
continue;
}
int x = scm.xPos;
int y = scm.yPos;
int z = scm.zPos;
int LoadingRangeX = (int)scm.loadingRange.x * 2 + 1;
int LoadingRangeZ = (int)scm.loadingRange.z * 2 + 1;
int xs = 0, zs = 0, dx = 0, dy = -1;
int t = Math.Max(LoadingRangeX, LoadingRangeZ);
int maxI = t * t;
//Debug.Log(LoadingRangeX);
//Debug.Log(LoadingRangeZ);
SceneSplit split;
for (int i = 0; i < maxI; i++)
{
if ((-LoadingRangeX / 2 <= xs) && (xs <= LoadingRangeX / 2) && (-LoadingRangeZ / 2 <= zs) && (zs <= LoadingRangeZ / 2))
{
for (int ys = 0; ys <= scm.loadingRange.y; ys++)
{
for (int yi = -1; yi <= 1; yi += 2)
{
if (ys == 0 && yi != -1)
continue;
count++;
if (scm.useLoadingRangeMin)
if (xs >= -scm.loadingRangeMin.x && xs <= scm.loadingRangeMin.x &&
ys >= -scm.loadingRangeMin.y && ys <= scm.loadingRangeMin.y &&
zs >= -scm.loadingRangeMin.z && zs <= scm.loadingRangeMin.z)
{
continue;
}
x = xs + scm.xPos;
y = ys * yi + scm.yPos;
z = zs + scm.zPos;
Vector3Int sceneID = new Vector3Int(x, y, z);
//Debug.Log(sceneID);
float xMoveLimit = 0;
int xDeloadLimit = 0;
float yMoveLimit = 0;
int yDeloadLimit = 0;
float zMoveLimit = 0;
int zDeloadLimit = 0;
//set scene possition according to looping
if (looping)
{
if (scm.xSplitIs)
{
int xFinal = mod((x + Mathf.Abs(scm.xLoadingLimitx)), scm.xLoadingRange) + scm.xLoadingLimitx;
xDeloadLimit = (int)Math.Ceiling((x - scm.xLoadingLimity) / (float)scm.xLoadingRange) * scm.xLoadingRange;
xMoveLimit = xDeloadLimit * scm.xSize;
sceneID[0] = xFinal;
}
if (scm.ySplitIs)
{
int yFinal = mod((y + Mathf.Abs(scm.yLoadingLimitx)), scm.yLoadingRange) + scm.yLoadingLimitx;
yDeloadLimit = (int)Math.Ceiling((y - scm.yLoadingLimity) / (float)scm.yLoadingRange) * scm.yLoadingRange;
yMoveLimit = yDeloadLimit * scm.ySize;
sceneID[1] = yFinal;
}
if (scm.zSplitIs)
{
int zFinal = mod((z + Mathf.Abs(scm.zLoadingLimitx)), scm.zLoadingRange) + scm.zLoadingLimitx;
zDeloadLimit = (int)Math.Ceiling((z - scm.zLoadingLimity) / (float)scm.zLoadingRange) * scm.zLoadingRange;
zMoveLimit = zDeloadLimit * scm.zSize;
sceneID[2] = zFinal;
}
}
//Debug.Log(sceneID[0] + " " + sceneID[1] + " " + sceneID[2]);
//load scene if scene array contains it and set up scene offset position according to looping
if (scm.scenesArray.TryGetValue(sceneID, out split))
{
// Debug.Log(sceneID[0] + " " + sceneID[1] + " " + sceneID[2]);
if (!split.loaded)
{
split.loaded = true;
split.posXLimitMove = xMoveLimit;
split.xDeloadLimit = xDeloadLimit;
split.posYLimitMove = yMoveLimit;
split.yDeloadLimit = yDeloadLimit;
split.posZLimitMove = zMoveLimit;
split.zDeloadLimit = zDeloadLimit;
scenesToLoad.Add(split);
scm.loadedScenes.Add(split);
tilesToLoadNew++;
}
}
else
{
//Debug.Log(scm.name+ " no scene id " + sceneID);
}
}
}
}
if ((xs == zs) || ((xs < 0) && (xs == -zs)) || ((xs > 0) && (xs == 1 - zs)))
{
t = dx;
dx = -dy;
dy = t;
}
xs += dx;
zs += dy;
}
}
tilesToLoad = tilesToLoadNew;
initialized = true;
}
/// <summary>
/// Unloads tiles out of range
/// </summary>
void SceneUnloading()
{
List<SceneSplit> scenesToDestroy = new List<SceneSplit>();
SceneSplit splitCheck;
float count;
foreach (var scm in sceneCollectionManagers)
{
count = scm.loadedScenes.Count;
for (int i = 0; i < count; i++)
{
splitCheck = scm.loadedScenes[i];
if (!scm.active)
{
scenesToDestroy.Add(splitCheck);
continue;
}
if (scm.unloadRangeConnectParent != null)
{
SceneCollectionManager connectedScm = scm.unloadRangeConnectParent;
//Debug.Log($"unloadRangeConnectParent {splitCheck.sceneName} {splitCheck.sceneGo.name} {splitCheck.sceneGo.scene.name}");
//Debug.Log(Mathf.Abs(splitCheck.posX + splitCheck.xDeloadLimit - scm.xPos) > scm.deloadingRange.x);
if ((Mathf.Abs(splitCheck.posX + splitCheck.xDeloadLimit - scm.xPos) > scm.deloadingRange.x ||
Mathf.Abs(splitCheck.posY + splitCheck.yDeloadLimit - scm.yPos) > scm.deloadingRange.y ||
Mathf.Abs(splitCheck.posZ + splitCheck.zDeloadLimit - scm.zPos) > scm.deloadingRange.z) &&
(Mathf.Abs(splitCheck.posX + splitCheck.xDeloadLimit - scm.xPos) > connectedScm.deloadingRange.x ||
Mathf.Abs(splitCheck.posY + splitCheck.yDeloadLimit - scm.yPos) > connectedScm.deloadingRange.y ||
Mathf.Abs(splitCheck.posZ + splitCheck.zDeloadLimit - scm.zPos) > connectedScm.deloadingRange.z))
if (splitCheck.sceneGo != null)
{
//Debug.Log($"split {splitCheck.sceneName} {splitCheck.sceneGo.name} {splitCheck.sceneGo.scene.name}");
scenesToDestroy.Add(splitCheck);
}
continue;
}
if (Mathf.Abs(splitCheck.posX + splitCheck.xDeloadLimit - scm.xPos) > (int)scm.deloadingRange.x
|| Mathf.Abs(splitCheck.posY + splitCheck.yDeloadLimit - scm.yPos) > (int)scm.deloadingRange.y
|| Mathf.Abs(splitCheck.posZ + splitCheck.zDeloadLimit - scm.zPos) > (int)scm.deloadingRange.z)
if (splitCheck.sceneGo != null)
{
// Debug.Log($"splitCheck.sceneName {splitCheck.sceneName} {splitCheck.sceneGo.name} {splitCheck.sceneGo.scene.name} base");
scenesToDestroy.Add(splitCheck);
}
if (scm.useLoadingRangeMin && !scm.useUnloadRangeConnect)
{
//Debug.Log($"splitCheck.sceneName {splitCheck.sceneName} {splitCheck.sceneGo.name} {splitCheck.sceneGo.scene.name} !useUnloadRangeConnect");
if (Mathf.Abs(splitCheck.posX + splitCheck.xDeloadLimit - scm.xPos) <= scm.loadingRangeMin.x &&
Mathf.Abs(splitCheck.posY + splitCheck.yDeloadLimit - scm.yPos) <= scm.loadingRangeMin.y &&
Mathf.Abs(splitCheck.posZ + splitCheck.zDeloadLimit - scm.zPos) <= scm.loadingRangeMin.z)
if (splitCheck.sceneGo != null)
{
//Debug.Log($"splitCheck.sceneName {splitCheck.sceneName} {splitCheck.sceneGo.name} {splitCheck.sceneGo.scene.name} useUnloadRangeConnect");
scenesToDestroy.Add(splitCheck);
}
}
}
}
UnloadScenes(scenesToDestroy);
scenesToDestroy.Clear();
Streamer.UnloadAssets(this);
}
private void UnloadScenesSync(SceneSplit item)
{
if (item.sceneGo != null)
{
Terrain childTerrain = item.sceneGo.GetComponentInChildren<Terrain>();
if (childTerrain)
{
GameObject childTerrainGo = childTerrain.gameObject;
Destroy(childTerrain);
childTerrain = null;
Destroy(childTerrainGo);
childTerrainGo = null;
}
}
item.loaded = false;
item.loadingFinished = false;
item.sceneCollectionManager.loadedScenes.Remove(item);
item.sceneGo = null;
loadingManager.UnloadSplitAsync(item);
}
private void UnloadScenes(List<SceneSplit> scenesToDestroy)
{
foreach (var item in scenesToDestroy)
{
item.loaded = false;
item.loadingFinished = false;
item.sceneCollectionManager.loadedScenes.Remove(item);
item.sceneGo = null;
#if AT_STREAMER2
tilesLoaded--;
#endif
loadingManager.UnloadSplitAsync(item);
}
if (terrainNeighbours)
terrainNeighbours.CreateNeighbours();
}
/// <summary>
/// Unloads all tiles of streamer
/// </summary>
public void UnloadAllScenes()
{
Debug.Log("UnloadAllScenes start");
foreach (var sceneCollectionManager in sceneCollectionManagers)
{
foreach (var item in sceneCollectionManager.scenesArray)
{
if (item.Value.sceneGo != null)
{
//Terrain childTerrain = item.Value.sceneGo.GetComponentInChildren<Terrain>();
//if (childTerrain)
//{
// GameObject childTerrainGO = childTerrain.gameObject;
// Destroy(childTerrain);
// childTerrain = null;
// Destroy(childTerrainGO);
// childTerrainGO = null;
//}
try
{
loadingManager.UnloadSplitAsync(item.Value);
}
catch (System.Exception ex)
{
Debug.Log(item.Value.sceneName);
Debug.Log(item.Value.sceneGo.name);
Debug.Log(item.Value.sceneGo.scene.name);
Debug.LogError(ex.Message);
}
}
item.Value.loaded = false;
item.Value.loadingFinished = false;
item.Value.sceneGo = null;
}
sceneCollectionManager.loadedScenes.Clear();
}
if (terrainNeighbours)
terrainNeighbours.CreateNeighbours();
Streamer.UnloadAssets(this);
Debug.Log("UnloadAllScenes finish");
}
public static void UnloadAssets(Streamer streamer)
{
if (Streamer.canUnload)
{
Streamer.canUnload = false;
streamer.StartCoroutine(streamer.UnloadAssetsWait());
}
else
unloadNext = true;
}
public IEnumerator UnloadAssetsWait()
{
do
{
unloadNext = false;
//Debug.Log("Resources.UnloadUnusedAssets");
Resources.UnloadUnusedAssets();
yield return new WaitForSeconds(waitTillNextUnload);
} while (unloadNext);
canUnload = true;
}
#endregion
//// called first
//void OnEnable()
//{
// SceneManager.sceneLoaded += OnSceneLoaded;
//}
//void OnDisable()
//{
// SceneManager.sceneLoaded -= OnSceneLoaded;
//}
void OnDrawGizmosSelected()
{
if (sceneCollectionManagers == null)
return;
Vector3 size = Vector3.zero;
Vector3 position = Vector3.zero;
Vector3Int loadingRange = Vector3Int.zero;
foreach (var scm in sceneCollectionManagers)
{
if (scm && scm.showDebug && scm.active)
{
Gizmos.color = scm.color;
size.x = scm.xSize == 0 ? 2 : scm.xSize;
size.y = scm.ySize == 0 ? 2 : scm.ySize;
size.z = scm.zSize == 0 ? 2 : scm.zSize;
loadingRange.x = !scm.xSplitIs ? 0 : scm.loadingRange.x;
loadingRange.y = !scm.ySplitIs ? 0 : scm.loadingRange.y;
loadingRange.z = !scm.zSplitIs ? 0 : scm.loadingRange.z;
for (int x = -(int)loadingRange.x + scm.xPos; x <= (int)loadingRange.x + scm.xPos; x++)
{
for (int y = -(int)loadingRange.y + scm.yPos; y <= (int)loadingRange.y + scm.yPos; y++)
{
for (int z = -(int)loadingRange.z + scm.zPos; z <= (int)loadingRange.z + scm.zPos; z++)
{
if (scm.useLoadingRangeMin && x - scm.xPos >= -scm.loadingRangeMin.x && x - scm.xPos <= scm.loadingRangeMin.x &&
y - scm.yPos >= -scm.loadingRangeMin.y && y - scm.yPos <= scm.loadingRangeMin.y &&
z - scm.zPos >= -scm.loadingRangeMin.z && z - scm.zPos <= scm.loadingRangeMin.z)
{
continue;
}
else
{
if (Application.isPlaying)
{
position.x = x * size.x;
position.y = y * size.y;
position.z = z * size.z;
}
else
{
position.x = (x - scm.xPos) * size.x;
position.y = (y - scm.yPos) * size.y;
position.z = (z - scm.zPos) * size.z;
}
Gizmos.DrawWireCube(position + size * 0.5f + currentMove, size);
}
}
}
}
Gizmos.color = Color.green;
if (Application.isPlaying)
Gizmos.DrawWireCube(new Vector3(scm.xPos * size.x, scm.yPos * size.y, scm.zPos * size.z) + size * 0.5f + currentMove, size);
else
Gizmos.DrawWireCube(size * 0.5f, size);
}
}
}
#if AT_STREAMER2
public override int GetTilesToLoad()
{
return tilesToLoad;
}
public override int GetTilesLoaded()
{
return tilesLoaded;
}
public override float GetLoadingProgress()
{
return (tilesToLoad > 0) ? tilesLoaded / (float)tilesToLoad : 1;
}
#endif
}
}