Search code examples
texturesgodotgdscript

Godot: How to pass texture as a parameter to a scene


I have a scene that represents a type of NPC. These NPCs have the same behavior and same animations. The only difference is that they look slightly different (e.g. they're wearing differently colored clothes). So I have multiple slightly different spritesheets PNG files (they all contain exactly the same amount of frames).

How could I make the specific spritesheet image easily configurable for a scene instance?

What I tried

With this scene structure:

enter image description here

I managed to implement something like this:

extends KinematicBody2D

export(Texture) var texture

func _ready():
    $Sprite.texture = texture

This sort-of works, but gives me bunch of errors like:

scene/animation/animation_tree.cpp:828 - Condition "!track_cache.has(path)" is true. Continuing.

It also creates a really crappy experience as the image no more shows up in the editor - one can only see it when actually running the game.

Additionally

In reality not all of these NPC-s have exactly similar spritesheets. They have animations with the same names, but one NPC might have a 2-frame idle animation, while another might have a longer 20-frame idle animation.

I'm wondering whether I could configure both the SpriteSheet and AnimationPlayer (defining frames for each animation) for each instance of this NPC scene?


Solution

  • How could I make the specific spritesheet image easily configurable for a scene instance?

    Use secondary click on the instance on the scene panel, and on the context menu enable "Editable Children".


    scene/animation/animation_tree.cpp:828 - Condition "!track_cache.has(path)" is true. Continuing.

    If everything is OK, these should go away by reloading the project. In fact, I think this is unrelated, unless you are animating the texture.


    It also creates a really crappy experience as the image no more shows up in the editor - one can only see it when actually running the game.

    If you want your code to run on the editor make your code a tool script.

    You can check if your code is running on the editor by checking Engine.editor_hint.

    Also, you probably want to use a setter (with setget).


    I'm wondering whether I could configure both the SpriteSheet and AnimationPlayer (defining frames for each animation) for each instance of this NPC scene?

    Keep it simple. Although you can use a tool script and so on, I do believe "Editable Children" is the better and simpler solution. That will allow you to configure the instances you add in the scene panel.

    However, that is per instance and only instances added in the scene panel. Thus, consider also creating inherited scenes with the modifications. You can create inherited scenes from the file system panel, on the context menu opened by secondary click on the scene file select "New Inherited Scene".