using System.Threading; using Cysharp.Threading.Tasks; using RebootKit.Engine.Main; using RebootKit.Engine.Simulation; using UnityEngine; using Logger = RebootKit.Engine.Foundation.Logger; namespace RebootKit.Engine.Network { public abstract class NetworkPlayerController : MonoBehaviour { static readonly Logger s_Logger = new Logger(nameof(NetworkPlayerController)); ushort m_ActorIDToPossess; CancellationTokenSource m_PossessionCancellationTokenSource = new CancellationTokenSource(); public Actor PossessedActor { get; private set; } internal void SetPossessedActor(ushort actorID) { s_Logger.Info("Setting possessed actor to " + actorID); if (actorID == 0) { m_ActorIDToPossess = 0; if (PossessedActor != null) { PossessedActor = null; OnUnpossessActor(PossessedActor); } } else { m_PossessionCancellationTokenSource.Cancel(); m_PossessionCancellationTokenSource.Dispose(); m_PossessionCancellationTokenSource = new CancellationTokenSource(); WaitForActorToSpawnThenPossessAsync(actorID, m_PossessionCancellationTokenSource.Token).Forget(); } } async UniTask WaitForActorToSpawnThenPossessAsync(ushort actorID, CancellationToken cancellationToken) { Actor actor = null; while (actor == null) { actor = RR.FindSpawnedActor(actorID); await UniTask.WaitForSeconds(0.5f, cancellationToken: cancellationToken); if (cancellationToken.IsCancellationRequested) { return; } } PossessedActor = actor; OnPossessActor(actor); } protected virtual void OnPossessActor(Actor actor) { } protected virtual void OnUnpossessActor(Actor actor) { } } }