Class KCCPlatform
Predicted moving platform on FishNet's own model: every peer runs the same autonomous, deterministic replicate, the server reconciles it to every observer, and FishNet rolls it back and replays it with everything else. Riders inherit its per-tick velocity through KCCPlayer.
public class KCCPlatform : TickNetworkBehaviour, ISceneObject
- Inheritance
-
ObjectComponentBehaviourMonoBehaviourNetworkBehaviourTickNetworkBehaviourKCCPlatform
- Implements
- Inherited Members
-
TickNetworkBehaviour.SetTickCallbacks(TickNetworkBehaviour.TickCallback)TickNetworkBehaviour.TimeManager_OnPreTick()TickNetworkBehaviour.TimeManager_OnPostTick()TickNetworkBehaviour.TimeManager_OnUpdate()TickNetworkBehaviour.TimeManager_OnLateUpdate()NetworkBehaviour.IsSpawnedNetworkBehaviour.ComponentIndexNetworkBehaviour.NetworkObjectNetworkBehaviour.MAXIMUM_NETWORKBEHAVIOURSNetworkBehaviour.UNSET_NETWORKBEHAVIOUR_IDNetworkBehaviour.ToString()NetworkBehaviour.Reset()NetworkBehaviour.OnValidate()NetworkBehaviour.IsBehaviourReconcilingNetworkBehaviour.ClearReplicateCache()NetworkBehaviour.Reconcile_Reader<T>(PooledReader, ref T)NetworkBehaviour.OnStartServerCalledNetworkBehaviour.OnStartClientCalledNetworkBehaviour.OnStopNetwork()NetworkBehaviour.OnStartServer()NetworkBehaviour.OnStopServer()NetworkBehaviour.OnOwnershipServer(NetworkConnection)NetworkBehaviour.OnSpawnServer(NetworkConnection)NetworkBehaviour.OnDespawnServer(NetworkConnection)NetworkBehaviour.OnStartClient()NetworkBehaviour.OnStopClient()NetworkBehaviour.OnOwnershipClient(NetworkConnection)NetworkBehaviour.ClearBuffedRpcs()NetworkBehaviour.ExcludeOwnerFromUnbufferedObserversRpcsNetworkBehaviour.IsClientOnlyNetworkBehaviour.IsServerOnlyNetworkBehaviour.IsHostNetworkBehaviour.IsClientNetworkBehaviour.IsServerNetworkBehaviour.IsDeinitializingNetworkBehaviour.NetworkManagerNetworkBehaviour.ServerManagerNetworkBehaviour.ClientManagerNetworkBehaviour.ObserverManagerNetworkBehaviour.TransportManagerNetworkBehaviour.TimeManagerNetworkBehaviour.SceneManagerNetworkBehaviour.PredictionManagerNetworkBehaviour.RollbackManagerNetworkBehaviour.NetworkObserverNetworkBehaviour.IsClientInitializedNetworkBehaviour.IsClientStartedNetworkBehaviour.IsClientOnlyInitializedNetworkBehaviour.IsClientOnlyStartedNetworkBehaviour.IsServerInitializedNetworkBehaviour.IsServerStartedNetworkBehaviour.IsServerOnlyInitializedNetworkBehaviour.IsServerOnlyStartedNetworkBehaviour.IsHostInitializedNetworkBehaviour.IsHostStartedNetworkBehaviour.IsOfflineNetworkBehaviour.IsNetworkedNetworkBehaviour.GetIsNetworked()NetworkBehaviour.IsManagerReconcilingNetworkBehaviour.ObserversNetworkBehaviour.IsOwnerNetworkBehaviour.IsControllerNetworkBehaviour.HasAuthorityNetworkBehaviour.OwnerNetworkBehaviour.OwnerIdNetworkBehaviour.ObjectIdNetworkBehaviour.LocalConnectionNetworkBehaviour.OwnerMatches(NetworkConnection)NetworkBehaviour.Despawn(GameObject, DespawnType?)NetworkBehaviour.Despawn(NetworkObject, DespawnType?)NetworkBehaviour.Despawn(DespawnType?)NetworkBehaviour.Spawn(GameObject, NetworkConnection, Scene)NetworkBehaviour.Spawn(NetworkObject, NetworkConnection, Scene)NetworkBehaviour.RemoveOwnership()NetworkBehaviour.GiveOwnership(NetworkConnection)NetworkBehaviour.GetInstance<T>()NetworkBehaviour.TryRegisterInstance<T>(T)NetworkBehaviour.UnregisterInstance<T>()NetworkBehaviour.CanLog(LoggingType)MonoBehaviour.IsInvoking()MonoBehaviour.CancelInvoke()MonoBehaviour.StopCoroutine(Coroutine)MonoBehaviour.StopAllCoroutines()MonoBehaviour.destroyCancellationTokenMonoBehaviour.useGUILayoutMonoBehaviour.didStartMonoBehaviour.didAwakeMonoBehaviour.runInEditModeBehaviour.enabledBehaviour.isActiveAndEnabledComponent.GetComponent<T>()Component.TryGetComponent<T>(out T)Component.GetComponentInChildren<T>()Component.GetComponentsInChildren<T>()Component.GetComponentInParent<T>()Component.GetComponentsInParent<T>()Component.GetComponents<T>()Component.GetComponentIndex()Component.CompareTag(TagHandle)Component.transformComponent.transformHandleComponent.gameObjectComponent.tagObject.GetEntityId()Object.GetInstanceID()Object.GetHashCode()Object.InstantiateAsync<T>(T)Object.InstantiateAsync<T>(T, Transform)Object.InstantiateAsync<T>(T, Vector3, Quaternion)Object.InstantiateAsync<T>(T, Transform, Vector3, Quaternion)Object.Instantiate(Object, Vector3, Quaternion)Object.Instantiate(Object, Vector3, Quaternion, Transform)Object.Instantiate(Object)Object.Instantiate(Object, Scene)Object.Instantiate<T>(T, InstantiateParameters)Object.Instantiate<T>(T, Vector3, Quaternion, InstantiateParameters)Object.Instantiate(Object, Transform)Object.Instantiate<T>(T)Object.Instantiate<T>(T, Vector3, Quaternion)Object.Instantiate<T>(T, Vector3, Quaternion, Transform)Object.Instantiate<T>(T, Transform)Object.Destroy(Object)Object.DestroyImmediate(Object)Object.DontDestroyOnLoad(Object)Object.DestroyObject(Object)Object.FindObjectsOfType<T>()Object.FindObjectsByType<T>(FindObjectsSortMode)Object.FindObjectsByType<T>(FindObjectsInactive, FindObjectsSortMode)Object.FindObjectOfType<T>()Object.FindFirstObjectByType<T>()Object.FindAnyObjectByType<T>()Object.FindFirstObjectByType<T>(FindObjectsInactive)Object.FindAnyObjectByType<T>(FindObjectsInactive)Object.FindObjectsByType<T>()Object.FindObjectsByType<T>(FindObjectsInactive)Object.nameObject.hideFlags
Remarks
A fork of FishNet's Demos/Prediction/CharacterController/MovingPlatform, and since
issue #228 deliberately back ON that model. This platform's NetworkObject is the one
kind of scene object in the project with state forwarding ENABLED (pinned by
InterestManagementWiringTests.OnlyPlatforms_ShipWithStateForwardingOn), because the
argument that keeps forwarding off everywhere else does not apply to it: forwarding a
character relays every owner's INPUT to every observer, which is what makes 100-200 players
unaffordable — an ownerless platform has no input. Its replicate is an empty struct, and the
only wire cost is one delta-encoded reconcile (Vector3 + byte) per observer per tick.
What that buys, in the demo's own words: with the body run in EVERY replicate state,
IsFuture included, a client's platform runs AHEAD of the server by that client's ping —
where the platform will be by the time the client's input reaches the server — and every
reconcile rolls the platform back to the server's state and replays it in lockstep with the
rider, so a replayed ground probe meets the deck where it actually stood on that tick.
The previous model — forwarding off, each client stepping the platform itself from a
one-shot spawn payload — had neither property. With forwarding off FishNet returns from
Replicate_NonAuthoritative before invoking the body and sends no reconcile for an
ownerless object, so the client copy was seeded from the payload and dead-reckoned open-loop
for the rest of the session: seeded BEHIND the server (aligned to the interpolated observer
frame ability objects use, the opposite of what a deck the owner stands on needs), and never
rolled back, so a reconcile replay probed a deck up to a round trip downstream of where the
rider stood. Riders sank through moving decks, worst at high ping, worst near the edges.
Properties
GameObject
The Unity GameObject associated with this scene object.
public GameObject GameObject { get; }
Property Value
- GameObject
ID
Unique identifier for the scene object.
public long ID { get; set; }
Property Value
LastCompletedTickVelocity
Velocity of the platform during its most recently completed Step(float), in world units per second. Refreshed by every run of the replicate body — the live tick on both peers, and each replayed tick on a client — so it is the velocity of whatever tick the platform last simulated.
public Vector3 LastCompletedTickVelocity { get; }
Property Value
- Vector3
Methods
CreateReconcile()
Override this method to create your reconcile data, and call your reconcile method.
public override void CreateReconcile()
OnStartNetwork()
Called when the network has initialized this object. May be called for server or client but will only be called once. When as host or server this method will run before OnStartServer. When as client only the method will run before OnStartClient.
public override void OnStartNetwork()
ReadPayload(NetworkConnection, Reader)
Called before network start callbacks, but after the object is initialized with network values. This may be used to read information from predicted spawning, or simply have values set before initialization without depending on SyncTypes.
public override void ReadPayload(NetworkConnection connection, Reader reader)
Parameters
connectionNetworkConnectionConnection sending the payload. When coming from the server connection.IsValid will return false.
readerReader
Remarks
A SEED, not a sync. A client arriving mid-cycle would otherwise draw the platform at its authored pose for the tick or two before its first reconcile lands; the reconcile is what places it, and every reconcile after that keeps it placed. The catch-up that used to live here (fast-forwarding the snapshot by its transit) is gone with the reason it existed — the payload is no longer the only word the client ever hears about this platform.
ResetState(bool)
Resets this NetworkBehaviour so that it may be added to an object pool.
public override void ResetState(bool asServer)
Parameters
asServerbool
TimeManager_OnTick()
protected override void TimeManager_OnTick()
Remarks
Identical on every peer, exactly as the FishNet demo has it. The server's call is
authoritative and drives the reconcile; a client's routes through
Replicate_NonAuthoritative, which — because this object forwards state — runs the
body with the server's queued data when it has some and with default, IsFuture
data when it does not. The body moves in either case, which is what puts the client's
platform ahead of the server by its ping rather than behind it.
TryGetVelocityForTick(uint, out Vector3)
The velocity this platform produced on a specific tick, in the CLIENT tick domain.
public bool TryGetVelocityForTick(uint tick, out Vector3 velocity)
Parameters
tickuintThe tick to look up.
velocityVector3The velocity produced on that tick, when still held.
Returns
- bool
True when the tick is still in the ring.
Remarks
FishNet promises no tick order across NetworkObjects, so a rider simulating tick T cannot
know whether this platform has already stepped T or is still on T-1 when it asks for
LastCompletedTickVelocity. The ring answers by tick instead, and is filled
wherever the platform runs a tick on a client: from TimeManager_OnTick() keyed
by LocalTick for the live tick, and from the replayed replicate keyed by
PredictionManager.ClientReplayTick — both the same counter a rider's input carries.
The server fills it too, keyed by ITS local tick, but must not consult it with a rider's input tick: that tick is the owning client's unsynchronised counter, so the lookup is an arbitrary hit or a miss. The server never replays, and reads the live value instead.
WritePayload(NetworkConnection, Writer)
Called when writing a spawn. This may be used to deliver information for predicted spawning, or simply have values set before initialization without depending on SyncTypes.
public override void WritePayload(NetworkConnection connection, Writer writer)
Parameters
connectionNetworkConnectionConnection receiving the payload. When sending to the server connection.IsValid will return false.
writerWriter