@rpc
2026/4/14大约 4 分钟
最后更新日期:2026-04-16
最后同步日期:2026-04-15 | Godot 官方原文 — @rpc
@rpc
定义
@rpc 是 GDScript 中的一个注解(annotation),用来将一个函数标记为远程过程调用(Remote Procedure Call)。简单说,就是让一个函数可以通过网络在其他玩家的游戏实例上执行。
想象你在做一款多人游戏。当玩家 A 挥剑攻击时,你不仅要在玩家 A 的屏幕上播放攻击动画,还要告诉玩家 B 的游戏:"嘿,玩家 A 攻击了,你也播一下动画。" @rpc 就是负责这个"远程通知"的注解——你调用一个本地函数,Godot 会自动帮你在其他玩家的游戏里也调用这个函数。
在 C# 中,对应的写法是 [Rpc(MultiplayerApi.RpcMode.AnyPeer)] 等特性。
语法
C#
// 基本远程调用(任何客户端都可以调用)
[Rpc(MultiplayerApi.RpcMode.AnyPeer)]
public void RpcTakeDamage(int amount)
{
// 这个函数可以被远程调用
}
// 仅授权客户端可以调用
[Rpc(MultiplayerApi.RpcMode.Authority)]
public void RpcUpdatePosition(Vector3 position)
{
Position = position;
}GDScript
# 基本远程调用(任何客户端都可以调用)
@rpc func rpc_take_damage(amount: int):
pass
# 仅授权客户端可以调用
@rpc("authority") func rpc_update_position(position: Vector3):
pass
# 指定传输模式和调用模式
@rpc("any_peer", "call_remote", "unreliable")
func rpc_sync_position(position: Vector3):
pass参数说明
| 参数 | 类型 | 必需 | 默认值 | 说明 |
|---|---|---|---|---|
rpc_mode | String | 否 | "authority" | 谁可以调用这个 RPC。"authority" 表示只有权威节点(服务器/宿主)可以调用;"any_peer" 表示任何客户端都可以调用 |
sync_mode | String | 否 | "call_remote" | 调用方式。"call_remote" 只在远程执行;"call_local" 本地和远程都执行 |
transfer_mode | String | 否 | "unreliable_ordered" | 网络传输模式。"reliable" 保证送达;"unreliable" 不保证送达但更快;"unreliable_ordered" 不保证送达但保持顺序 |
transfer_channel | int | 否 | 0 | 传输通道号,用于区分不同优先级的数据包 |
返回值
@rpc 是一个注解,没有返回值。它改变的是函数的调用行为,让函数可以通过网络被远程触发。
代码示例
C#
using Godot;
public partial class Player : CharacterBody3D
{
// ===== 基础用法:标记 RPC 函数 =====
[Rpc(MultiplayerApi.RpcMode.AnyPeer)]
public void RpcTakeDamage(int amount)
{
GD.Print($"受到 {amount} 点伤害!");
}
public void AttackOtherPlayer()
{
// 调用所有远程客户端的 RpcTakeDamage
Rpc(MethodName.RpcTakeDamage, 25);
}
// 运行结果(远程客户端): 受到 25 点伤害!
// ===== 实际场景:同步位置信息 =====
[Export] public float ExMoveSpeed = 200f;
[Rpc(MultiplayerApi.RpcMode.Authority, CallLocal = false,
TransferMode = MultiplayerPeer.TransferModeEnum.Unreliable)]
public void RpcSyncPosition(Vector3 position, Vector3 velocity)
{
Position = position;
Velocity = velocity;
}
public override void _PhysicsProcess(double delta)
{
// 只有权威节点(服务器或宿主玩家)负责计算并同步位置
if (IsMultiplayerAuthority())
{
Vector3 velocity = Velocity;
// ... 移动逻辑 ...
Rpc(MethodName.RpcSyncPosition, Position, velocity);
}
}
// ===== 进阶用法:多种 RPC 模式组合 =====
// 聊天消息:任何客户端可以发送,所有人(包括自己)都能收到
[Rpc(MultiplayerApi.RpcMode.AnyPeer, CallLocal = true,
TransferMode = MultiplayerPeer.TransferModeEnum.Reliable)]
public void RpcSendChatMessage(string playerName, string message)
{
GD.Print($"[{playerName}]: {message}");
}
public void SendChat(string message)
{
Rpc(MethodName.RpcSendChatMessage, "玩家1", message);
}
// 运行结果: [玩家1]: 大家好!
// 游戏开始:只有服务器可以触发
[Rpc(MultiplayerApi.RpcMode.Authority, CallLocal = true,
TransferMode = MultiplayerPeer.TransferModeEnum.Reliable)]
public void RpcStartGame()
{
GD.Print("游戏开始!");
}
// 运行结果: 游戏开始!
}GDScript
extends CharacterBody3D
# ===== 基础用法:标记 RPC 函数 =====
@rpc func rpc_take_damage(amount: int):
print("受到 %d 点伤害!" % amount)
func attack_other_player():
# 调用所有远程客户端的 rpc_take_damage
rpc("rpc_take_damage", 25)
# 运行结果(远程客户端): 受到 25 点伤害!
# ===== 实际场景:同步位置信息 =====
@export var ex_move_speed: float = 200.0
@rpc("authority", "call_remote", "unreliable")
func rpc_sync_position(position: Vector3, velocity: Vector3):
self.position = position
self.velocity = velocity
func _physics_process(delta):
# 只有权威节点负责计算并同步位置
if is_multiplayer_authority():
var vel := velocity
# ... 移动逻辑 ...
rpc("rpc_sync_position", position, vel)
# ===== 进阶用法:多种 RPC 模式组合 =====
# 聊天消息:任何客户端可以发送,所有人都能收到(包括自己)
@rpc("any_peer", "call_local", "reliable")
func rpc_send_chat_message(player_name: String, message: String):
print("[%s]: %s" % [player_name, message])
func send_chat(message: String):
rpc("rpc_send_chat_message", "玩家1", message)
# 运行结果: [玩家1]: 大家好!
# 游戏开始:只有服务器可以触发
@rpc("authority", "call_local", "reliable")
func rpc_start_game():
print("游戏开始!")
# 运行结果: 游戏开始!注意事项
@rpc只能用于成员函数,不能用于静态函数或局部函数。- 调用 RPC 时使用
rpc("函数名", 参数...)的方式(GDScript)或Rpc(MethodName.函数名, 参数...)的方式(C#)。 - 默认模式是
"authority":只有拥有该节点多玩家权限的客户端才能远程调用。如果需要任何客户端都能调用,必须显式设置为"any_peer"。 - 传输模式选择:位置同步等高频数据用
"unreliable"(快但可能丢包);聊天消息、游戏状态等关键数据用"reliable"(保证送达但较慢)。 @rpc函数的参数和返回值必须是可序列化的类型(基本类型、Vector、Array 等),不能传递 Node 引用等不可序列化的对象。- C# 中使用
[Rpc(MultiplayerApi.RpcMode.模式)]特性,可以配合CallLocal和TransferMode参数。 - RPC 调用在没有连接多人服务器时不会生效(不会报错,但也不会远程执行)。
