[Netcode] ServerRpc not getting called

Making a player class selection system w/ Netcode.

using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine;

public class PlayerPrefabManager : NetworkBehaviour
{
    public static PlayerPrefabManager Instance { get; private set; }
    [SerializeField] private GameObject marinePrefab;
    [SerializeField] private GameObject ninjaPrefab;
    [SerializeField] private GameObject zombiePrefab;

    [SerializeField]
    private LobbyManager.PlayerCharacter[] playerCharacters;

    private Dictionary<LobbyManager.PlayerCharacter, GameObject> playerPrefabs;

    private void Awake()
    {
        if (Instance != null && Instance != this)
        {
            Destroy(this.gameObject);
        }
        else
        {
            Instance = this;
            DontDestroyOnLoad(this.gameObject);
        }

        int maxPlayers = 10; // Replace with your game's actual maximum player count.
        playerCharacters = new LobbyManager.PlayerCharacter[maxPlayers];

        playerPrefabs = new Dictionary<LobbyManager.PlayerCharacter, GameObject>
        {
            { LobbyManager.PlayerCharacter.Marine, marinePrefab },
            { LobbyManager.PlayerCharacter.Ninja, ninjaPrefab },
            { LobbyManager.PlayerCharacter.Zombie, zombiePrefab }
        };

        foreach (var prefab in playerPrefabs)
        {
            if (prefab.Value == null)
            {
                Debug.LogError($"{prefab.Key} prefab is not assigned in the inspector.");
            }
        }
    }

    public override void OnNetworkSpawn()
    {
        Debug.Log($"OnNetworkSpawn - OwnerClientId: {OwnerClientId}");
        SpawnPlayerServerRpc();
    }

    [ServerRpc(RequireOwnership = false)]
    void SpawnPlayerServerRpc(ServerRpcParams rpcParams = default)
    {
        // Get the ID of the client that sent the RPC
        ulong senderClientId = rpcParams.Receive.SenderClientId;

        Debug.Log($"SpawnPlayerServerRpc - clientId: {senderClientId}");
        SpawnPlayerOnClients(senderClientId);
    }

    void SpawnPlayerOnClients(ulong clientId)
    {
        Debug.Log($"SpawnPlayerOnClients - clientId: {clientId}");


        if (GetPlayerPrefab(playerCharacters[clientId]) == null)
        {
            Debug.LogError($"Prefab for character {playerCharacters[clientId]} is missing. Defaulting to Marine.");
            playerCharacters[clientId] = LobbyManager.PlayerCharacter.Marine;
        }

        // Instantiate player object
        Debug.Log("Spawning Player: " + playerCharacters[clientId]);
        GameObject player = Instantiate(GetPlayerPrefab(playerCharacters[clientId]));

        // Get the NetworkObject component
        var playerNetworkObject = player.GetComponent<NetworkObject>();

        // Spawn the player object on all clients
        playerNetworkObject.SpawnAsPlayerObject(clientId);
    }

    public GameObject GetPlayerPrefab(LobbyManager.PlayerCharacter playerCharacter)
    {
        if (playerPrefabs.TryGetValue(playerCharacter, out GameObject prefab))
        {
            return prefab;
        }

        Debug.LogError($"No prefab found for player character: {playerCharacter}");
        return null;
    }

    [ServerRpc(RequireOwnership = false)]
    public void SetPlayerPrefabServerRPC(LobbyManager.PlayerCharacter playerCharacter_, ServerRpcParams rpcParams = default)
    {
        Debug.Log("Setting player character " + playerCharacter_ + " for clientId: " + rpcParams.Receive.SenderClientId);
        playerCharacters[rpcParams.Receive.SenderClientId] = playerCharacter_;
        Debug.Log("Player Character changed to: " + playerCharacters[rpcParams.Receive.SenderClientId]);
    }
}

    public void FinalizeSelectClass()
    {
        Debug.Log("Calling SetPlayerPrefabServerRPC");
        PlayerPrefabManager.Instance.SetPlayerPrefabServerRPC(character);
    }

    public async void UpdatePlayerCharacter(PlayerCharacter playerCharacter)
    {
        FinalizeSelectClass();
        if (joinedLobby != null)
        {
            try
            {
                UpdatePlayerOptions options = new UpdatePlayerOptions();

                options.Data = new Dictionary<string, PlayerDataObject>() {
            {
                KEY_PLAYER_CHARACTER, new PlayerDataObject(
                    visibility: PlayerDataObject.VisibilityOptions.Public,
                    value: playerCharacter.ToString())
            }
        };
                character = playerCharacter;

                string playerId = AuthenticationService.Instance.PlayerId;

                Lobby lobby = await LobbyService.Instance.UpdatePlayerAsync(joinedLobby.Id, playerId, options);
                joinedLobby = lobby;

                OnJoinedLobbyUpdate?.Invoke(this, new LobbyEventArgs { lobby = joinedLobby });

            }
            catch (LobbyServiceException e)
            {
                Debug.Log(e);
            }
        }

    }

When I run this, FinalizeSelectClass() gets called, but SetPlayerPrefabServerRPC doesnt get called. There is no debug message, and all the player prefabs spawn the same, regardless of the chosen character.
(Sorry, I’m new to netcode.)

Where is this being called?

This method has to be called from within OnNetworkSpawn or later, and the script it is in needs to be a NetworkBehaviour.

If the debug message inside that method isn’t called either then FinalizeSelectClass doesn’t get called.

Ahh that was the case!

I was calling FinalizeSelectClass before OnNetworkReady.

Thanks~