MultiplayerSpawner
2026/4/14大约 5 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — MultiplayerSpawner
MultiplayerSpawner
节点继承关系
继承链:Node → MultiplayerSpawner
继承自 Node
| 类型 | 名称 | 说明 |
|---|---|---|
| 属性 | Name | 节点名称 |
| 属性 | ProcessMode | 处理模式(始终 / 暂停时 / 仅编辑器) |
| 属性 | ProcessPriority | 处理优先级,数字越小越先执行 |
| 信号 | ready | 节点进入场景树并准备就绪 |
| 信号 | tree_entered | 节点进入场景树 |
| 信号 | tree_exited | 节点完全离开场景树 |
| 方法 | GetNode<T>() | 按路径获取子节点 |
| 方法 | AddChild() | 添加子节点 |
| 方法 | RemoveChild() | 移除子节点 |
| 方法 | QueueFree() | 帧结束后释放节点 |
| 方法 | GetParent() | 获取父节点 |
定义
在网络中自动同步生成和删除节点的管理器——服务器说"这里冒出一颗子弹",所有客户端自动跟着冒。
想象你在玩一个在线射击游戏,你开了一枪,屏幕上出现了一颗子弹。同时,和你一起玩的朋友屏幕上也出现了一颗一模一样的子弹。这个"让所有玩家的屏幕同步出现相同东西"的工作,就是 MultiplayerSpawner 做的。
使用频率:★★ 偶尔使用——几乎每个多人游戏都会用到。
节点用途
- 子弹:玩家开枪时,服务器创建子弹节点,所有客户端同步出现
- 玩家角色:新玩家加入时,服务器生成角色,所有人看到
- 掉落物品:怪物死亡时掉落宝箱,全服同步
- 特效:爆炸、魔法等需要在所有人屏幕上出现的效果
使用场景
典型场景
- 射击游戏:玩家开枪时服务器端生成子弹,客户端自动同步
- 多人 RPG:新玩家加入时生成角色模型,所有人可见
- 生存游戏:怪物死亡掉落物品,全服玩家都能看到
不适用场景
- 需要同步已有节点的属性变化(位置、血量等) → 使用 MultiplayerSynchronizer
- 需要调用远程函数 → 使用 RPC(
@rpc装饰器) - 需要和 Web 服务器通信 → 使用 HTTPRequest
常用节点搭配
| 搭配节点 | 用途 | 必需? |
|---|---|---|
| MultiplayerSynchronizer | 同步生成节点的属性变化(如位置、旋转) | 推荐 |
| ENetMultiplayerPeer | 建立网络连接(服务器/客户端) | 必需 |
| PackedScene(场景资源) | 指定要实例化的场景模板 | 必需 |
典型节点树:
NetworkManager (Node)
├── ENetMultiplayerPeer(网络连接)
├── BulletContainer (Node) ← spawn_path 指向这里
│ └── MultiplayerSpawner
│ └── (自动同步生成的子弹节点会出现在 BulletContainer 下)
└── PlayerContainer (Node)
└── MultiplayerSpawner
└── (自动同步生成的玩家角色会出现在 PlayerContainer 下)生效必备素材/资源
| 资源 | 类型 | 说明 |
|---|---|---|
| PackedScene(场景资源) | Scene 资源 | 在 spawn_path 下需要生成节点的场景模板,服务器和客户端都必须拥有相同的场景文件 |
节点属性与信号
生成配置
| 属性 | 类型 | 默认值 | 继承自 | 说明 |
|---|---|---|---|---|
SpawnPath | NodePath | .. | — | 监视的节点路径,新节点在这个路径下生成 |
SpawnLimit | int | 0 | — | 同时存在的最大生成数量(0 = 无限) |
SpawnOrder | int | 0 | — | 生成顺序:0(递增)/ 1(递减)/ 2(随机) |
高级配置
| 属性 | 类型 | 默认值 | 继承自 | 说明 |
|---|---|---|---|---|
SpawnFunction | Callable | null | — | 自定义生成函数(替代默认的 PackedScene.Instantiate()) |
SpawnableScene | PackedScene[] | [] | — | 可生成的场景列表(在编辑器中配置) |
信号
| 信号 | 触发时机 | 继承自 | 说明 |
|---|---|---|---|
spawned(node) | 新节点被同步生成时 | — | 在服务器和客户端上都会触发,参数是生成的节点实例 |
despawned(node) | 节点被同步删除时 | — | 在服务器和客户端上都会触发,参数是被删除的节点实例 |
常用方法
| 方法 | 返回值 | 说明 |
|---|---|---|
GetSpawnableScenes() | StringName[] | 获取所有可生成的场景路径列表 |
SetSpawnableScene(idx, scene) | void | 设置指定索引的可生成场景 |
GetSpawnPath() | NodePath | 获取当前监视的节点路径 |
SetSpawnPath(path) | void | 设置监视的节点路径 |
IsSpawning() | bool | 是否正在生成中 |
代码示例
C
using Godot;
/// <summary>
/// 子弹管理器——演示 MultiplayerSpawner 的自动同步生成
/// 节点结构:BulletManager (Node3D) + MultiplayerSpawner(子节点)
/// </summary>
public partial class BulletManager : Node3D
{
[Export] public PackedScene BulletScene { get; set; }
/// <summary>
/// 在服务器上生成一颗子弹
/// MultiplayerSpawner 会自动将这个子弹同步到所有客户端
/// </summary>
public void SpawnBullet(Vector3 startPos, Vector3 direction)
{
// 只有权威端(服务器)才能生成
if (!Multiplayer.HasMultiplayerPeer() || !IsMultiplayerAuthority())
return;
Node3D bullet = BulletScene.Instantiate<Node3D>();
bullet.Position = startPos;
// 设置子弹的运动方向(自定义脚本)
var bulletScript = bullet as Bullet;
if (bulletScript != null)
bulletScript.SetDirection(direction);
// 添加到场景树 → MultiplayerSpawner 会自动同步到客户端
AddChild(bullet, true);
}
}GDScript
# 子弹管理器——演示 MultiplayerSpawner 的自动同步生成
# 节点结构:BulletManager (Node3D) + MultiplayerSpawner(子节点)
extends Node3D
@export var bullet_scene: PackedScene
## 在服务器上生成一颗子弹
## MultiplayerSpawner 会自动将这个子弹同步到所有客户端
func spawn_bullet(start_pos: Vector3, direction: Vector3) -> void:
# 只有权威端(服务器)才能生成
if not multiplayer.has_multiplayer_peer() or not is_multiplayer_authority():
return
var bullet = bullet_scene.instantiate()
bullet.position = start_pos
# 设置子弹的运动方向(自定义脚本)
if bullet.has_method("set_direction"):
bullet.set_direction(direction)
# 添加到场景树 → MultiplayerSpawner 会自动同步到客户端
add_child(bullet, true)MultiplayerSpawner 的工作原理
- 服务器端:在
spawn_path下添加子节点(如子弹) - 自动同步:MultiplayerSpawner 自动将节点信息发送给所有客户端
- 客户端:收到节点信息后自动实例化相同的场景,添加到
spawn_path下 - 删除同步:服务器删除节点时,客户端也自动删除对应节点
你不需要写任何网络同步代码,只要在服务器上 AddChild(),剩下的 MultiplayerSpawner 全帮你搞定。
