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

Godot 4.1中如何动态对Rect2执行补间动画?

在Godot中为Rect2尺寸实现补间动画的解决方案

问题说明

想在Godot里给Rect2的尺寸做补间动画,但Rect2并非Object类型,tween_property()方法无法直接生效,因此尝试用tween_method()实现。tween_method()本身能正常工作,也能通过draw_rect()看到动画效果,但由于对象包含多个Rect2,希望通过.bind()传递要补间的Rect2引用给调用方法,结果发现.bind()只能按值传递得到副本,修改的是副本的尺寸而非原Rect2,需要动态解决这个问题。

原实例化代码

cross = Cross.new()
add_child(cross)

原Cross.gd代码

class_name Cross extends Node2D

var rect_1:Rect2
var rect_2:Rect2
var tween:Tween

func _init(r1=Rect2(400, 300, 50, 200), r2=Rect2(400, 300, 200, 50)):
    rect_1 = r1
    rect_2 = r2

# Called when the node enters the scene tree for the first time.
func _ready():
    tween = create_tween()
    tween.set_ease(Tween.EASE_IN_OUT)
    #tween.tween_method(change_width, 50, 0, 1)
    tween.tween_method(change_width_dyn.bind(self.rect_1), 50, 0, 1)

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
    queue_redraw()

func _draw():
    draw_rect(
        Rect2(
            rect_1.position.x - rect_1.size.x/2,
            rect_1.position.y - rect_1.size.y/2,
            rect_1.size.x,
            rect_1.size.y
        ), Color.WHITE
    )
    draw_rect(
        Rect2(
            rect_2.position.x - rect_2.size.x/2,
            rect_2.position.y - rect_2.size.y/2,
            rect_2.size.x,
            rect_2.size.y
        ), Color.WHITE
    )

func change_width(val:int):
    rect_1.size = Vector2(val, rect_1.size.y)
    print(rect_1)

func change_width_dyn(val:int, r:Rect2):
    r.size = Vector2(val, r.size.y)
    print(r)
    print(rect_1)

解决方案

实际上不需要用tween_method()绕路,Godot的tween_property()支持通过属性路径直接访问Rect2的子属性(比如size.x),即使Rect2是值类型,只要它是节点的成员变量,就能通过这种方式直接修改原对象的属性。

重构后的Cross.gd代码

class_name Cross extends Node2D

var rect_1:Rect2
var rect_2:Rect2
var tween:Tween

func _init(r1=Rect2(400, 300, 50, 200), r2=Rect2(400, 300, 200, 50)):
    rect_1 = r1
    rect_2 = r2

# Called when the node enters the scene tree for the first time.
func _ready():
    tween = create_tween()
    tween.set_ease(Tween.EASE_IN_OUT)
    tween.tween_property(self, "rect_1:size:x", 0, 1.0)
    tween.tween_property(self, "rect_2:size:y", 0, 1.0)
    tween.tween_property(self, "rect_1:size:x", 50, 2.0)
    tween.parallel().tween_property(self, "rect_2:size:y", 50, 2.0)

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
    queue_redraw()

func _draw():
    draw_rect(create_printable_rect(rect_1), Color.WHITE)
    draw_rect(create_printable_rect(rect_2), Color.WHITE)

func create_printable_rect(r:Rect2):
    return Rect2(
        r.position.x - r.size.x/2,
        r.position.y - r.size.y/2,
        r.size.x,
        r.size.y
    )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 17:43:19