CharacterNetwork
Synchronizes character state across the network — movement, look direction, sprint state, and interactions. Handles ownership transfer for interactables and replicates interaction input via RPCs.
Definition
Namespace: Paragon.Townskeep.CharacterSystem
Assembly: Townskeep.dll
public class CharacterNetwork : ParagonNetworkBehaviour, IParagonComponent<Character>Inheritance: NetworkBehaviour → ParagonNetworkBehaviour → CharacterNetwork
Implements: IParagonComponent<Character>
Remarks
CharacterNetwork is the networking backbone of the Character system. Unlike other character services that extend CharacterComponent (a serializable subsystem component), this class extends ParagonNetworkBehaviour directly because it must be a MonoBehaviour on the character's GameObject for Unity Netcode to manage it.
It implements IParagonComponent<Character> to participate in the Character's component lifecycle (OnAdded, OnRemoved, Initialize).
Synchronization Strategy
The class uses two complementary sync mechanisms:
NetworkVariable<SyncData> — Continuous state sync (position, rotation, sprint, look direction). The owner writes every
Update(); non-owners read and apply to the character controller.RPCs — Discrete event sync (interaction begin/end, interaction inputs). Sent
NotOwnerso all remote clients replicate interactions.OnSynchronize — Initial state synchronization when a new client joins. Serializes all active interactions so late-joiners can reconstruct interaction state.
Interaction Networking Flow
Quick Lookup
Access owner character
IParagonComponent<Character>.Owner (explicit interface)
Check if local player owns this
IsOwner (from NetworkBehaviour)
Get client ID
ClientID (static, from ParagonNetworkBehaviour)
Methods
Awake
Initializes the NetworkVariable<SyncData>, SyncData struct, and input callbacks dictionary.
Initialize
Subscribes to the character's interaction system events (InteractionBegin, InteractionEnd).
OnAdded
Called when this component is added to a Character. Stores the character reference.
character
Character
The owning character
OnRemoved
Called when this component is removed from a Character. Clears the character reference.
OnSynchronize (override)
Handles initial state sync for late-joining clients. Serializes/deserializes all active interactions with their network object references.
Late-join deserialization uses Yield.WaitForEndOfFrame() to ensure NetworkObject references are resolved before attempting interaction replay.
BeginInteractionRpc
Replicates an interaction start to non-owner clients.
EndInteractionRpc
Replicates an interaction end to non-owner clients.
InputRpc
Replicates an interaction input press to non-owner clients.
networkObjectReference
NetworkObjectReference
Reference to the interactable's network object
inputName
string
Name of the InteractionInput to invoke
Update
Per-frame sync loop. Owner writes SyncData to the NetworkVariable; non-owners read and apply movement to the character's controller.
Nested Types
SyncData
Network-serializable struct containing the character's synchronized movement state.
TargetPose
Pose
Target position and rotation
IsRunning
bool
Whether the character is sprinting
LookAt
Vector3
Camera look direction
Common Pitfalls
Not a CharacterComponent subclass
Unlike CharacterAnimator or CharacterCamera, this class is a MonoBehaviour (via ParagonNetworkBehaviour). It is added as a Unity component on the character's GameObject, not as a serialized subsystem component. It participates in the Character lifecycle via explicit IParagonComponent<Character> implementation.
Ownership transfer on interaction
When the owner begins interacting with an object, OnInteractionBegin requests ownership transfer of the interactable's NetworkObject. This blocks on WaitUntil(IsSpawned) — if the network object never spawns, this will hang.
Debug.Assert on ownership
After ownership transfer, there is a Debug.Assert(OwnerClientId == interactableNetworkObject.OwnerClientId) that will fire in development builds if ownership transfer fails or is contested.
SyncData equality check
NetworkVariable<SyncData> only sends updates when the value changes (via IEquatable<SyncData>.Equals). The equality check uses Pose.Equals and Vector3.Equals, which are exact comparisons — even tiny floating-point differences trigger network updates.
See Also
ParagonNetworkBehaviour — base class providing network + debug integration
CharacterComponent — base class used by non-network character services
IParagonComponent<T> — component lifecycle interface
Last updated