+3 votes

I have a situation where I'd like to extend from a gdscript, but I would also like to keep the node's script extending their built in type.

I would have a RigidBody2D and a StaticBody2D, and they would want to inherit a bunch of general properties and initialization logic from a gdscript. I don't want to create two copies that extend each type, because it will become a problem have to maintain multiple versions of the same thing as time goes on.

I know there isn't any multiple inheritance for extends, so I can't extend both and use it as a properties mixin.

Are there any eloquent ways around this? My initial idea is to preload the script as something like a props, and then refer to things like props.height, etc.

Any one else have any interesting alternatives?

asked Dec 2, 2016 in Engine by avencherus (4,831 points)

NOTE - Only works in older versions of Godot.

One way to achieving this is by having a base class that extends a common class. The node type in the editor will apply it's type regardless of what parent class it's script will extend.

So something such as this...

base_class.gd

extends Spatial

func common_function():
    return "something"

RigidBody

extends "base_class.gd"

func _ready():
    print(common_function())

StaticBody

extends "base_class.gd"

func _ready():
    print(common_function())

Is fine with your answer.

I'm not sure if that is a feature or a bug, as feature is an overkill, one can make generic scripts and use them everywhere with behavior filter by type, group or metadata.

But I'm not sure if I like it...

I know this is an old post, but the question is still relevant.
Anyway, at least in version 3.1, to use the class properties of the extending class (eg. RigidBody or StaticBody above), the engine will throw a compile error (method or property doesn't exist in the class). To overcome this, simply do:

var body = self
body.some_func_on_body()

I tried your suggestion and it worked nicely, since this post is old I wanted to ask you if you found any problems with this approach/technique, so far looks safe, clean an elegant to my eyes, thanks!

@TGMG : Not sure for whom the question was... But I've now been using this kind of "cross extending" for about a year or two, quite actively in some cases, and haven't had any problems, where this has been applicable. There are still cases where I've had to double the code due to more complex inheritance. Anyway, some notes:
1. If you want to create a new node with your class with a specific internal class, first create a node of the desired class (eg. var node= StaticBody.new()) and then attach the script by node.set_script(my_script). (Doing var node = my_script.new() will use whatever base class the first script extends.)
2. If you want to enjoy the GDScript's typed hints and such, you can also do the below:

var body : KinematicBody
func _init():
    var _self = self
    body = _self

Please log in or register to answer this question.

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 How to use this Q&A? before posting your first questions.