world object link: further improve, implement for raft

This commit is contained in:
JohnCorby 2022-03-14 01:22:50 -07:00
parent 24cc63012a
commit 06c6ae179b
10 changed files with 50 additions and 41 deletions

View File

@ -21,8 +21,8 @@ public class RaftPatches : QSBPatch
__instance._interactReceiver.SetInteractionEnabled(false);
var qsbRaft = __instance.GetWorldObject<QSBRaft>();
qsbRaft.TransformSync.netIdentity.UpdateAuthQueue(AuthQueueAction.Force);
Delay.RunWhen(() => qsbRaft.TransformSync.hasAuthority, () =>
qsbRaft.NetworkBehaviour.netIdentity.UpdateAuthQueue(AuthQueueAction.Force);
Delay.RunWhen(() => qsbRaft.NetworkBehaviour.hasAuthority, () =>
{
var normalized = Vector3.ProjectOnPlane(Locator.GetPlayerCamera().transform.forward, __instance.transform.up).normalized;
__instance._raftBody.AddVelocityChange(normalized * 5f);

View File

@ -2,23 +2,22 @@
using QSB.EchoesOfTheEye.RaftSync.WorldObjects;
using QSB.Syncs.Unsectored.Rigidbodies;
using QSB.Utility;
using QSB.Utility.LinkedWorldObject;
using QSB.WorldSync;
using System.Collections.Generic;
namespace QSB.EchoesOfTheEye.RaftSync.TransformSync;
public class RaftTransformSync : UnsectoredRigidbodySync
public class RaftTransformSync : UnsectoredRigidbodySync, ILinkedNetworkBehaviour<QSBRaft>
{
protected override bool UseInterpolation => false;
private QSBRaft _qsbRaft;
private static readonly List<RaftTransformSync> _instances = new();
public QSBRaft WorldObject { get; private set; }
public void LinkTo(IWorldObject worldObject) => WorldObject = (QSBRaft)worldObject;
protected override OWRigidbody InitAttachedRigidbody() => _qsbRaft.AttachedObject._raftBody;
protected override OWRigidbody InitAttachedRigidbody() => WorldObject.AttachedObject._raftBody;
public override void OnStartClient()
{
_instances.Add(this);
if (QSBCore.IsHost)
{
netIdentity.RegisterAuthQueue();
@ -29,7 +28,6 @@ public class RaftTransformSync : UnsectoredRigidbodySync
public override void OnStopClient()
{
_instances.Remove(this);
if (QSBCore.IsHost)
{
netIdentity.UnregisterAuthQueue();
@ -40,9 +38,6 @@ public class RaftTransformSync : UnsectoredRigidbodySync
protected override void Init()
{
_qsbRaft = RaftManager.Rafts[_instances.IndexOf(this)].GetWorldObject<QSBRaft>();
_qsbRaft.TransformSync = this;
base.Init();
SetReferenceTransform(AttachedRigidbody.GetOrigParent());

View File

@ -3,18 +3,19 @@ using Mirror;
using QSB.AuthoritySync;
using QSB.EchoesOfTheEye.LightSensorSync.WorldObjects;
using QSB.EchoesOfTheEye.RaftSync.TransformSync;
using QSB.Utility.LinkedWorldObject;
using QSB.WorldSync;
using System.Linq;
using System.Threading;
using UnityEngine;
namespace QSB.EchoesOfTheEye.RaftSync.WorldObjects;
public class QSBRaft : WorldObject<RaftController>
public class QSBRaft : WorldObject<RaftController>, ILinkedWorldObject<RaftTransformSync>
{
public override bool ShouldDisplayDebug() => false;
public RaftTransformSync TransformSync;
public RaftTransformSync NetworkBehaviour { get; private set; }
public void LinkTo(NetworkBehaviour networkBehaviour) => NetworkBehaviour = (RaftTransformSync)networkBehaviour;
private QSBLightSensor[] _lightSensors;
@ -22,10 +23,12 @@ public class QSBRaft : WorldObject<RaftController>
{
if (QSBCore.IsHost)
{
NetworkServer.Spawn(Object.Instantiate(QSBNetworkManager.singleton.RaftPrefab));
this.SpawnLinked(QSBNetworkManager.singleton.RaftPrefab);
}
else
{
await this.WaitForLink();
}
await UniTask.WaitUntil(() => TransformSync, cancellationToken: ct);
await UniTask.WaitUntil(() => QSBWorldSync.AllObjectsAdded, cancellationToken: ct);
_lightSensors = AttachedObject._lightSensors.Select(x => x.GetWorldObject<QSBLightSensor>()).ToArray();
@ -40,7 +43,7 @@ public class QSBRaft : WorldObject<RaftController>
{
if (QSBCore.IsHost)
{
NetworkServer.Destroy(TransformSync.gameObject);
NetworkServer.Destroy(NetworkBehaviour.gameObject);
}
foreach (var lightSensor in _lightSensors)
@ -53,7 +56,7 @@ public class QSBRaft : WorldObject<RaftController>
{
if (AttachedObject.IsPlayerRiding())
{
TransformSync.netIdentity.UpdateAuthQueue(AuthQueueAction.Force);
NetworkBehaviour.netIdentity.UpdateAuthQueue(AuthQueueAction.Force);
}
}

View File

@ -45,7 +45,7 @@ public abstract class SyncBase : QSBNetworkTransform
return false;
}
if (!QSBWorldSync.AllObjectsAdded)
if (!QSBWorldSync.AllObjectsReady)
{
return false;
}

View File

@ -1,4 +1,5 @@
using Mirror;
using Cysharp.Threading.Tasks;
using Mirror;
using QSB.WorldSync;
using UnityEngine;
@ -6,11 +7,24 @@ namespace QSB.Utility.LinkedWorldObject;
public static class Extensions
{
public static void SpawnLinked(this GameObject go, ILinkedWorldObject<INetworkBehaviour> worldObject)
/// <summary>
/// link a world object and network object, then spawn it.
/// (host only)
/// </summary>
public static void SpawnLinked(this ILinkedWorldObject<NetworkBehaviour> worldObject, GameObject prefab)
{
var networkBehaviour = go.GetComponent<ILinkedNetworkBehaviour<IWorldObject>>();
worldObject.LinkTo(networkBehaviour);
var networkBehaviour = prefab.GetComponent<ILinkedNetworkBehaviour<IWorldObject>>();
worldObject.LinkTo((NetworkBehaviour)networkBehaviour);
networkBehaviour.LinkTo(worldObject);
NetworkServer.Spawn(go);
NetworkServer.Spawn(prefab);
}
/// <summary>
/// wait for a world object to be linked.
/// (non host only)
/// </summary>
public static async UniTask WaitForLink(this ILinkedWorldObject<NetworkBehaviour> worldObject) =>
UniTask.WaitUntil(() => worldObject.NetworkBehaviour);
}

View File

@ -5,7 +5,7 @@ namespace QSB.Utility.LinkedWorldObject;
/// <summary>
/// a network behaviour that is linked to a world object
/// </summary>
public interface ILinkedNetworkBehaviour<out TWorldObject> : INetworkBehaviour
public interface ILinkedNetworkBehaviour<out TWorldObject>
where TWorldObject : IWorldObject
{
TWorldObject WorldObject { get; }

View File

@ -1,4 +1,5 @@
using QSB.WorldSync;
using Mirror;
using QSB.WorldSync;
namespace QSB.Utility.LinkedWorldObject;
@ -6,8 +7,8 @@ namespace QSB.Utility.LinkedWorldObject;
/// a world object that is linked to a network behaviour
/// </summary>
public interface ILinkedWorldObject<out TNetworkBehaviour> : IWorldObject
where TNetworkBehaviour : INetworkBehaviour
where TNetworkBehaviour : NetworkBehaviour
{
TNetworkBehaviour NetworkBehaviour { get; }
void LinkTo(INetworkBehaviour networkBehaviour);
void LinkTo(NetworkBehaviour networkBehaviour);
}

View File

@ -10,15 +10,15 @@ namespace QSB.Utility.LinkedWorldObject;
/// </summary>
public class LinkMessage : QSBMessage<(int ObjectId, uint NetId)>
{
public LinkMessage(IWorldObject worldObject, INetworkBehaviour networkBehaviour) :
public LinkMessage(IWorldObject worldObject, NetworkBehaviour networkBehaviour) :
base((worldObject.ObjectId, networkBehaviour.netId)) { }
public override void OnReceiveRemote()
{
var worldObject = Data.ObjectId.GetWorldObject<ILinkedWorldObject<INetworkBehaviour>>();
var worldObject = Data.ObjectId.GetWorldObject<ILinkedWorldObject<NetworkBehaviour>>();
var networkBehaviour = NetworkClient.spawned[Data.NetId].GetComponent<ILinkedNetworkBehaviour<IWorldObject>>();
worldObject.LinkTo(networkBehaviour);
worldObject.LinkTo((NetworkBehaviour)networkBehaviour);
networkBehaviour.LinkTo(worldObject);
}
}

View File

@ -1,4 +1,5 @@
using QSB.Messaging;
using Mirror;
using QSB.Messaging;
using QSB.WorldSync;
namespace QSB.Utility.LinkedWorldObject;
@ -19,7 +20,7 @@ public class RequestLinksMessage : QSBMessage
{
DebugLog.DebugWrite($"sending world object links to {to}");
foreach (var worldObject in QSBWorldSync.GetWorldObjects<ILinkedWorldObject<INetworkBehaviour>>())
foreach (var worldObject in QSBWorldSync.GetWorldObjects<ILinkedWorldObject<NetworkBehaviour>>())
{
new LinkMessage(worldObject, worldObject.NetworkBehaviour) { To = to }.Send();
}

View File

@ -4,12 +4,7 @@ using System;
namespace QSB.Utility;
public interface INetworkBehaviour
{
uint netId { get; }
}
public abstract class QSBNetworkBehaviour : NetworkBehaviour, INetworkBehaviour
public abstract class QSBNetworkBehaviour : NetworkBehaviour
{
protected virtual float SendInterval => 0.1f;
protected virtual bool UseReliableRpc => false;