idk
This commit is contained in:
@@ -9,6 +9,7 @@ using Unity.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.Assertions;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using Logger = RebootKit.Engine.Foundation.Logger;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
@@ -21,14 +22,15 @@ namespace RebootKit.Engine.Simulation {
|
||||
|
||||
readonly NetworkSystem m_Network;
|
||||
|
||||
readonly List<Actor> m_InSceneActors = new List<Actor>();
|
||||
readonly List<Actor> m_SpawnedActors = new List<Actor>();
|
||||
internal readonly List<Actor> InSceneActors = new List<Actor>();
|
||||
internal readonly List<Actor> SpawnedActors = new List<Actor>();
|
||||
|
||||
// @NOTE: 0 is reserved for no actor so we should start assigning IDs from 1.
|
||||
ushort m_ActorIDCounter;
|
||||
List<ushort> m_ActorIDFreeList = new List<ushort>(ushort.MaxValue);
|
||||
|
||||
public ushort InSceneActorsCount { get { return (ushort) m_InSceneActors.Count; } }
|
||||
public ushort SpawnedActorsCount { get { return (ushort) m_SpawnedActors.Count; } }
|
||||
public ushort InSceneActorsCount { get { return (ushort) InSceneActors.Count; } }
|
||||
public ushort SpawnedActorsCount { get { return (ushort) SpawnedActors.Count; } }
|
||||
public int TotalActorsCount { get { return InSceneActorsCount + SpawnedActorsCount; } }
|
||||
|
||||
public ActorsManager(NetworkSystem networkSystem) {
|
||||
@@ -41,11 +43,11 @@ namespace RebootKit.Engine.Simulation {
|
||||
// @MARK: Update
|
||||
//
|
||||
public void Tick(float deltaTime) {
|
||||
foreach (Actor actor in m_InSceneActors) {
|
||||
foreach (Actor actor in InSceneActors) {
|
||||
actor.OnClientTick(deltaTime);
|
||||
}
|
||||
|
||||
foreach (Actor actor in m_SpawnedActors) {
|
||||
foreach (Actor actor in SpawnedActors) {
|
||||
actor.OnClientTick(deltaTime);
|
||||
}
|
||||
}
|
||||
@@ -58,8 +60,8 @@ namespace RebootKit.Engine.Simulation {
|
||||
return;
|
||||
}
|
||||
|
||||
TickActorsList(m_InSceneActors, dt);
|
||||
TickActorsList(m_SpawnedActors, dt);
|
||||
TickActorsList(InSceneActors, dt);
|
||||
TickActorsList(SpawnedActors, dt);
|
||||
}
|
||||
|
||||
void TickActorsList(List<Actor> actors, float deltaTime) {
|
||||
@@ -137,19 +139,14 @@ namespace RebootKit.Engine.Simulation {
|
||||
return null;
|
||||
}
|
||||
|
||||
GameObject actorObject = assetReference.InstantiateAsync(position, rotation).WaitForCompletion();
|
||||
Actor actor = actorObject.GetComponent<Actor>();
|
||||
if (actor is null) {
|
||||
s_Logger.Error($"GameObject {actorObject.name} does not have an Actor component.");
|
||||
Object.Destroy(actorObject);
|
||||
return null;
|
||||
}
|
||||
|
||||
actor.Manager = this;
|
||||
actor.SourceActorPath = assetReference.AssetGUID;
|
||||
actor.ActorID = actorID;
|
||||
actor.Data = actor.InternalCreateActorData();
|
||||
m_SpawnedActors.Add(actor);
|
||||
Actor actor = InstantiateActor(assetReference.AssetGUID,
|
||||
actorID,
|
||||
position,
|
||||
rotation,
|
||||
null,
|
||||
default);
|
||||
actor.IsLocalOnly = false;
|
||||
SpawnedActors.Add(actor);
|
||||
|
||||
foreach (NetworkClientState client in m_Network.Clients.Values) {
|
||||
if (client.IsServer) {
|
||||
@@ -166,6 +163,18 @@ namespace RebootKit.Engine.Simulation {
|
||||
}
|
||||
|
||||
bool TryGenerateNextActorID(out ushort actorID) {
|
||||
if (m_ActorIDFreeList.Count > 0) {
|
||||
actorID = m_ActorIDFreeList[0];
|
||||
m_ActorIDFreeList.RemoveAtSwapBack(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_ActorIDCounter >= ushort.MaxValue) {
|
||||
s_Logger.Error("Reached maximum number of actor ids which is: " + ushort.MaxValue);
|
||||
actorID = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_ActorIDCounter += 1;
|
||||
actorID = m_ActorIDCounter;
|
||||
return true;
|
||||
@@ -178,44 +187,42 @@ namespace RebootKit.Engine.Simulation {
|
||||
}
|
||||
|
||||
m_ActorIDCounter = 0;
|
||||
m_ActorIDFreeList.Clear();
|
||||
|
||||
foreach (Actor actor in m_InSceneActors) {
|
||||
foreach (Actor actor in InSceneActors) {
|
||||
if (!TryGenerateNextActorID(out ushort actorID)) {
|
||||
s_Logger.Error("Failed to generate actor ID. Probably reached the limit of 65535 actors.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
actor.ActorID = actorID;
|
||||
}
|
||||
}
|
||||
|
||||
public Actor SpawnLocalOnlyActor(AssetReferenceGameObject assetReference, Vector3 position, Quaternion rotation) {
|
||||
if (!assetReference.RuntimeKeyIsValid()) {
|
||||
s_Logger.Error("Trying to spawn an actor with an invalid asset reference.");
|
||||
return null;
|
||||
|
||||
public void DestroyActor(Actor actor) {
|
||||
if (actor.IsLocalOnly) {
|
||||
Object.Destroy(actor.gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryGenerateNextActorID(out ushort actorID)) {
|
||||
s_Logger.Error("Cannot spawn actor: Failed to generate next actor ID.");
|
||||
return null;
|
||||
if (!RR.IsServer()) {
|
||||
s_Logger.Error("Only the server can destroy non-local only actors");
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject actorObject = assetReference.InstantiateAsync(position, rotation).WaitForCompletion();
|
||||
Actor actor = actorObject.GetComponent<Actor>();
|
||||
if (actor is null) {
|
||||
s_Logger.Error($"GameObject {actorObject.name} does not have an Actor component.");
|
||||
Object.Destroy(actorObject);
|
||||
return null;
|
||||
if (InSceneActors.Contains(actor)) {
|
||||
s_Logger.Error("InScene actors cannot be destroyed!");
|
||||
return;
|
||||
}
|
||||
|
||||
actor.Manager = this;
|
||||
actor.IsLocalOnly = true;
|
||||
actor.SourceActorPath = assetReference.AssetGUID;
|
||||
actor.ActorID = actorID;
|
||||
actor.Data = actor.InternalCreateActorData();
|
||||
// m_SpawnedActors.Add(actor);
|
||||
for (int i = SpawnedActors.Count - 1; i >= 0; --i) {
|
||||
if (SpawnedActors[i] == actor) {
|
||||
m_ActorIDFreeList.Add(actor.ActorID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return actor;
|
||||
s_Logger.Error($"Failed to destroy an actor(name: {actor.ActorName}, id: {actor.ActorID})");
|
||||
}
|
||||
|
||||
//
|
||||
@@ -228,11 +235,11 @@ namespace RebootKit.Engine.Simulation {
|
||||
|
||||
actor.Manager = this;
|
||||
|
||||
m_InSceneActors.Add(actor);
|
||||
InSceneActors.Add(actor);
|
||||
}
|
||||
|
||||
Actor FindInSceneActorWithStaticID(ulong staticID) {
|
||||
foreach (Actor actor in m_InSceneActors) {
|
||||
foreach (Actor actor in InSceneActors) {
|
||||
if (actor.ActorStaticID == staticID) {
|
||||
return actor;
|
||||
}
|
||||
@@ -242,13 +249,13 @@ namespace RebootKit.Engine.Simulation {
|
||||
}
|
||||
|
||||
public Actor FindActorByID(ushort actorID) {
|
||||
foreach (Actor actor in m_InSceneActors) {
|
||||
foreach (Actor actor in InSceneActors) {
|
||||
if (actor.ActorID == actorID) {
|
||||
return actor;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Actor actor in m_SpawnedActors) {
|
||||
foreach (Actor actor in SpawnedActors) {
|
||||
if (actor.ActorID == actorID) {
|
||||
return actor;
|
||||
}
|
||||
@@ -258,15 +265,40 @@ namespace RebootKit.Engine.Simulation {
|
||||
}
|
||||
|
||||
public void CleanUp() {
|
||||
m_InSceneActors.Clear();
|
||||
InSceneActors.Clear();
|
||||
|
||||
foreach (Actor actor in m_SpawnedActors) {
|
||||
foreach (Actor actor in SpawnedActors) {
|
||||
if (actor.OrNull() != null) {
|
||||
Object.Destroy(actor.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
m_SpawnedActors.Clear();
|
||||
SpawnedActors.Clear();
|
||||
}
|
||||
|
||||
public Actor SpawnLocalOnlyActor(AssetReferenceGameObject assetReference, Vector3 position, Quaternion rotation) {
|
||||
if (!assetReference.RuntimeKeyIsValid()) {
|
||||
s_Logger.Error("Trying to spawn an actor with an invalid asset reference.");
|
||||
return null;
|
||||
}
|
||||
|
||||
AsyncOperationHandle<GameObject> handle = Addressables.InstantiateAsync(assetReference, position, rotation);
|
||||
GameObject actorObject = handle.WaitForCompletion();
|
||||
Actor actor = actorObject.GetComponent<Actor>();
|
||||
if (actor == null) {
|
||||
s_Logger.Error($"GameObject {actorObject.name} does not have an Actor component.");
|
||||
handle.Release();
|
||||
return null;
|
||||
}
|
||||
|
||||
actor.Manager = this;
|
||||
actor.AssetHandle = handle;
|
||||
actor.IsLocalOnly = true;
|
||||
actor.SourceActorPath = assetReference.AssetGUID;
|
||||
actor.ActorID = 0;
|
||||
actor.Data = actor.InternalCreateActorData();
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
||||
///
|
||||
@@ -355,50 +387,55 @@ namespace RebootKit.Engine.Simulation {
|
||||
return;
|
||||
}
|
||||
|
||||
SpawnLocalActor(assetGUID.ToString(),
|
||||
coreState,
|
||||
stateData);
|
||||
InstantiateActor(assetGUID.ToString(),
|
||||
coreState.ActorID,
|
||||
coreState.Position,
|
||||
coreState.Rotation,
|
||||
coreState,
|
||||
stateData);
|
||||
}
|
||||
|
||||
void SpawnLocalActor(string guid,
|
||||
ActorCoreStateSnapshot coreStateSnapshot,
|
||||
NativeSlice<byte> stateData) {
|
||||
Actor InstantiateActor(string guid,
|
||||
ushort actorID,
|
||||
Vector3 position,
|
||||
Quaternion rotation,
|
||||
ActorCoreStateSnapshot? coreStateSnapshot,
|
||||
NativeSlice<byte> stateData) {
|
||||
AssetReferenceGameObject assetReference = new AssetReferenceGameObject(guid);
|
||||
if (!assetReference.RuntimeKeyIsValid()) {
|
||||
s_Logger.Error($"Invalid asset reference for actor with GUID {guid}");
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
GameObject actorObject = assetReference
|
||||
.InstantiateAsync(coreStateSnapshot.Position, coreStateSnapshot.Rotation)
|
||||
.WaitForCompletion();
|
||||
if (actorObject == null) {
|
||||
s_Logger.Error($"Failed to instantiate actor with GUID {guid}");
|
||||
return;
|
||||
}
|
||||
AsyncOperationHandle<GameObject> handle = Addressables.InstantiateAsync(assetReference, position, rotation);
|
||||
GameObject actorObject = handle.WaitForCompletion();
|
||||
|
||||
Actor actor = actorObject.GetComponent<Actor>();
|
||||
if (actor is null) {
|
||||
if (actor == null) {
|
||||
s_Logger.Error($"GameObject {actorObject.name} does not have an Actor component.");
|
||||
Object.Destroy(actorObject);
|
||||
return;
|
||||
Addressables.ReleaseInstance(handle);
|
||||
return null;
|
||||
}
|
||||
|
||||
actor.Manager = this;
|
||||
actor.AssetHandle = handle;
|
||||
actor.SourceActorPath = guid;
|
||||
actor.ActorID = coreStateSnapshot.ActorID;
|
||||
actor.ActorID = actorID;
|
||||
actor.Data = actor.InternalCreateActorData();
|
||||
|
||||
if (!RR.IsServer()) {
|
||||
actor.InitializeOnClient();
|
||||
}
|
||||
|
||||
actor.RestoreCoreState(coreStateSnapshot);
|
||||
if (coreStateSnapshot.HasValue) {
|
||||
actor.RestoreCoreState(coreStateSnapshot.Value);
|
||||
}
|
||||
|
||||
if (stateData.Length > 0) {
|
||||
DataSerializationUtils.Deserialize(stateData, ref actor.Data);
|
||||
}
|
||||
|
||||
m_SpawnedActors.Add(actor);
|
||||
return actor;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -427,7 +464,7 @@ namespace RebootKit.Engine.Simulation {
|
||||
internal void WriteInSceneActorsStates(NetworkBufferWriter writer) {
|
||||
writer.Write((ushort) InSceneActorsCount);
|
||||
|
||||
foreach (Actor actor in m_InSceneActors) {
|
||||
foreach (Actor actor in InSceneActors) {
|
||||
writer.Write(actor.ActorStaticID);
|
||||
writer.Write(actor.ActorID);
|
||||
actor.GetCoreStateSnapshot().Serialize(writer);
|
||||
@@ -443,7 +480,7 @@ namespace RebootKit.Engine.Simulation {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
reader.Read(out ulong actorStaticID);
|
||||
reader.Read(out ushort actorID);
|
||||
|
||||
|
||||
s_Logger.Info($"Reading actor with StaticID {actorStaticID} and ID {actorID} during synchronization.");
|
||||
|
||||
Actor actor = FindInSceneActorWithStaticID(actorStaticID);
|
||||
@@ -467,8 +504,8 @@ namespace RebootKit.Engine.Simulation {
|
||||
actor.ActorID = actorID;
|
||||
s_Logger.Info("Actor id set to " + actor.ActorID);
|
||||
}
|
||||
|
||||
foreach (Actor inSceneActor in m_InSceneActors) {
|
||||
|
||||
foreach (Actor inSceneActor in InSceneActors) {
|
||||
s_Logger.Info($"InSceneActor: StaticID={inSceneActor.ActorStaticID}, ID={inSceneActor.ActorID}, Path={inSceneActor.SourceActorPath}");
|
||||
}
|
||||
|
||||
@@ -481,7 +518,7 @@ namespace RebootKit.Engine.Simulation {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (Actor actor in m_SpawnedActors) {
|
||||
foreach (Actor actor in SpawnedActors) {
|
||||
if (actor.OrNull() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user