Files
RebootKit/Runtime/Engine/Code/Network/NetworkPlayerController.cs
2025-07-21 09:04:43 +02:00

81 lines
2.5 KiB
C#

using System;
using System.Threading;
using Cysharp.Threading.Tasks;
using RebootKit.Engine.Foundation;
using RebootKit.Engine.Main;
using RebootKit.Engine.Simulation;
using Unity.Netcode;
namespace RebootKit.Engine.Network {
public abstract class NetworkPlayerController : NetworkBehaviour {
static readonly Logger s_Logger = new Logger(nameof(NetworkPlayerController));
ulong m_ActorIDToPossess;
public Actor PossessedActor { get; private set; }
public void PossessActor(Actor actor) {
if (!IsServer) {
s_Logger.Error("PossessActor can only be called on the server.");
return;
}
if (actor == null) {
s_Logger.Error("Cannot possess a null actor.");
return;
}
PossessActorRpc(actor.ActorID, RpcTarget.Everyone);
}
[Rpc(SendTo.SpecifiedInParams)]
void PossessActorRpc(ulong actorID, RpcParams rpcParams) {
if (PossessedActor is not null) {
OnUnpossessActor(PossessedActor);
}
WaitForActorToSpawnThenPossessAsync(actorID, destroyCancellationToken).Forget();
}
async UniTask WaitForActorToSpawnThenPossessAsync(ulong 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);
}
public void UnPossessActor() {
if (!IsServer) {
s_Logger.Error("UnPossessActor can only be called on the server.");
return;
}
if (PossessedActor == null) {
return;
}
UnPossessActorRpc(RpcTarget.Everyone);
}
[Rpc(SendTo.SpecifiedInParams)]
void UnPossessActorRpc(RpcParams rpcParams) {
if (PossessedActor is not null) {
OnUnpossessActor(PossessedActor);
PossessedActor = null;
}
}
protected virtual void OnPossessActor(Actor actor) {
}
protected virtual void OnUnpossessActor(Actor actor) {
}
}
}