You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity Netcode主机调用ServerRpc无法执行的问题排查

问题分析与解决方案

问题根源

主机端调用AddNewPlayer_ServerRpc未执行的核心原因是:PlayersListManager对应的NetworkObject未被服务器正确Spawn,导致其IsServer属性为false,ServerRpc方法无法触发;其次是NetworkList的初始化时机不正确,客户端也会创建实例,可能引发同步问题。

解决步骤

1. 确保PlayersListManager的NetworkObject被服务器Spawn

选中PlayersListManager所在的GameObject,检查NetworkObject组件的Spawn On Start选项是否勾选。如果未勾选,需要在主机启动时手动调用Spawn逻辑(仅在服务器端执行):

private void Start()
{
    if (IsServer)
    {
        GetComponent<NetworkObject>().Spawn();
    }
}

2. 修正NetworkList的初始化时机

将NetworkList的初始化移到OnNetworkSpawn中,且仅在服务器端执行,避免客户端创建无效实例:

public class PlayersListManager : NetworkBehaviour
{
    [SerializeField] RectTransform playersListTransform;
    [SerializeField] GameObject playerNamePrefab;

    public NetworkList<FixedString32Bytes> playerUsernamesList;

    public override void OnNetworkSpawn()
    {
        base.OnNetworkSpawn();
        if (IsServer)
        {
            playerUsernamesList = new NetworkList<FixedString32Bytes>();
            playerUsernamesList.OnListChanged += OnPlayersListUpdate;
        }
    }

    [ServerRpc(RequireOwnership = false)]
    public void AddNewPlayer_ServerRpc(string newUsername)
    {
        Debug.Log("AddNewPlayer_ServerRpc");
        playerUsernamesList.Add(new FixedString32Bytes(newUsername));
    }

    // ...其他代码
}

3. 延迟调用ServerRpc,确保依赖对象完成初始化

主机端NetworkPlayer的OnNetworkSpawn可能早于PlayersListManager的网络初始化,延迟一帧调用ServerRpc避免时机问题:

public class NetworkPlayer : NetworkBehaviour
{
    [SerializeField] private string _username; //DEBUG ONLY
    public string Username { get; private set; }

    private MainMenuInteraction mainMenuInteraction;
    private PlayersListManager playersListManager;

    public override void OnNetworkSpawn()
    {
        base.OnNetworkSpawn();
        mainMenuInteraction = FindObjectOfType<MainMenuInteraction>();
        playersListManager = FindObjectOfType<PlayersListManager>();
        if (IsLocalPlayer)
        {
            Username = mainMenuInteraction.GetUsernameText();
            _username = Username;
            StartCoroutine(DelayedCallServerRpc());
        }
    }

    private IEnumerator DelayedCallServerRpc()
    {
        yield return null; // 等待一帧,确保PlayersListManager完成网络Spawn
        if (playersListManager != null && playersListManager.IsServer)
        {
            playersListManager.AddNewPlayer_ServerRpc(Username);
        }
        else
        {
            Debug.LogError("无法找到有效的PlayersListManager服务器实例");
        }
    }

    // ...其他代码
}

4. 验证ServerRpc的执行条件(可选)

在AddNewPlayer_ServerRpc开头添加服务器校验,确保只在服务器端执行:

[ServerRpc(RequireOwnership = false)]
public void AddNewPlayer_ServerRpc(string newUsername)
{
    if (!IsServer)
    {
        Debug.LogError("AddNewPlayer_ServerRpc只能在服务器端执行");
        return;
    }
    Debug.Log("AddNewPlayer_ServerRpc");
    playerUsernamesList.Add(new FixedString32Bytes(newUsername));
}

内容的提问来源于stack exchange,提问作者Giobar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 06:40:22