Networking

The recommended approach for State Designer and networking is to have State Designer run on the server. This will ensure the server makes all of the decisions and then sends the clients the results. For example, if the PlayAnimation state is running the client should only receive an event indicating that the animation should play. With this setup the state machine isn’t even aware of the network. This is also true for a client authoritative solution. Only the resulting transform/animation properties should be synced to all other clients. The actual state machine does not need to be synchronized across the network.

For a practical example your script would look something like this:

public class StateMachineEnabler : MonoBehaviour
{
    [Tooltip("A reference to the state machine."]
    public StateMachine m_StateMachine;

    private void Awake()
    {
        m_StateMachine.enabled = IsServer();
    }
}

The IsServer method depends on your networking implementation but it will ensure the behavior tree is enabled only on the server or the authoritative client in a peer to peer situation. With this setup State Designer can work with any networking implementation.

For Entity clients the StartBakedStateMachine method should not be called. This will prevent the behavior tree systems from starting on the client and only the server will run the behavior tree. From the Entity Baking page, the spawner script would look something like:

public partial struct EntitySpawnerSystem : ISystem
{
    /// <summary>
    /// Sets the system requirements.
    /// </summary>
    /// <param name="state">The current SystemState.</param>
    private void OnCreate(ref SystemState state)
    {
        state.RequireForUpdate<SpawnData>();
    }

    /// <summary>
    /// Spawns the entities.
    /// </summary>
    /// <param name="state">The current SystemState.</param>
    private void OnUpdate(ref SystemState state)
    {
        state.Enabled = false;

        var spawner = SystemAPI.ManagedAPI.GetSingleton<SpawnData>();
        var entities = state.EntityManager.Instantiate(spawner.Prefab, 100, Allocator.Temp);

        // Any custom setup for each entity. This can include adding new components, enabling components, setting entity data, etc.

        // The behavior trees have been baked.
        if (spawner.IsServer) { // Your networking implementation for determining if the agent is on the server.
            StateDesigner.StartBakedStateMachine(World.DefaultGameObjectInjectionWorld, entity);
        }   
    }
}

Keep Reading

Previous Page

API