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

Unity Netcode:调用其他脚本ServerRPC方法报错,如何修复?

问题:调用NetworkBehaviour的ServerRpc时出现KeyNotFoundException错误

问题场景

我需要在玩家脚本TestUseScript中调用另一个类DashT的ServerRPC方法,代码示例如下:

DashT.cs

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

public class DashT : NetworkBehaviour
{
    [ServerRpc]
    public void UseServerRpc()
    {
        Debug.Log(1);
    }
}

TestUseScript.cs

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

public class TestUseScript : NetworkBehaviour
{
    private void Start()
    {
        GameObject obj = new GameObject();
        obj.name = string.Format("_{0}", typeof(DashT).Name);
        DashT skill = obj.AddComponent<DashT>();

        if (IsOwner)
            skill.UseServerRpc();
    }
}

运行后触发如下错误:

KeyNotFoundException: The given key 'DashT' was not present in the dictionary.
System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (TKey key) (at <20deccf348554c238921b06fec015ff8>:0)
Unity.Netcode.NetworkBehaviour.__endSendServerRpc (Unity.Netcode.FastBufferWriter& bufferWriter, System.UInt32 rpcMethodId, Unity.Netcode.ServerRpcParams serverRpcParams, Unity.Netcode.RpcDelivery rpcDelivery) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.8.1/Runtime/Core/NetworkBehaviour.cs:127)
DashT.UseServerRpc () (at Assets/Scripts/Skills/DashT.cs:11)
TestUseScript.Start () (at Assets/Scripts/Player/TestUseScript.cs:15)

修复方案

错误核心原因是:你动态创建的DashT所在的GameObject没有被正确注册到Netcode网络系统中。所有继承NetworkBehaviour的组件必须依附在带有NetworkObject组件的GameObject上,且该对象需要通过网络同步(要么是场景预先放置的NetworkObject,要么由服务器Spawn生成)。

方案一:通过服务器Spawn独立技能对象

因为客户端没有权限直接生成网络对象,所以需要先请求服务器创建并注册对象,再调用ServerRpc:

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

public class TestUseScript : NetworkBehaviour
{
    private void Start()
    {
        if (IsOwner)
        {
            // 客户端向服务器请求创建技能对象
            RequestSpawnDashServerRpc();
        }
    }

    [ServerRpc]
    private void RequestSpawnDashServerRpc()
    {
        // 服务器端创建对象并添加必要组件
        GameObject obj = new GameObject();
        obj.name = string.Format("_{0}", typeof(DashT).Name);
        NetworkObject networkObj = obj.AddComponent<NetworkObject>();
        DashT skill = obj.AddComponent<DashT>();

        // Spawn对象,同步到所有客户端
        networkObj.Spawn();
        // 服务器端直接调用ServerRpc,或后续由客户端调用
        skill.UseServerRpc();
    }
}

方案二:复用玩家对象的NetworkObject

如果DashT不需要作为独立网络对象,可以直接将其挂载到玩家对象上(玩家对象本身已有NetworkObject),无需额外Spawn:

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

public class TestUseScript : NetworkBehaviour
{
    private DashT skill;

    private void Start()
    {
        // 将DashT挂载到当前玩家对象上
        skill = gameObject.AddComponent<DashT>();
        if (IsOwner)
        {
            skill.UseServerRpc();
        }
    }
}

关键注意事项

  • 所有NetworkBehaviour组件必须依附在带有NetworkObject的GameObject上
  • 动态创建的网络对象必须由**服务器调用Spawn()**完成注册,客户端不能直接Spawn
  • ServerRpc的调用方必须是拥有对象权限的客户端(通过IsOwner判断),且目标NetworkBehaviour所在对象必须已完成网络注册

内容的提问来源于stack exchange,提问作者Канал Shoker 2

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:55:06