如何以编程方式更改动画精灵的纹理

How to change the texture of AnimatedSprite programatically

我已经创建了一个基础场景,我打算将其用于游戏中的所有人类角色。我正在使用 AnimatedSprite,我在其中为角色的不同位置定义了不同的动画,所有动画都使用包含所有帧的纹理。

这适用于特定角色,但现在我想创建其他角色。由于我使用的是角色生成器,所以所有精灵表基本相同,但衣服、配饰等不同。我想避免复制其他角色的动画定义。我可以通过在场景的每个实例上设置不同的纹理来实现这一点,但我找不到实现它的方法。

如果我编辑 tscn 文件并设置不同的图像,它会执行我想要的操作。

我尝试更新动画帧的 atlas 属性,但这样做会影响场景的所有实例:

func update_texture(value: Texture):
    for animation in $AnimatedSprite.frames.animations:
        for frame in animation.frames:
            frame.atlas = value

我还尝试通过调用 duplicate(0) 克隆一个 SpriteFrames 实例,用上面的代码更新它,然后设置 $AnimatedSprite.frames,但这也会更新场景的所有实例。

更改特定 AnimatedSprite 实例的纹理的正确方法是什么?

我找到了解决办法。问题是 duplicate 方法不执行深度克隆,所以我引用了相同的帧实例。 这是我的更新版本:

func update_texture(texture: Texture):
    var reference_frames: SpriteFrames = $AnimatedSprite.frames
    var updated_frames = SpriteFrames.new()
    
    for animation in reference_frames.get_animation_names():
        if animation != "default":
            updated_frames.add_animation(animation)
            updated_frames.set_animation_speed(animation, reference_frames.get_animation_speed(animation))
            updated_frames.set_animation_loop(animation, reference_frames.get_animation_loop(animation))
            
            for i in reference_frames.get_frame_count(animation):
                var updated_texture: AtlasTexture = reference_frames.get_frame(animation, i).duplicate()
                updated_texture.atlas = texture
                updated_frames.add_frame(animation, updated_texture)

    updated_frames.remove_animation("default")

    $AnimatedSprite.frames = updated_frames