0 votes

Hi,

I created a class that inherits from KinematicBody2D
....so far so good

then I want other objects to inherit from my class
and it does not work

what am I missing ?
thanks for your help

enter image description here

Godot version 3.3
in Engine by (37 points)

2 Answers

0 votes
Best answer

That guy seems to use abstract "interfaces" and inherited scenes

https://www.youtube.com/watch?v=AM9bQVgzw3M

which deals with scenes AND script inheritance

by (37 points)
0 votes

Multiple inheritance is not allow in Godot. Since CharacterClass already inherits from KinematicBody2D, CharacterClass cannot be inherited from again.

You should generally favor composition over inheritance when programming in Godot.

by (3,888 points)

and I thought Godot was so easy going to make a 2D game, I knew there was a catch

what do you mean by composition ?

It is easy. It's difficult if you're not accustomed to programming with an observer pattern (which most game engines use) or not accustomed to creating your objects via composition rather than inheritance (which is just a preference thing). Neither of these styles are focused very heavily on in computer science programs.

Inheritance is an "is a" relationship, while composition is a "has a" relationship. If you think about it in an inheritance way: a Tank is a Vehicle so it makes sense that a Tank would inherit from a Vehicle class. Tank.move() would likely just call Vehicle.move().

If you think about it in a composition way: a Vehicle really is just an object that moves so a Tank and a Vehicle could just have a Mover class that they act on when they want to move. Tank.move() or Vehicle.move() could just call Mover.move().

Tanks in both situations will likely have a Turret to shoot out of. So in the inheritance case: a Tank is a Vehicle that has a Turret OR a Tank inherits from the Vehicle class and is composed of a Turret. In the composition case: a Tank has a Mover and a Turret OR a Tank is an object that is composed of a Mover and a Turret.

There are many ways to skin a cat while programming. It is initially difficult moving from what you learn in a computer science based curriculum, which generally favors inheritance and using the command or chain of responsibility patterns to a system that limits inheritance and uses an observer pattern. I assure you that you can solve any problem that you want to solve in Godot, you'll probably just have to go at it a different way than you're used to.

https://en.wikipedia.org/wiki/Composition_over_inheritance

https://en.wikipedia.org/wiki/Object_composition

most game engine use controllers and inheritance

I want to be able to control different characters/vehicles during the game

like a player picking up a bike and then controlling the bike with the keyboard

my issue is to understand how to create the equivalent of a CharacterController that all my other characters will be inheriting...

so I need to do inheritance around classes AND scenes

without using bad design practices like

if instance == player
..
else if instance == bike 
...
else ..

or worst

if instance.has(feet)
...
else if instance.has(wheels)
...
then

so far I am investigating scenes re usability and interfaces

That guy seems to use abstract "interfaces" and inherited scenes

https://www.youtube.com/watch?v=AM9bQVgzw3M

If you're creating a single player game make a controller autoload singleton that processes all your inputs. Then register which object that the player is currently controlling when you swap vehicles/moving on foot.

class_name Controller
extends Node

var current_object 

func register_object_as_current(obj):
    current_object = obj

func query_inputs():
    var input_vector = Vector2.ZERO
    input_vector.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
    input_vector.y = Input.get_action_strength("move_down") - Input.get_action_strength("move_up")

    current_object.input_vector = input_vector.normalized()

Then when you enter a vehicle:

vehicle.gd
func on_vehicle_entry():
    Controller.register_object_as_current(self)

If you're worried about code reuse make a Mover class that handles any logic related to movement then:

var my_mover = get_node("Mover")

func _physics_process(delta):
    Controller.query_inputs()
    my_mover.handle_movement(delta)

mover.gd
func handle_movement(delta):
    direction = get_parent().input_vector
    speed = get_parent().speed # alternatively use a setup() function to set this
    ...
    get_parent().move_and_slide(direction * speed)

This way you create different Movers for your objects that can function differently without needing to inherit from some master base class.

thanks, I'll implement something like this indeed

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.