using System.Collections.Generic; using System.Threading; using Cysharp.Threading.Tasks; using RebootKit.Engine.Foundation; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.ResourceProviders; using UnityEngine.SceneManagement; namespace RebootKit.Engine.Services.Simulation { public class WorldService : IService { readonly List m_Actors = new(); WorldConfig m_Config; public void Dispose() { KillAllActors(); } public async UniTask Load(WorldConfig worldConfig) { m_Config = worldConfig; AsyncOperationHandle handle = worldConfig.mainScene.LoadSceneAsync(LoadSceneMode.Additive, false); await handle.ToUniTask(); await handle.Result.ActivateAsync(); SceneManager.SetActiveScene(handle.Result.Scene); foreach (GameObject root in handle.Result.Scene.GetRootGameObjects()) { foreach (Actor actor in root.GetComponentsInChildren()) { RegisterActor(actor); } } } public async UniTask SpawnActor(AssetReferenceT asset, CancellationToken cancellationToken) where TActor : Actor { GameObject gameObject = await Addressables.InstantiateAsync(asset); if (cancellationToken.IsCancellationRequested) { asset.ReleaseInstance(gameObject); return null; } if (gameObject.TryGetComponent(out TActor actor)) { return actor; } asset.ReleaseInstance(gameObject); return null; } public void RegisterActor(Actor actor) { m_Actors.Add(actor); } public void KillActor(Actor actor) { Addressables.ReleaseInstance(actor.gameObject); } public void KillAllActors() { foreach (Actor actor in m_Actors) { Addressables.ReleaseInstance(actor.gameObject); } m_Actors.Clear(); } } }