Skip to content

Instantly share code, notes, and snippets.

@FNGgames
Last active October 12, 2023 01:30
Show Gist options
  • Save FNGgames/9a82adc903fe959dfa566c5654b88ce1 to your computer and use it in GitHub Desktop.
Save FNGgames/9a82adc903fe959dfa566c5654b88ce1 to your computer and use it in GitHub Desktop.
Entitias Scene Initialization Example
public interface IApplicationService : IService
{
HashSet<string> GetValidScenes();
void Load(string sceneName, Action<string, float> onProgress, Action<string> onComplete);
void Unload(string sceneName, Action<string, float> onProgress, Action<string> onComplete);
void Quit();
}
public class UnityApplicationService : MonoBehaviour, IApplicationService
{
private Contexts _contexts;
private Scene _rootScene;
public void Initialize(Contexts contexts)
{
_contexts = contexts;
_rootScene = SceneManager.GetActiveScene();
}
public HashSet<string> GetValidScenes()
=> new HashSet<string>(SceneHelpers.GetLoadableSceneNames());
public void Load(string sceneName, Action<string, float> onProgress, Action<string> onComplete)
=> StartCoroutine(BeginLoadScene(sceneName, onProgress, onComplete));
public void Unload(string sceneName, Action<string, float> onProgress, Action<string> onComplete)
=> StartCoroutine(BeginUnloadScene(sceneName, onProgress, onComplete));
public void Quit() => Application.Quit();
private IEnumerator BeginLoadScene(string sceneName, Action<string, float> onProgress, Action<string> onComplete)
{
var unityName = "Scenes/" + sceneName;
var asyncLoad = SceneManager.LoadSceneAsync(unityName, LoadSceneMode.Additive);
asyncLoad.allowSceneActivation = false;
while (!asyncLoad.isDone)
{
if (asyncLoad.progress >= 0.9f && !asyncLoad.allowSceneActivation) asyncLoad.allowSceneActivation = true;
onProgress?.Invoke(sceneName, asyncLoad.progress);
yield return null;
}
var newScene = SceneManager.GetSceneByName(sceneName);
SceneManager.SetActiveScene(newScene);
yield return StartCoroutine(InitializeSceneCoroutine(newScene));
onComplete?.Invoke(sceneName);
}
private IEnumerator InitializeSceneCoroutine(Scene scene)
{
const int objectsPerFrame = 10;
var rootGameObjects = scene.GetRootGameObjects();
for(var i = 0; i < rootGameObjects.Length; i++)
{
if (!rootGameObjects[i].activeSelf) continue;
var view = rootGameObjects[i].GetComponent<UnityViewController>();
if (view != null) view.InitialiseView(_contexts, _contexts.game.CreateEntity());
if (i % objectsPerFrame == 0) yield return null;
}
}
private IEnumerator BeginUnloadScene(string name, Action<string, float> onProgress, Action<string> onComplete)
{
yield return null;
var unityName = "Scenes/" + name;
var asyncLoad = SceneManager.UnloadSceneAsync(unityName);
while (!asyncLoad.isDone)
{
onProgress?.Invoke(name, asyncLoad.progress);
yield return null;
}
SceneManager.SetActiveScene(_rootScene);
onComplete?.Invoke(name);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment