Skip to main content
Tweeted twitter.com/StackGameDev/status/1420896933825089537
deleted 14 characters in body
Source Link
Marty Cagas
  • 319
  • 1
  • 3
  • 11

 

 
Followed a debugging suggestion in the comments
Source Link
Marty Cagas
  • 319
  • 1
  • 3
  • 11

New scene: Character

New scene: Character

New inherited scene: Player

New inherited scene: Player

Also why does Player show as a Type: KinematicBody when hovering over it in the scene inspector and not like Type: Player, the same way Character shows as Type: Character - or why don't they both show up as Type: KinematicBody?

Edit

Following @Vaillancourt's suggestion, I placed breakpoints at each of the print_debug() calls. Stepping through the code, the last 4 prints behave as expected - first there's the Character constructor, implicitly called from the Player constructor, then the body of the Player constructor itself. This is clear from the backtrace. Same for the _ready() calls. But before this, there's always one extra Character constructor call not called from the Player constructor.

Same goes when I put multiple Player instances into the scene. Both had the correct constructor calls preceded by one extra, separate call.

Putting a Character instance along with a Player instance to the scene resulted in a - once again - malfunctioning Player (three _init() and two _ready() calls) and a correctly functioning Character (just one _init() and one _ready() call).

New scene: Character

New inherited scene: Player

Also why does Player show as a Type: KinematicBody when hovering over it in the scene inspector and not like Type: Player, the same way Character shows as Type: Character - or why don't they both show up as Type: KinematicBody?

New scene: Character

New inherited scene: Player

Also why does Player show as a Type: KinematicBody when hovering over it in the scene inspector and not like Type: Player, the same way Character shows as Type: Character - or why don't they both show up as Type: KinematicBody?

Edit

Following @Vaillancourt's suggestion, I placed breakpoints at each of the print_debug() calls. Stepping through the code, the last 4 prints behave as expected - first there's the Character constructor, implicitly called from the Player constructor, then the body of the Player constructor itself. This is clear from the backtrace. Same for the _ready() calls. But before this, there's always one extra Character constructor call not called from the Player constructor.

Same goes when I put multiple Player instances into the scene. Both had the correct constructor calls preceded by one extra, separate call.

Putting a Character instance along with a Player instance to the scene resulted in a - once again - malfunctioning Player (three _init() and two _ready() calls) and a correctly functioning Character (just one _init() and one _ready() call).

Source Link
Marty Cagas
  • 319
  • 1
  • 3
  • 11

Extra constructor call when using inheritance in Godot

I'm trying to design a character system for my game. Considering I'll need a player and non-player characters - and non-player characters will further come in many more forms, making use of inheritance sounds almost necessary.

Right now, I'm trying to make every instance hold a dictionary of context options and I need the dictionary to be modified with every level of inheritance. From the documentation I learned that the constructor implicitly calls the parent constructor, and so does the _ready() function as noted here.

... but first I wanted to test it, so I set up following scenes (slightly simplified):


New scene: Character

  • Character (Type: Character - here I'm not sure why, should be just KinematicBody)

... with the attached script:

extends KinematicBody

class_name Character

func _init():
    print_debug(self.to_string(), " Character _init()")

func _ready():
    print_debug(self.to_string(), " Character _ready()")

New inherited scene: Player

  • Player (Inherits: Character.tscn, Type: KinematicBody)

... and detatched the Character.gd script and attached a new script:

extends Character

class_name Player

func _init():
    print_debug(self.to_string(), " Player _init()")

func _ready():
    print_debug(self.to_string(), " Player _ready()")

... and I instantiate one Player scene as a child scene in my main scene (through editor, not code).


For some reason, whenever I instantiate Player, Godot consistently prints this:

[KinematicBody:1422] Character _init()
   At: res://scenes/characters/Character.gd:22:_init()
[KinematicBody:1422] Character _init()
   At: res://scenes/characters/Character.gd:22:_init()
[KinematicBody:1422] Player _init()
   At: res://scenes/characters/player/Player.gd:26:_init()
[KinematicBody:1422] Character _ready()
   At: res://scenes/characters/Character.gd:30:_ready()
[KinematicBody:1422] Player _ready()
   At: res://scenes/characters/player/Player.gd:34:_ready()

However, when I instantiate only Character in its place, the output is as I'd expect:

[KinematicBody:1425] Character _init()
   At: res://scenes/characters/Character.gd:22:_init()
[KinematicBody:1425] Character _ready()
   At: res://scenes/characters/Character.gd:30:_ready()

Where is the extra _init() call coming from? Sounds like something that could make a lot of mess if I didn't notice this and blindly used it.

Also why does Player show as a Type: KinematicBody when hovering over it in the scene inspector and not like Type: Player, the same way Character shows as Type: Character - or why don't they both show up as Type: KinematicBody?