+8 votes

I have an enemy scene that doesn't inherit anything, but now I want it to inherit a scene called damageable. How do I change the inheritance of the enemy scene?

in Engine by (53 points)

Don't know if will work as you expect but try making a new scene that inherits "damageable" and merge with your actual "enemy" (right click on the tree you have the option to merge scenes),.

That sadly didn't work.

4 Answers

+7 votes
Best answer

In the end I had to hand edit the scene file to change the inheritance of the scene. A quick run down of what I did:

added 1 to the loadsteps in

[gd_scene load_steps=3 format=1]
                     ↓
[gd_scene load_steps=4 format=1]

added a line to load the resource to inherit from

[ext_resource path="res://scenes/objects/damageable.tscn" type="PackedScene" id=1]

added 1 to all the other ext_resource's id and the lines where these are used

[ext_resource path="res://scripts/objects/enemy.gd" type="Script" id=1]
                                                                     ↓
[ext_resource path="res://scripts/objects/enemy.gd" type="Script" id=2]

&

script/script = ExtResource( 1 )
                             ↓
script/script = ExtResource( 2 )

and I removed the first node's type and replaced it with the inherited scene

[node name="enemy" type="RigidBody2D"]
                   ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
[node name="enemy" instance=ExtResource( 1 )]

Maybe I could've just given the scene to inherit from the last id, but I was afraid that that might somehow bite me later on.

by (53 points)

For someone stumbling up on this in the future (I'm using Godot 3.1 alpha 5),

You don't actually have to add the PackedScene extresource as id=1 and add 1 to every other extresource 'cause that would be too fiddly if you have dozens of nodes. Instead add it to the bottom with the next id available. Also no need to increase the load_steps.


To illustrate,
say you have 6 ext_resources in your .tscn file.
Add this but with id=7 instead of id=1,

[ext_resource path="res://scenes/objects/damageable.tscn" type="PackedScene" id=7]

Then edit

[node name="enemy" type="RigidBody2D"]

to

[node name="enemy" instance=ExtResource( 7 )]

You're done! :D

Worked perfectly, and was easier than expected. Thanks!

As an additional step to what Dlean Jeans said, in Godot 3.4.4 you are gonna wanna delete the type (or instance) of any node that's also in the inherited scene, for example, if you have a hurtbox node both in enemy.tscn and in damageable.tscn, and you want both nodes to be one and the same in enemy.tscn, you'll have to change

[node name="hurtbox" type="Area2D" parent="pivot"]

to

[node name="hurtbox" parent="pivot"]

in the enemy.tscn file.
Otherwise both nodes will coexist in a weird state where neither displays the changes enemy might have applied to it.

Note that this will also reorder the nodes, as the inherited nodes take precedence over non-inherited nodes. That is:
- if all nodes are non-inherited and they have no set index in the file, they will be listed in the order they are mentioned
- if some nodes are inherited and others are non-inherited, and they have no set index, the inherited nodes will be listed first
- if a node has a set index ([node name="hurtbox" parent="pivot" index="3"]), then its order will be respected regardless of whether it is an inherited or non-inherited node

So if you have non-inherited nodes that should be higher up in the childlist of the node, you'll have to either set their index in the file by hand or reorder them in the editor.
Saving the file in the editor for the first time will set indexes for every node in a way that reflects the way the tree was rendered in-editor when it was saved, it will also update the load_steps and remove unused resources. None of this will break or alter the scene.

+1 vote

I'm afraid you can't in the actual stand of Godot Editor. You can only replace the root node with an standard node.

by (703 points)

That's annoying, sounds like a normal capability to me.

+9 votes

One way to do this through GUI is by merging scenes.

I did this by inheriting a new scene from the parent, merging it with the scene you want to be a child scene and then saving it by replacing at the place of that scene, so it does not break any links.

For example:
Parent scene : Machine
Wannabe Child scene : Aeroplane
inherited new scene (from Machine) : new_aeroplane (not yet saved)

Now merge Aeroplane with newaeroplane, (from newaeroplane scene)

Save new_aeroplane as Aeroplane to preserve links

by (32 points)

This way is safer!

This seems to work quite well.

0 votes

This is an update to Steven Vroom's answer to contemplate a few circumstances and correct some steps

Given a parentclass.tscn file and a subclass.tscn file, where subclass.tscn doesn't currently inherit parentclass.tscn, but you want it to.
The steps are as follow:

- Backup the subclass.tscn file

You'll need to revisit it to look at the node order if it has any, or if it matters, given the process will change the order of inherited nodes

- Open the subclass.tscn file in a text editor

- Add the following line (doesn't matter where)

[ext_resource path="res://path/to/parentclass.tscn" type="PackedScene" id=${id}]

Replace ${id} by an id not currently in use by another ext_resource (if you have 3 ext_resources, with ids 1,2,3, then ${id} could be 4 and the line would read [ext_resource path="res://path/to/parentclass.tscn" type="PackedScene" id=4]).

- Edit the root node

[node name="subclass" type="RigidBody2D"]
                               ↓↓↓
[node name="subclass" instance=ExtResource( ${id} )]

- If subclass.tscn has nodes that parentclass.tscn also has, remove their type/instance tag

[node name="some_node" parent="." instance=ExtResource( 16 )]
                                         ↓↓↓
[node name="some_node" parent="."]

and

[node name="some_other_node" parent="." type="Area2D"]
                                           ↓↓↓
[node name="some_other_node" parent="."]

- Save the file

- Open it on the editor

- Reorder the nodes in the order they originally were

This is where the backup made on the first step comes in. Given the scene will have been reordered in a way that inherited nodes appear first in the list, you'll need to save or remember the order they were in pre-inheritance, to reset it (omit this if the order doesn't matter in this case).

- Save the scene

That's it. The file will now have been fixed by the editor to eliminate unnecessary references and the load_steps will have been updated

by (18 points)
edited by
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.