working on actors

This commit is contained in:
2025-07-03 05:52:25 +02:00
parent dca9f8883a
commit c39b87ed44
16 changed files with 975 additions and 165 deletions

View File

@@ -4,6 +4,7 @@ using Cysharp.Threading.Tasks;
using RebootKit.Engine.Foundation;
using RebootKit.Engine.Main;
using RebootKit.Engine.Services.Simulation;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Assertions;
@@ -27,14 +28,19 @@ namespace RebootKit.Engine.Simulation {
WorldState m_WorldState = WorldState.Unloaded;
WorldConfig m_Config;
AsyncOperationHandle<SceneInstance> m_SceneInstance;
enum ActorOrigin {
InScene,
Prefab
}
struct ActorData {
public ActorOrigin Origin;
public Actor Actor;
public readonly bool ManagedByAddressables;
public ActorData(Actor actor, bool managedByAddressables) {
public ActorData(ActorOrigin origin, Actor actor) {
Origin = origin;
Actor = actor;
ManagedByAddressables = managedByAddressables;
}
}
@@ -68,7 +74,9 @@ namespace RebootKit.Engine.Simulation {
await m_SceneInstance.Result.ActivateAsync();
SceneManager.SetActiveScene(m_SceneInstance.Result.Scene);
// await UniTask.WaitWhile(() => RR.CoreNetworkGameSystemsInstance is null, cancellationToken: cancellationToken);
foreach (GameObject root in m_SceneInstance.Result.Scene.GetRootGameObjects()) {
if (root.TryGetComponent(out IWorldContext worldContext)) {
Assert.IsNull(Context,
@@ -77,15 +85,11 @@ namespace RebootKit.Engine.Simulation {
}
foreach (Actor actor in root.GetComponentsInChildren<Actor>()) {
m_Actors.Add(new ActorData(actor, false));
RR.NetworkSystemInstance.Actors.RegisterInSceneActor(actor);
}
}
m_WorldState = WorldState.Loaded;
if (RR.GameInstance is not null) {
RR.GameInstance.OnWorldLoaded();
}
}
public void Unload() {
@@ -93,12 +97,10 @@ namespace RebootKit.Engine.Simulation {
return;
}
if (RR.GameInstance is not null) {
RR.GameInstance.OnWorldUnload();
if (RR.NetworkSystemInstance is not null) {
RR.NetworkSystemInstance.Actors.CleanUp();
}
KillAllActors();
if (m_SceneInstance.IsValid()) {
m_SceneInstance.Release();
m_SceneInstance = default;
@@ -107,79 +109,5 @@ namespace RebootKit.Engine.Simulation {
m_WorldState = WorldState.Unloaded;
Context = null;
}
public async UniTask<TActor> SpawnActor<TActor>(AssetReferenceT<GameObject> asset,
CancellationToken cancellationToken) where TActor : Actor {
if (m_WorldState != WorldState.Loaded) {
s_Logger.Error("World is not loaded. Cannot spawn actor.");
return null;
}
GameObject gameObject = await Addressables.InstantiateAsync(asset);
if (cancellationToken.IsCancellationRequested) {
asset.ReleaseInstance(gameObject);
return null;
}
if (gameObject.TryGetComponent(out TActor actor)) {
actor.OnSpawned();
actor.IsPlaying = true;
m_Actors.Add(new ActorData(actor, true));
return actor;
}
asset.ReleaseInstance(gameObject);
return null;
}
public void KillActor(Actor actor) {
ActorData actorData = default;
bool found = false;
for (int i = m_Actors.Count - 1; i >= 0; i--) {
if (m_Actors[i].Actor == actor) {
found = true;
actorData = m_Actors[i];
m_Actors.RemoveAt(i);
break;
}
}
Assert.IsTrue(found, $"Actor {actor.name} not found in the world actors list.");
actor.IsPlaying = false;
actor.OnDespawned();
if (actorData.ManagedByAddressables) {
Addressables.ReleaseInstance(actor.gameObject);
}
}
public void KillAllActors() {
foreach (ActorData actorData in m_Actors) {
actorData.Actor.IsPlaying = false;
actorData.Actor.OnDespawned();
if (actorData.ManagedByAddressables) {
Addressables.ReleaseInstance(actorData.Actor.gameObject);
} else {
UnityEngine.Object.Destroy(actorData.Actor.gameObject);
}
}
m_Actors.Clear();
}
public void Tick(float deltaTime) {
if (m_WorldState != WorldState.Loaded) {
return;
}
foreach (ActorData actorData in m_Actors) {
Actor actor = actorData.Actor;
if (actor.IsPlaying) {
actor.Tick(deltaTime);
}
}
}
}
}