+1 vote

So I have this simple script called damageable.gd that handles how objects that extend this script take damage. But the problem is that I want things like players, enemies and walls to be damageable, and these don't share the same PhysicsBody2D subclass. I need these objects to inherit the proper PhysicsBody2D subclass because I need to use the functions RigidBody2D and KinematicBody2D offer.

So how do I make sure all these things extend the correct PhysicsBody2D subclass but are still damageable?

in Engine by (38 points)

3 Answers

0 votes

Normally I'd say to use the common denominator node and check self extends whatever to use a method, but in your case RigidBody2d has modes. And one of them is kinematic. Therefore you can avoid the problem.

by (698 points)
+1 vote

As long as it inherits any parent class up to Node (or maybe Object) the script should work attached to any node if you don't try to use an inexistent method (not sure for how long this will be a feature).

But as @Gokudomatic2 said, could be better if you use rigids on kinematic mode.

by (7,832 points)
+3 votes

Whenever you are in a case you want to inherit two classes, then you should change your design (especially when the language doesn't let you do multiple inheritance). Inheritance does that often and it's the reason why I avoid it nowadays except for API, especially in games.

You could find a common denominator. If you do, you're in luck.
You could copy/paste but that's a sign of future doom :p

What I usually do is compose logic. Your damageable objects could be recognized as having a child "Damageable" node (just of type Node), that handles damage taking. This way you can compose it on your scenes without having to inherit a fixed type that does everything or nothing you need.

Another way is to use duck typing, a pattern widely used in Python. Whatever your object is, if it has a take_damage function, then it can certainly take damage. These calls are made like that:

if obj.has_method("take_damage"):
    obj.take_damage(42)

It's like interfaces, but the GDScript/Python way.

by (27,599 points)

If revising the design, I think the name "damageable" suggest a group...

You can add all the items that takes damage with the same method and just check is_in_group is similar to has_method but feels more clean on design.

Also, this way, if you forget to add the method it will throw an error instead of skipping the object (not to mention you can damage everything on a simple call group).

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.
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 webmaster@godotengine.org with your username.