Duplicate Scene, change Collision in code not unique

Godot Version

4.3

Question

I’m learning by creating a tower game. I’ve created a Scene with my Tower and an Area that represents how far the tower can see. This Area2D has a CollisionShape2D in it.
First, for ease of use, I thought to export a view_radius from the tower itself and then with a setter, set the radious of the collisionshape. This works BUT only on runtime, so it’s useless inside the editor. If I read it correctly , I need to make the whole gdscript executable with @tool. Is it correct? Isn’t there a better way in all what I’m doing? Should I have to add different areas for different “levels” of my tower? Right now I’m thinking to remove all the setter stuff and just test it by modifying it by hand every time I want to test a different radius.

The main question is another one though. If I have two towers and I change in code the CollisionShape2D of one, also the second one get modified. The reason seems to be that even if I create a new Tower (by dropping the tcsn in the main scene), the sub-objects of my Tower scene are not copied but they are all the same. I tried to click “Make Unique” on the dropdown of the CollisionShape selection but it does nothing. I’m not sure what I should do and even if it’s the optimal way to do that. What other devs do? Create a different scene for each level?

1 Like

So for the radius of your tower, you have exported the view_radius variable of your tower. You want to see the effects of modifying this radius at runtime. Is this correct? Can you explain more about what you want to test when setting your radius? There are two things that can help here:

  1. Set collision shapes as visible: Overview of debugging tools — Godot Engine (stable) documentation in English
  2. The remote scene dock: Overview of debugging tools — Godot Engine (stable) documentation in English

I am not sure if your view_radius will update properly if you set it in the remote scene dock, but you could change the size of the area’s collisionshape there as an alternative.

As for your duplicate collisionshape2d:
instead of dropping the tscn on your main scene, try right-clicking the main scene and selecting “instantiate child scene” and select your tower scene. This should create unique instances of your towers. When this works, you do not need multiple collisionshapes for different levels, you can just set the size of the current shape in each instance.

1 Like

This is the code:

The idea was to be able to see the change in the editor:

image

But when I change it, I don’t see any change on the 2D view (big circle):
image

I knew trick 1, thanks. That’s how I discovered the problem of duplicate().
The trick 2 is then not useful for that. Thanks anyway I might need it later.

If it’s not possible I think I have to create several scenes for each different radius.
Anyone with experience in “Tower upgrades” or any kind of Object upgrade like that? I thought that was the way to test several radiuses but if it’s not possible I might change my testing strategy. (Note: “testing” as deciding the balance between enemies and towers, not debugging)

Regarding the duplicate: thanks for the tip. It will make any child unique. I wonder why it’s not the case, maybe performance? Then how to avoid that all are unique and just have the tower unique? Also I’m not sure why that is the solution. I have several enemies duplicate() on main and they all have their own health (a float on the node/script). All sub-items are then all linked to the same? Seems counter intuitive (apologies if that offends a godot developer.). I’m trying to remember if it’s the same in other languages (python mainly).
Having said that, it seems that the best solution / most generic one that balances complexity and speed is to create a new collisionshape2d every time. Something that I didn’t do.

[2 minutes later… ]

This code works!

Now for the picky one (not me): what happens if I do this a million times? I suppose nothing because the old one get Garbage-collected. Or should I add $Visibility/VisibilityShape.shape.Free() before setting = s again?

1 Like

little reply to myself for future reference:
the code works for the duplicate issue.
To see the changes on the 2d editor dynamically I still have no idea if it’s doable.