如何通过编程方式修改AnimatedSprite特定实例的纹理
修改AnimatedSprite特定实例纹理的正确方案
问题根因
你遇到的问题本质是Godot中SpriteFrames属于共享资源:默认同一场景的所有实例会共用同一份SpriteFrames资源,修改任何一个实例的资源属性都会同步到所有实例。你之前使用duplicate(0)属于浅拷贝,仅复制了SpriteFrames的外层结构,内部的帧资源依然和原资源共享,因此修改后还是会影响全部实例。
方案1:深拷贝SpriteFrames资源
该方案不需要修改原有动画配置逻辑,只需要在每个实例初始化时生成独立的动画资源即可,代码如下:
func update_character_texture(new_texture: Texture): # 对原有SpriteFrames做深拷贝,参数7表示对内部子资源也做完整拷贝 # Godot 4中可直接写作 $AnimatedSprite.frames.duplicate(DUPLICATE_DEEP_RESOURCES) var independent_frames = $AnimatedSprite.frames.duplicate(7) # 遍历所有动画的所有帧替换精灵表纹理 for anim_name in independent_frames.get_animation_names(): for frame_idx in range(independent_frames.get_frame_count(anim_name)): independent_frames.get_frame(anim_name, frame_idx).atlas = new_texture # 将独立的动画资源绑定到当前实例的AnimatedSprite $AnimatedSprite.frames = independent_frames
方案2:Shader动态替换纹理(推荐,性能更高)
如果所有角色的精灵表结构(帧大小、帧序列、坐标偏移)完全一致,可以用Shader实现无感知的纹理替换,完全不需要操作动画资源,性能更好,适配性更高:
- 给AnimatedSprite新建一个CanvasItem材质,使用如下Shader:
shader_type canvas_item; // 传入自定义的角色精灵表,filter_nearest保证像素风格精灵清晰 uniform sampler2D custom_spritesheet: filter_nearest; void fragment() { // 复用原有动画的UV坐标采样新的精灵表 COLOR = texture(custom_spritesheet, UV); }
- 运行时只需要修改Shader参数即可替换纹理,不会影响其他任何实例:
func update_character_texture(new_texture: Texture): $AnimatedSprite.material.set_shader_parameter("custom_spritesheet", new_texture)
内容的提问来源于stack exchange,提问作者Antoine Aubry
相关产品推荐
相关产品推荐

