docs.unity3d.com
Search Results for

    Show / Hide Table of Contents

    Developing with GhostBridge

    GhostBridge offers the possibility for developers to use game object-like programming approaches to develop game objects based on Netcode for Entities. Figure 1 shows the relationship between an entity and its ghost game object in the entity world and game scene.

    Ghost Bridge UML

    View ghost game objects in the editor

    While playing the game in the editor, you can view GhostGameObjects in the scene hierarchy. Under the root node, the /Server node contains all the ghost game objects in the server world and the /Client node contains all the ghost game objects in the client world.

    Ghost Bridge Editor

    Defining ghost game objects

    To define a ghost game object, you have to add at least one behaviour script that inherits from GhostMonoBehaviour.

    Ghost Bridge Sphere Example of how the GhostSphere prefab is set up with the GhostSphere script component.

    Defining a ghost game object

    To define a new ghost game object, inherit from GhostMonoBehaviour instead of MonoBehaviour . Below is an example showing how the GhostSphere class is declared:

    public class GhostSphere : GhostMonoBehaviour, IUpdateServer, IUpdateClient
    {
    	...
    }
    

    Implement the Update functions

    You can write code to handle the server process in UpdateServer and client process in UpdateClient. The following code snippet demonstrates spinning the sphere and determining the color of the sphere on the server side and physically changing the sphere color on the client side.

    public void UpdateServer(float deltaTime)
    {
        // Rotate the sphere continuously
        m_RotationYaw += deltaTime * RotationSpeed;
        if (m_RotationYaw > 360f)
        {
            // After one full rotation, change color
            var colourState = ReadGhostComponentData<ColourState>();
            colourState.ColourIndex++;
            WriteGhostComponentData(colourState);
    
            // Notify all clients of the color change
            BroadcastRPC(new ColourChangedRPC
            {
                NewColourIndex = colourState.ColourIndex,
            });
    
            m_RotationYaw -= 360f;
        }
    
        transform.rotation = Quaternion.Euler(0f, m_RotationYaw, 0f);
    }
    
    public void UpdateClient(float deltaTime)
    {
        var colourState = ReadGhostComponentData<ColourState>();
        if (colourState.ColourIndex != m_ClientCachedColourIndex)
        {
            m_ClientCachedColourIndex = colourState.ColourIndex;
            m_Renderer.material.color = Colour.GetSequentiallyDifferentColour(colourState.ColourIndex);
        }
    
        if (ConsumeRPC<ColourChangedRPC>(out var rpc))
        {
            Debug.Log($"[ColourChangedRPC] Colour changing to {rpc.NewColourIndex}");
        }
    }
    

    Defining entity data components

    By using the GhostBridge feature, you can define ECS component data and access the data values within your GhostMonoBehaviour scripts. See the following code sample to understand how the definition of the ColourIndex component is defined.

    public class GhostSphere : GhostMonoBehaviour, IUpdateServer, IUpdateClient
    {
        public struct ColourState : IComponentData
        {
            [GhostField] public int ColourIndex;
        }
    
      ...
    }
    

    Handling OnGhostLinked

    OnGhostLinked is called once the game object is linked with its entity.

    public override void OnGhostLinked()
    {
        if (Role == MultiplayerRole.Server)
        {
            var colourState = ReadGhostComponentData<ColourState>();
            colourState.ColourIndex = 0;
            WriteGhostComponentData(colourState);
        }
        else
        {
            m_Renderer = GetComponentInChildren<Renderer>();
    
            var colourState = ReadGhostComponentData<ColourState>();
            m_ClientCachedColourIndex = colourState.ColourIndex;
            m_Renderer.material.color = Colour.GetSequentiallyDifferentColour(colourState.ColourIndex);
        }
    }
    

    Sending RPCs

    Define an RPC by inheriting from IRpcCommand:

    public class GhostSphere : GhostMonoBehaviour, IUpdateServer, IUpdateClient
    {
        public struct ColourChangedRPC : IRpcCommand
        {
            public int NewColourIndex;
        }
      ...
    }
    

    Send the RPC by calling the RPC functions:

    public void BroadcastRPC<T>(T rpcCommand)
       where T : unmanaged, IRpcCommand
    
    public void SendDirectedRPC<T>(T rpcCommand)
       where T : unmanaged, IRpcCommand, IGhostGameObjectDirectedRPC
    
    public bool ConsumeRPC<T>(out T rpc)
       where T : unmanaged, IRpcCommand
    
    In This Article
    Back to top
    Copyright © 2026 Unity Technologies — Trademarks and terms of use
    • Legal
    • Privacy Policy
    • Cookie Policy
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)