This section explains how to send and listen for events over the network from a specific NetworkObject.
Events dispatched this way will be received on the corresponding NetworkObject instance across all clients.
If you’re looking to send global events that are not tied to a specific NetworkObject, please refer to the Global Events section.
Sending
First, you need to create a unique identifier for this event, this identifier shall be a positive integer number.
constint LOCAL_CUSTOM_EVENT =20000;
Note: It's highly recommenced to group events to avoid two events using the same code
Local events work exactly as Global Events, the main difference is that Object Event is sent having a NetworkObject as origin and will arrive on the same object in the client instance, this means that Object Event is a smart way to update or change a specific NetworkObject.
This code illustrates how to send an event from an object over the network, you can include data on the message to be received on the target destination.
using (DataStream writer =newDataStream()) {writer.Write(this.transform.position); // Vector3writer.Write(this.objectStatus); // intwriter.Write(this.errorCode); // uint // Send event // Is important to send using "this" because system will include object information's during event sendthis.Send(LOCAL_CUSTOM_EVENT, writer,DeliveryMode.Reliable); }
Listening
You can listen to events sent by other network peers and execute some action based on this event, this event will arrive specifically on the same object where the event will be raised on the server or another remote player.
This code illustrates how to listen to some network event from a NetworkObject, read data on this event, and take some action.
public override void OnNetworkStarted() {
this.RegisterEvent(LOCAL_CUSTOM_EVENT, this.OnCustomEventReceivedOnObject);
}
private void OnCustomEventReceivedOnObject(IDataStream reader) {
Vector3 receivedPosition = reader.Read<Vector3>();
float receivedStatus = reader.Read<float>();
int receivedErrorCode = reader.Read<ushort>();
// Update player with received information
this.RaiseObjectError(receivedPosition, receivedStatus, receivedErrorCode);
}
Note: Register the event OnNetworkStarted to make sure the object is intialized or else it wont work.
Full Code Example
Note: the script inherits from NetworkBehaviour class as we are sending Network Object Events. Sending global events dont need that (see Sending Global Events)
using UnityEngine;
using com.onlineobject.objectnet;
public class SendEventExample : NetworkBehaviour
{
const int LOCAL_CUSTOM_EVENT = 20000;
//Subscribe the reciever method to the event
public override void OnNetworkStarted() {
this.RegisterEvent(LOCAL_CUSTOM_EVENT, this.OnCustomEventReceivedOnObject);
}
private void Update(){
//makes sure only the active running this code
if (IsPassive()) return;
// sends the event when ever the user press T
if (Input.GetKeyDown(KeyCode.T)){
using (DataStream writer = new DataStream()) {
writer.Write(this.transform.position); // Vector3
writer.Write(this.objectStatus); // int
writer.Write(this.errorCode); // uint
// Send event
// Is important to send using "this" because system will include object information's during event send
this.Send(LOCAL_CUSTOM_EVENT, writer, DeliveryMode.Reliable);
}
}
}
//Event will trigger this method
private void OnCustomEventReceivedOnObject(IDataStream reader) {
Vector3 receivedPosition = reader.Read<Vector3>();
float receivedStatus = reader.Read<float>();
int receivedErrorCode = reader.Read<ushort>();
// Update player with received information
this.RaiseObjectError(receivedPosition, receivedStatus, receivedErrorCode);
}
//regular method
private void RaiseObjectError(Vector3 position, float status, ushort errorCode){
//any logic
}
}
BroadCast
When registering the event you have an option to broadcast the event to other clients. other wise the event will only be triggered on the server.
This tells the server to propagate the message coming from one client to all other clients.
Note: if the sender is the Server then all clients will recive the message regardless if broadcast was true or false, broadcast option is only for clients that want to communicate with other clients.
Supported Data types
You can include the following data types on the event message.
intuintlongulongshortushortfloatdouble-------------------------------------------------------------bytesbytebyte[] boolstringcharchar[] enum-------------------------------------------------------------Vector2 Vector3 Vector4 Quaternion Color Matrix4x4
FAQ:
Show me an Example on how to send a list using DataStream
Here is an example that illustrate the write and read of a full list.
private List<int> Numbers = new List<int>();
//any where in you script
using (DataStream writer = new DataStream()){
//write the length of the list
writer.Write(this.Numbers.Count); // int
//write each value on the list
for (int i = 0; i < Numbers.Count; i++){
writer.Write(Numbers[i]);
}
// Is important to send using "this" because system will include object information's during event send
this.Send(LOCAL_CUSTOM_EVENT, writer, DeliveryMode.Reliable);
}
//On the reciver
private void OnCustomEventReceivedOnObject(IDataStream reader){
//read the length
int listLength = reader.Read<int>();
//read and update each value on the list
for (int i = 0; i < listLength; i++){
Numbers[i] = reader.Read<int>();
}
}
Why the Event is not triggered on the sender?
Events will not be triggered on the sender. Custom events are broadcast to other clients, not to the sender itself.
When a client sends a DataStream message, the message is not looped back to the sender.
This means the sender will not receive or trigger the event locally.
If you want the sender to also process the logic, you’ll need to manually invoke the logic on the sender’s side after sending.
//for example
using (DataStream writer = new DataStream()) {
writer.Write(this.transform.position); // Vector3
writer.Write(this.objectStatus); // int
writer.Write(this.errorCode); // uint
// Send event
// Is important to send using "this" because system will include object information's during event send
this.Send(LOCAL_CUSTOM_EVENT, writer, DeliveryMode.Reliable);
}
//execute locally
this.RaiseObjectError(this.transform.position, this.objectStatus, this.errorCode);