Network Behaviour
Overview
A NetworkBehaviour
requires a NetworkObject
on the same node or a parent node.
NetworkBehaviour
functions similarly to SimulationBehaviour
with the addition that it can carry a synchronized state. This is the reason why it has to have an associated NetworkObject
.
Overridable Methods
A NetworkObject
has a number of additional life-cycle methods, all of which can be overriden when implementating SimulationBehaviour
and NetworkBehaviour
.
Function | Description |
---|---|
FixedUpdateNetwork() | Fusion's fixed time step callback. Used for the core game logic. |
Spawned() | Post spawn callback. |
Despawned(bool hasState) | Called before the network object is despawned.
--- bool hasState: If the state of the behaviour is still accessible. |
Render() | Post simulation frame rendering callback. Runs after all simulations have finished. Use in place of Unity's Update when Fusion is handling Physics. |
Networked State
Internally Fusion stores the entire networked state for each tick as a single memory buffer, called a Snapshot
. Networked Properties define which variables in a NetworkedBehaviour
are part of that networked state.
Networked Properties
To define a Networked Property, use the [Networked]
attribute. Fusion will automatically connect these tagged properties to its own high performance data buffers and delta compression. The property setters and getters are compile-time replaced with custom code to eliminate memory allocation overhead and provide optimal performance.
public class PlayerBehaviour : NetworkedBehaviour
{
[Networked] public float Health { get; set; }
}
At compile-time Fusion will replace the empty get/set stubs with code that accesses the actual networked state data. The direct access eliminates the memory allocation overhead and provides optimal performance. DO NOT implement them manually.
This direct property access to the state buffer means that whenever a change occurs, the state reflects that change immediately.
To write logic affecting networked state, override and implement FixedUpdateNetwork()
.
public override void FixedUpdateNetwork()
{
Health += Runner.DeltaTime * HealthRegen;
}
Allowed Types
The following types are supported by Fusion and can be [Networked]
:
- Primitives
- byte, sbyte
- Int16, Int32, Int64
- UInt16, UInt32, UInt64
- float
- double
- float
- double
- bool (convereted to int)
- Strings with a maximum
Length
set using the[Capacity]
attribute (defaults to 16) - Unity struct types (defined in ILWeaver.cs)
- Vector2, Vector3, Vector4
- Quaternion
- Matrix4x4
- Vector2Int, Vector3Int
- BoundingSphere
- Bounds
- Rect
- BoundsInt
- RectInt
- Color, Color32
- System.Guid
- User Defined INetworkStructs
- Fusion Defined INetworkStructs
- NetworkString<
- IFixedStorage>
- NetworkBool
- Ptr
- Angle
- BitSet64, BitSet128, BitSet192, BitSet256
- PlayerRefSet
- NetworkId
- NetworkButtons
- NetworkRNG
- NetworkObjectGuid
- NetworkPrefabRef
- NetworkObjectHeader
- NetworkPrefabId
- SceneRef
- TickTimer
- IFixedStorage (_2, _4, _8, _16, _32, _64, _128, _256, _512)
- Fusion Types
- NetworkObject (serialized as
NetworkId
) - NetworkBehaviour (serialized as
NetworkId
and theNetworkBehaviour
index) - PlayerRef (serialized as
PlayerRef.PlayerId
)
- NetworkObject (serialized as
- NetworkArray<T> with a maximum
Length
set using the[Capacity]
attribute (defaults to 1) - NetworkDictionary<K, V> with a maximum
Count
set using the[Capacity]
- NetworkLinkedList<T> with a maximum
Count
set using the [Capacity] attribute. - NetworkString<_size>
Setting Default Values
It is possible to set default values for [Networked]
properties.
Common Types
For most common types a simple assignment is sufficient.
public class PlayerBehaviour : NetworkedBehaviour
{
[Networked] public float Health { get; set; } = 100;
[Networked] public NetworkObject DefaultNetworkObject { get; set; } = GameObject.FindGameObjectWithTag("Foo").GetComponent<NetworkObject>();
}
Collections
Network Collections such as NetworkArray<T> , NetworkDictionary<K, V> , NetworkLinkedList<T> and NetworkString<_size> require a special syntax. Please refer to the page of the same name for more information.
Ref And Ptr
It is possible to set default values for references and pointers by using the appropriate constructors.
[Networked] public ref Byte Prop => ref MakeRef<Byte>(123);
[Networked] public Byte* Prop => MakePtr<Byte>(123);
Additional Attributes
The [Networked]
attribute can be combined with several other attributes to define more specificly how the network state is handled.
Accuracy
It is possible to control the accuracy of individual numeric type properties by using the [Accuracy]
attribute.
public class PlayerBehaviour : NetworkedBehaviour
{
[Networked, Accuracy(0.001)]
public float Health { get; set; }
}
Capacity
[Capacity]
is used to define the maximum size of NetworkArray
, NetworkDictionary
, NetworkLinkedList
, NetworkString
and strings.
public class MyNetworkBehaviour : NetworkedBehaviour
{
[Networked, Capacity(14)]
string MyString { get; set; }
[Networked, Capacity(8)]
NetworkArray<byte> MyArray { get; }
}
For more information on the handling of network collection, please refer to the Network Collections page.
OnChanged
Game code can be triggered when a change is detected in a networked property between two render frames. To write reactive code, use the (OnChanged)
parameter on the [Networked]
attribute.
public class Powerup : NetworkBehaviour
{
[Networked(OnChanged = nameof(OnXyzChanged))] public TypeOfProperty Xyz { get; set; }
// Has to be public static void
public static void OnXyzChanged(Changed<Powerup> changed)
{
changed.Behaviour.OnXyzChanged();
}
private void OnXyzChanged()
{
// Some logic reacting to the value change of the "Xyz" property
}
}
In addition to specifying the callback name, it is possible to control on which machines the callback is executed:
OnChangedLocal
(default false): set to true to also have the event hook called on the machine that changed the propertyOnChangedRemote
(default true): set to false to only have the event hook called on the machine that changed the property.
Note that OnChanged
callbacks are called when a change is detected between two Unity Update
calls. I.e. these callbacks are not tick aligned and will only detect changes that occur between two render frames, and as such should never be used for gameplay logic. The primary use case for OnChange
callbacks is to trigger visual or audio effects, specifically on proxies.
The Changed<T>
parameter provides access to all properties of the behaviour both before and after the change - use LoadOld
and LoadNew
to toggle between the two:
private static void OnXyzChanged(Changed<Powerup> changed)
{
var new_value = changed.Behaviour.Xyz;
changed.LoadOld();
var old_value = changed.Behaviour.Xyz;
}
Generics
It is possible to create templated classes deriving from NetworkBehaviour
. These can even contain [Networked]
properties.
// This is VALID
class ValidGenericClass_With_NonGenericProperty<T> : NetworkBehaviour {
[Networked] public int Prop { get; set; }
}
However, it is NOT possible to have a generic [Networked]
property of type <T>.
// This is INVALID
class InValidGenericClass_With_GenericProperty<T> : NetworkBehaviour {
[Networked] public T Prop { get; set; }
}