Hi there, I have an instance of node which I would like to display in several distinct places, is there a pattern to do that in godot?

To give a bit more context: This node represent a "character" in a game, and is a custom type derivating from Node2D. It should be displayed both on the main map (as a child of a viewport) and on an UI box showing the "selected" character. It has itself several children nodes (like a weapon, a lifebar, ...) which should be displayed with it. I could of course duplicate the instance, but that would mean duplicating also the children, and updating the character would be difficult to manage without a lot of code duplication (or to say it otherwise, without a lot of bugs.)

(The kind of solution I would expect: - I would have a "main" instance of the node, as a child of the viewport - and I would have a "node viewer" as child of the UI, with a reference (but not as a child) to the main node, and some code to draw the main node at the position of the node viewer. But I do not know how to do this part.) Any advice on how I could do this?

Why just not duplicate it without children? Btw what's the node's graphical content? AFAIK Node2D is not visible unless you implement custom drawing function.

Why just not duplicate it without children?

Because I also want to display the children in both places, ie I want to display twice the exact same character with the same weapon, lifebar, animations, ...

Btw what's the node's graphical content? AFAIK Node2D is not visible unless you implement custom drawing function. Right, there is also a sprite child with the head of the character

Make your character into a scene and just instance that scene as many times as you need. In general, scenes can be configured in such a way that all instances behave like clones (all resources shared), or conversely, each instance can have fully or partially unique resources (resources duplicated at the moment of instancing)

Make your character into a scene and just instance that scene as many times as you need. In general, scenes can be configured in such a way that all instances behave like clones (all resources shared), or conversely, each instance can have fully or partially unique resources (resources duplicated at the moment of instancing)

I am using the same scene for several different characters, with dynamic instanciation. (One distinct scene by character is not an option.) Is it possible to have say "instance2" as a clone of "instance1", and "instance3" independent from those?

It really depends on the scene setup.

Duplicating the instance after it has been configured as a particular character could do the trick.

You could also put that scene into a wrapper scene and then instance that wrapper scene. This'll get rid of all eventual code duplication.

If that still doesn't work for you, perhaps post the entire scene structure and how you configure it to represent different characters. Then it'd be easier to suggest more specific solution.

If you need exact realtime visual replica of the character (with animations etc.) then reasonable option is to render it to a separate viewport and use it as a texture in all places needed.

Thanks for those answers!

If you need exact realtime visual replica of the character (with animations etc.) then reasonable option is to render it to a separate viewport and use it as a texture in all places needed.

Yes! This looks the kind of solution I was looking for. Maybe you would have some pointers to more details about it? (else... well I can try :) ) I wonder also if I should expect a significant perfs overhead? I would need say 50 to 500 such instances, each with their own viewport. (The size if each texture should stay reasonably small, about 100x100)

You could also put that scene into a wrapper scene and then instance that wrapper scene. This'll get rid of all eventual code duplication. I did not understand this one.

If that still doesn't work for you, perhaps post the entire scene structure and how you configure it to represent different characters. Then it'd be easier to suggest more specific solution.

Sure! Simplifying a bit, my scene representing one character looks as follow:

CharacterNode: 2DNode Sprite characterImage Sprite weapon Node2D lifebar HBoxContainer iconsContainer // containing several sprites displaying lasting effects

The state of weapon, lifebar and iconsContainer may change during the game ( eg character.TakeDamage() would modify the lifebar ) I have a lot of instances of this scene, representing different characters. They are all displayed on a viewport showing the main map. One (but not always the same) should also be displayed on a UI container.

Maybe I could also add the solution I have been thinking to since yesterday: I suppose I could use some kind of "Observer" pattern, where I would have a non-displayable character Node, with a method to spawn a new instance of a Node2D which "observes" this node. The character node would send messages whenever its state changes. The Node2D would have a script to listen to those messages, and update their own graphic elements as required. This way I can "simply" spawn several nodes observing the same character. Only issue I foresee with this method: it adds one layer of indirection (posting && receiving the messages) to every state change on the character, which makes it a bit slower to dev.

@alex_sand said: I did not understand this one.

It actually may be the easiest approach.

You need some code to configure the character, right? This code typically runs outside of the character scene so you can configure each character differently. However if you put some such code inside the scene, then all instances will run it, configuring the character in exactly the same way.

So for a character that needs a clone, place an instance of original character scene into another empty scene (the wrapper scene). To that placed instance then attach a script with all code that needs to be shared among clones. Now you can instance the wrapper scene multiple times and all instances will behave the same, to an extent of what is controlled via the shared code.

@alex_sand And yeah, something like observer is a good idea too, if character is not overly complex. The clone could just be a non hierarchical collection of sprites that mimick the original only in appearance. Each sprite in the clone corresponding to a sprite in the original, holding a reference to it. The clone would then each frame just copy the world space transforms and textures from the corresponding master sprite. The only signaling you really need is in case of adding/removing sprites in the original. In that case the clone would need to do so as well.

In fact I'd vote for this solution, especially if all characters have same/similar structure and all visual elements are sprites. Once you set up the system there's no additional work needed to clone any character or multiple characters at once.

a year later