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

Godot 4多人RPG游戏主机与客户端建筑同步异常问题求助

多人RPG游戏网格系统物品放置同步异常问题求助

问题现象

  • 主机放置物品后仅自身可见,编辑器Remote标签页的PlayerBuildings节点下无显示
  • 客户端放置物品后仅自身可见,Remote标签页有显示

报错信息

get_node: Node not found:"World/PlayerBuildings/@Camp1@3/MultiplayerSynchronizer" process_simplify_path: Condition "node == nullptr" is true.

节点树截图

节点树截图

网格系统代码

extends Node2D

@onready var camp_fire = preload("res://src/Scenes/camp.tscn")
var tile_size =16

enum {OBSTACTLE, COLLECTABLE,RESOURCE}
var grid_size = Vector2(160,160)
var grid = []


func _ready():
    for x in range(grid_size.x):
        grid.append([])
        for y in range(grid_size.y):
            grid[x].append(null)
    var positions = []
    for i in range (50):
        var xcoor = (randi() % int(grid_size.x))
        var ycoor = (randi() % int(grid_size.y))
        var grid_pos = Vector2(xcoor,ycoor)
        if not grid_pos in positions:
            positions.append(grid_pos)

func _input(event):
    if GameManager.enable:
        if event.is_action_pressed("LeftClick"):
            var mouse_pos = get_global_mouse_position()
            var multiX = int(round(mouse_pos.x)/tile_size)
            var numX = multiX*tile_size
            var multiY = int(round(mouse_pos.y)/tile_size)
            var numY = multiY*tile_size
            var new_pos = Vector2(multiX, multiY)
            var new_camp_fire = camp_fire.instantiate()
            new_camp_fire.name = str(new_camp_fire.name + str(multiplayer.get_unique_id()) )
            new_camp_fire.set_position(tile_size*new_pos)
            grid[multiX][multiY] = OBSTACTLE
            get_tree().root.get_node("World").get_node("PlayerBuildings").add_child(new_camp_fire)

解决方案

1. 切换到权威服务器架构

Godot多人游戏必须遵循服务器权威原则,所有节点创建/销毁操作由服务器统一处理,客户端仅发送请求,避免本地实例化导致的不同步。修改代码如下:

extends Node2D

@onready var camp_fire = preload("res://src/Scenes/camp.tscn")
var tile_size =16

enum {OBSTACTLE, COLLECTABLE,RESOURCE}
var grid_size = Vector2(160,160)
var grid = []


func _ready():
    for x in range(grid_size.x):
        grid.append([])
        for y in range(grid_size.y):
            grid[x].append(null)
    var positions = []
    for i in range (50):
        var xcoor = (randi() % int(grid_size.x))
        var ycoor = (randi() % int(grid_size.y))
        var grid_pos = Vector2(xcoor,ycoor)
        if not grid_pos in positions:
            positions.append(grid_pos)

func _input(event):
    if GameManager.enable:
        if event.is_action_pressed("LeftClick"):
            var mouse_pos = get_global_mouse_position()
            var multiX = int(round(mouse_pos.x)/tile_size)
            var multiY = int(round(mouse_pos.y)/tile_size)
            var grid_pos = Vector2(multiX, multiY)
            
            # 客户端请求服务器放置,服务器直接执行
            if multiplayer.is_client():
                rpc("request_place_campfire", grid_pos)
            else:
                if grid[grid_pos.x][grid_pos.y] == null:
                    place_campfire(grid_pos)

# 允许任意节点调用的RPC,仅服务器处理逻辑
@rpc("any_peer")
func request_place_campfire(grid_pos):
    if multiplayer.is_server() and grid[grid_pos.x][grid_pos.y] == null:
        place_campfire(grid_pos)

# 服务器统一执行的放置逻辑
func place_campfire(grid_pos):
    var new_camp_fire = camp_fire.instantiate()
    new_camp_fire.name = str(new_camp_fire.name + str(multiplayer.get_unique_id()))
    new_camp_fire.set_position(tile_size * grid_pos)
    new_camp_fire.set_network_master(1) # 设置服务器为节点主控
    
    grid[grid_pos.x][grid_pos.y] = OBSTACTLE
    get_tree().root.get_node("World/PlayerBuildings").add_child(new_camp_fire)

2. 修复MultiplayerSynchronizer报错

  • 打开camp.tscn,确保场景根节点下包含MultiplayerSynchronizer节点
  • 配置同步器的Properties列表,添加需要同步的属性(比如position、visible等)
  • 检查节点路径:确保同步器的Root Path设置正确,避免找不到节点的报错

3. 同步网格状态

服务器维护唯一的网格数据,客户端需要通过RPC同步网格状态,避免本地网格与服务器不一致。可以在服务器放置物品后,广播网格更新:

# 在place_campfire函数末尾添加
rpc("sync_grid_update", grid_pos, OBSTACTLE)

@rpc("all")
func sync_grid_update(grid_pos, tile_type):
    grid[grid_pos.x][grid_pos.y] = tile_type

4. 验证Remote标签页显示

修改后,服务器(主机)创建的节点会出现在Remote标签页的PlayerBuildings下,所有客户端会同步显示该节点,解决之前的可见性不一致问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 20:05:30