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

Godot 4.2多人模式下用户上传图片无法在其他客户端显示求助

Godot 4.2多人游戏图片同步问题:上传图片仅本地可见

我是Godot新手,在用Godot 4.2开发多人游戏时遇到问题:通过rpc和本地主机实现多人联机,使用文件对话框上传图片后,仅本地客户端能显示图片,其他客户端无法看到。尝试过将图片以base64格式传递,但找不到适用于Godot 4的正确写法,恳请帮助。

相关代码片段:

# Individual player joining game
@rpc("any_peer", "call_local")
func send_player_information(name_entry):
    
    GameManager.Players.append({
        "name": name_entry, 
        "score": 0,
        "prompt": "",
        "image": PackedByteArray(),
    })
func _on_file_dialog_file_selected(path):
    var image = Image.load_from_file(path)
    var texture = ImageTexture.create_from_image(image)
    
    # Saving file paths to a file
    #var file = FileAccess.open("res://photo-paths.txt", FileAccess.WRITE)
    #file.store_string(path)
    
    var raw_data = image.save_png_to_buffer()
    
    image = Image.new()
    var err = image.load_png_from_buffer(raw_data)
    if err != OK:
        printerr("Image loading error: " + str(err))
        return
    texture = ImageTexture.create_from_image(image)
    $ImageUploadScene/Image.texture = texture
    
    
    imagesUploaded += 1
    
    rpc("on_image_uploaded", player_id, raw_data)
    
    
    # Checking if the images uploaded equals the number of players in the game
    
    players = GameManager.Players.size()
    if imagesUploaded >= players:
        
        $ImageUploadScene.hide()
        $PresentationScene.show()
        rpc("presentation")


# Upload an image to the player function
@rpc("any_peer", "call_local")
func on_image_uploaded(id: int, image_base64: String):
    GameManager.Players[id].image = image_base64


@rpc("any_peer", "call_local")
func presentation():
    
    var i = 0
    players = GameManager.Players.size()
    
    while (i < players):
        
        $PresentationScene/Prompt.text = GameManager.Players[i].prompt
        $PresentationScene/Name.text = GameManager.Players[i].name
        
        
        # Load in the image
        rpc("update_player_image_display", i)
        
        
        # Start timer
        $PresentationScene/Timer.start(25.0)
        await $PresentationScene/Timer.timeout
        
        i += 1
    
    $PresentationScene.hide()
    $VotingScene.show()
    rpc("voting")


@rpc("any_peer", "call_local")
func update_player_image_display(i):
    # Load in the image
    var image = Image.new()
    var raw_data = GameManager.Players[i].image
    var err = image.load_png_from_buffer(raw_data)
    if err != OK:
        printerr("Image loading error: " + str(err))
        return
    var texture = ImageTexture.create_from_image(image)
    
    $PresentationScene/Image.texture = texture

问题分析与解决方案

核心问题

代码存在类型不匹配的关键错误:

  • 上传时通过rpc传递的是PackedByteArray类型的raw_data,但on_image_uploaded函数定义的参数却是String类型的image_base64,导致其他客户端无法正确解析图片数据。
  • send_player_information中初始化image为PackedByteArray(),但后续赋值成了字符串,类型不一致直接导致加载失败。

直接修正方案(无需base64)

修改on_image_uploaded的参数类型为PackedByteArray,保持数据类型一致:

@rpc("any_peer", "call_local")
func on_image_uploaded(id: int, image_data: PackedByteArray):
    GameManager.Players[id].image = image_data

调用rpc的代码无需修改(raw_data已经是正确的PackedByteArray类型),这样其他客户端就能正确接收并存储图片数据,后续update_player_image_display函数可正常加载显示。

若需使用base64格式(Godot 4写法)

如果担心二进制数据传输问题,可通过PackedByteArray的内置方法转换为base64字符串传递:

  1. 上传时转换为base64:
var raw_data = image.save_png_to_buffer()
var base64_data = raw_data.to_base64()
rpc("on_image_uploaded", player_id, base64_data)
  1. 接收时转换回PackedByteArray:
@rpc("any_peer", "call_local")
func on_image_uploaded(id: int, image_base64: String):
    var image_data = PackedByteArray.from_base64(image_base64)
    GameManager.Players[id].image = image_data

update_player_image_display函数无需修改,仍可正常加载图片。

额外注意事项

  • 确保GameManager.Players在所有客户端的玩家ID对应关系一致,避免索引错误导致图片加载失败。
  • 确认rpc的调用模式("any_peer"+"call_local")符合需求,该模式会让所有peer调用本地函数,需保证同步逻辑正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 23:27:34