Calling a method from an inherited class

Godot Version

4.1.2

Question

I’m trying to create an action system and in my action method call from the Action.gd class. I have another class ChoiceAction.gd which is written on top of Action.gd (inherits it) but when I try to call a method from ChoiceAction.gd it doesn’t work (godot say that action is null):

try some debug prints

in _init

  action = _action
  print("_init, action:", action)

func _ready():
    print("_ready, action:", action)
func call_action():
    print("call_action, action:", action)
    #......

i got this:


func _ready isn’t work becuse it Resource not Node.
It looks like it’s trying to convert my ChoiceAction to an Action and failing, but that’s not how it’s supposed to work.

example export SET debug, and that for your Action class?

@export var test: String:
	set(value):
		print("export test: ", value)

huh? it looks like it resetted somewhere.

try with print in your func _init , maybe also via base class?


So I fixed it, the problem was that in the ActionTextpart there was a Choice Action class and in init all the variables were optional and for some reason it wasn’t working fine, I change:

func _init(_variants :int, _choice_1 :Choice, _choice_2 :Choice...):
    ...

into

func _init(_variants := 2, _choice_1 := Choice.new(), _choice_2 := Choice.new(), _choice_3 := Choice.new(), _choice_4 := Choice.new()):
	...

oh not, that not fix problem :cry:
but now when it is set a second time, it is not null:

in call_action method it still is null:
изображение

looks like he just didn’t understand what class is base:
изображение

now i really fix that:
i change:

var action: Action = Action.new():
	set(value):
		print(value)

from:

var action: Action:
	set(value):
		print(value)

but now it call method only from base class:

extends Resource
class_name Action

func _init():
	pass

func do_action(player):
	printerr("Overwrite new do_action method in your class!")
	pass
extends Action
class_name ChoiceAction

@export var variants :int
@export var choice_1 :Choice
@export var choice_2 :Choice
@export var choice_3 :Choice
@export var choice_4 :Choice

func _init(_variants := 2, _choice_1 := Choice.new(), _choice_2 := Choice.new(), _choice_3 := Choice.new(), _choice_4 := Choice.new()):
	variants = _variants
	choice_1 = _choice_1
	choice_2 = _choice_2
	choice_3 = _choice_3
	choice_4 = _choice_4

func do_action(player):
	print("Do your choice!")
	pass

hmm, i check remote and when i start game it change my type into action

ok, I’m doing something similar in another class and that didn’t work either. Looks like Godot just can’t do what I need :sob:
изображение

oh ok, I’ll try something out later

If you want to see what I’ve done so far, you can watch it here:

1 Like

but this function overloading works

func _ready():
	print("player _ready")

	var action : Action = Action.new()
	action.do_action(self)

	var choise_action : ChoiceAction = ChoiceAction.new()
	choise_action.do_action(self)
player _ready

  Overwrite do_action method in your custom class!
player:player:<CharacterBody2D#29678896351>

Do your choice!
player:player:<CharacterBody2D#29678896351>

hmm, I think it works because you create in code. But when the ChoiceAction is created from the inspector, for some reason it doesn’t work.

and var choice_action = action as ChoiceAction ?


@export
var action: Action = Action.new():
	set(value):
		print("++++++++++++++++++++++++++++++++++")
		print("ActionTextPart export set ", value)
		print("get_class: ", value.get_class())
		var choice_action = value as ChoiceAction
		print("choice_action: ", choice_action)
		print("-----------------------------------")

print debugs

++++++++++++++++++++++++++++++++++
ActionTextPart export set <Resource#-9223372007679195861>
get_class: Resource
choice_action: <null>
-----------------------------------
++++++++++++++++++++++++++++++++++
ActionTextPart export set <Resource#-9223372007863745238>
get_class: Resource
choice_action: <Resource#-9223372007863745238>
-----------------------------------

currently I don’t know how it can be tested in your running game :slight_smile:


func call_action(player):
	var choice_action = action as ChoiceAction
	if choice_action:
		choice_action.do_action(player)

So I have exactly the same problem in Sayer.gd:

extends Interactor

@export_category("Настройки текста")
@export
var text = Text.new([])

func _init(_text = Text.new([])):
	text = _text

func interact(player):
	player.open_text(text as Text)

Interact.gd:

extends Node
class_name Interactor

func interact(player):
	printerr("Overwrite interact method in your custom class!")
	pass

and last one text.gd:

extends Resource
class_name Text

@export var text_parts : Array[TextPart] = []

func _init(_text_parts : Array[TextPart]):
	text_parts = _text_parts

when I try to pass a Text object to the player from Sayer.gd using player.open_text() it throws an error:
изображение