# Sending Events

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**.\
&#x20;If you’re looking to send **global events** that are not tied to a specific NetworkObject, please refer to the [global-events](https://onlineobject.gitbook.io/objectnet/general/network-components/network-events-manager/global-events "mention") section.

## <mark style="color:blue;">Sending</mark>

First, you need to create a unique identifier for this event, this identifier shall be a positive integer number.

```csharp
const int LOCAL_CUSTOM_EVENT = 20000;
```

{% hint style="danger" %}
Note: It's highly recommenced to group events to avoid two events using the same code
{% endhint %}

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.

```csharp
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);
       }
```

## <mark style="color:blue;">Listening</mark>

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.

```csharp
       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);           
       }
```

{% hint style="warning" %}
Note: Register the event OnNetworkStarted to make sure the object is intialized or else it wont work.
{% endhint %}

<details>

<summary>Full Code Example</summary>

Note: the script inherits from NetworkBehaviour class as we are sending Network Object Events. Sending global events dont need that (see [sending-global-events](https://onlineobject.gitbook.io/objectnet/general/networkmanager-functions/sending-global-events "mention"))

```csharp
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
        }
            
}
```

</details>

<details>

<summary>BroadCast</summary>

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.

<figure><img src="https://content.gitbook.com/content/NG75ky1pR1kRokWLRnzy/blobs/sC7R7N4zX1MlW8yuL5vE/Screenshot%202025-04-17%20125225.png" alt=""><figcaption></figcaption></figure>

This tells the server to propagate the message coming from one client to all other clients.

{% hint style="info" %}
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.
{% endhint %}

</details>

<details>

<summary>Supported Data types </summary>

You can include the following data types on the event message.

```csharp
int   uint   long   ulong   short   ushort   float   double 
-------------------------------------------------------------
byte   sbyte   byte[]   bool   string   char   char[]   enum
-------------------------------------------------------------
Vector2   Vector3   Vector4   Quaternion   Color   Matrix4x4
```

</details>

***

## FAQ:

<details>

<summary>Show me an Example on how to send a list using DataStream</summary>

Here is an example that illustrate the write and read of a full list.

<pre class="language-csharp"><code class="lang-csharp"><strong>private List&#x3C;int> Numbers = new List&#x3C;int>();  
</strong><strong>      //any where in you script
</strong>        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 &#x3C; 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&#x3C;int>();
       //read and update each value on the list 
       for (int i = 0; i &#x3C; listLength; i++){
           Numbers[i] = reader.Read&#x3C;int>();
       }
   }
</code></pre>

</details>

<details>

<summary>Why the Event is not triggered on the sender?</summary>

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.

```csharp
//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);
```

</details>
