如何在 Godot 中以编程方式创建 SubViewport + ViewportTexture?

blu*_*e10 3 viewport godot

我正在尝试在 Godot 4 中以编程方式创建一个SubViewport组合。ViewportTexture我的最小示例如下所示:

# This node is the root of my scene tree, and the only static node in the tree.
extends Node


func _ready():
    # Create the viewport, add something to it, and add it to the scene tree:
    # Note that setting UPDATE_ALWAYS doesn't help.
    var viewport = SubViewport.new()
    viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
    add_something_to_viewport(viewport)
    add_child(viewport)
    
    # Now that the viewport has a path, we can create a texture and connect it:
    var viewport_texture = ViewportTexture.new()
    viewport_texture.viewport_path = viewport.get_path()

    # Finally create a sprite that uses the viewport texture:
    var sprite = Sprite2D.new()
    sprite.centered = false
    sprite.texture = viewport_texture # <== this line causes debugger errors
    add_child(sprite)


func add_something_to_viewport(viewport: SubViewport):
    var label = Label.new()
    label.text = "Hello world"
    viewport.add_child(label)
Run Code Online (Sandbox Code Playgroud)

(或使用语法突出显示以获得更好的可读性)

在此输入图像描述

不幸的是,视口的内容不可见,相反我看到了调试器错误,例如:

get_height: Viewport Texture must be set to use it
get_width: Viewport Texture must be set to use it
Run Code Online (Sandbox Code Playgroud)

blu*_*e10 6

最初我怀疑这是 Godot 中的一个错误并提出了这个问题。一些有帮助的人指出我只是误解了设置 aviewport_path的作用ViewportTexture。显然,此功能仅由编辑器内部使用,而不是您应该以编程方式将视口纹理与视口连接的方式。

幸运的是,该解决方案比通过节点路径更简单,甚至更干净。无需手动构造ViewportTexture,只需调用即可直接Viewport.get_texture()获取ViewportTexture实例。这对我来说效果很好:

extends Node


func _ready():
    # Create the viewport, add something to it, and add it to the scene tree:
    var viewport = SubViewport.new()
    add_something_to_viewport(viewport)
    add_child(viewport)
    
    # Finally create a sprite that uses the viewport texture:
    var sprite = Sprite2D.new()
    sprite.centered = false
    sprite.texture = viewport.get_texture() # Just get the texture directly.
    add_child(sprite)


func add_something_to_viewport(viewport: SubViewport):
    var label = Label.new()
    label.text = "Hello world"
    viewport.add_child(label)
Run Code Online (Sandbox Code Playgroud)