Cannot call non-static function "get()".... Make an instance instead.
Asked Answered
S

13

0

Hey folks !

I'm new to Godot (and scripting overall actually ><). I'm following a tutorial to make a cardgame (( but already have some issues (3 years old tuto, so I suppose how the script was written doesn't work anymore ?)

Here's the script :

extends MarginContainer

@onready var CardDatabase = preload("res://Assets/Cards/CardsDatabase.gd")

var Cardname = "Footman":

@onready var CardInfo = CardDatabase.DATA[CardDatabase.get(Cardname)] <- ERROR HERE

func _ready():
print(CardInfo)

The error is : "Cannot call non-static function "get()" on the class "res://Assets/Cards/CardsDatabase.gd" directly. Make an instance instead."

So, my question is : How do I make this instance ?

Statant answered 20/9, 2023 at 8:55 Comment(0)
O
0

I don't think you need to preload your CardDatabase. Try removing that line and in your ready function (which should be defined as func _ready():) write something like print(CardDatabase.DATA) and see if that prints your array.

And _extends should be extends.

Also CardDatabase.DATA[CardDatabase.get(Cardname)] seems to do the same thing (kind of). Either write CardDatabase.DATA[Cardname] or CardDatabase.DATA.get(Cardname).

Oballa answered 20/9, 2023 at 9:28 Comment(0)
S
0

Oballa

Thanks for your answer !

For the _extends, yeah there's no underscore in my script, I just tried to write the code in Italics and it just put this underscore before the "extends" ><

I tried to remove the preload line and wrote print(CardDatabase.DATA), but I got an error since CardDatabase was not declared anywhere before. So I put back the preload line -> No more error, but it printed everything from the CardDatabase.gd (which is not what I intended to do)

I tried to replace @onready var CardInfo = CardDatabase.DATA[CardDatabase.get(Cardname)] by @onready var CardInfo = CardDatabase.DATA[CardDatabase.Footman] and it printed the Footman values from CardDatabase.gd just right, but I guess it will result in more issues when i'll go deeper in the tuto :/

Statant answered 20/9, 2023 at 11:56 Comment(0)
O
0

Statant Oh right, you probably need to add your CardDatabase to the autoload classes so that it gets loaded automatically at the beginning and is available globally.

Oballa answered 20/9, 2023 at 12:21 Comment(0)
S
0

Statant If you're a beginner, don't do 3.x tutorials in 4.x. It will cause a lot of headache along the way. Download 3.x and do the tutorial there.

Synsepalous answered 20/9, 2023 at 12:32 Comment(0)
S
0

Hey again, and thanks for your answers !

Using Godot 3 may be a good idea, but I can't help but think it would a waste of the acquired experience if I don't use 4.0 right from the beginning x)

I more or less solved my issue. I don't use the var Cardname anymore, instead I write the card's name directly in CardInfo : @onready var CardInfo = CardDatabase.DATA[CardDatabase.Footman], yet it results in a bit of a mess later as expected (when I want to switch card, I have to modify the big CardInfo line, instead of just the var Cardname

I still have a hardtime understanding why @onready var CardInfo = CardDatabase.DATA[CardDatabase.Footman] does work, while @onready var CardInfo = CardDatabase.DATA[CardDatabase.Cardname] with var Cardname = "Footman" doesn't and results in the following error : Invalid get index 'Cardname'(on base : 'Nil').

Statant answered 22/9, 2023 at 7:26 Comment(0)
O
0

Statant Weird. What is the output of something like this:

func _ready():
    print(Cardname)
    print(CardDatabase.Footman)
    print(CardDatabase.Cardname)
    print(CardDatabase.DATA)
    print(CardDatabase.DATA[CardDatabase.Footman])
    print(CardDatabase.DATA[CardDatabase.Cardname])

Statant Using Godot 3 may be a good idea, but I can't help but think it would a waste of the acquired experience if I don't use 4.0 right from the beginning x)

Well, the only input I have on this is that I started with Godot two months ago and have only ever used version 4.1.1 and I never ran into any issues in all that time. And after doing the tutorials in the Godot docs and reading the manual (especially on GDScript) I could easily convert anything Godot 3 related that I saw in older tutorials into the proper Godot 4 form (but I am also not new to programming, so that helps). Anyways, my point is: I started with Godot 4 and I'm doing fine.

Oballa answered 22/9, 2023 at 8:29 Comment(0)
S
0

Statant Using Godot 3 may be a good idea, but I can't help but think it would a waste of the acquired experience if I don't use 4.0 right from the beginning x)

No, it wouldn't. It's exactly the same engine with all the same features. All the things and concepts you learn with 3.x apply directly in 4.x. There were changes in function names in GDScript in 4.x, which are rather minimal but significant enough to stutter beginners attempting to "port" tutorials as they do them.

So again, either find a 4.x tutorial or do a 3.x tutorial in 3.x. A lot less headache and confusion that way. And you want to avoid confusion when learning something.

Synsepalous answered 22/9, 2023 at 12:9 Comment(0)
S
0

Oballa

with @onready var Cardname = "Footman"

func _ready():
    print(Cardname) -> Footman
    print(CardDatabase.Footman) -> 0
    print(CardDatabase.Cardname) -> error : Invalid get index 'Cardname" (on base "Nil")
    print(CardDatabase.DATA) -> all Data from CardDatabase.gd
    print(CardDatabase.DATA[CardDatabase.Footman]) -> Footman Data only
    print(CardDatabase.DATA[CardDatabase.Cardname]) -> error : Invalid get index 'Cardname" (on base "Nil")

I also tried print(CardDatabase.DATA[0]) -> Footman Data only too (which is good), and with @onready var Cardname = CardDatabase.Footman", print(Cardname) -> 0, and then print(CardDatabase.DATA[Cardname]) -> Footman Data only (which is good too)

So for some reason, when Cardname = "Footman", CardInfo = CardDatabase.DATA[CardDatabase.Cardname] doesn't work because Cardname = Footman (while it should be = to 0)

Or am I wrong ?

Statant answered 25/9, 2023 at 8:7 Comment(0)
S
0
print(CardDatabase.Footman) -> 0
print(CardDatabase.Cardname) -> error : Invalid get index 'Cardname" (on base "Nil")

Does your code look exactly like this? First the first line, immediately followed by the second line? This would mean that CardDatabase is not null in the first line and somehow then turns null in the second. Either your CardDatabase does something really weird with getters or you found a bug in Godot. I don't see any other explanation how that could possibly happen.

Just to be sure, can you post your CardDatabase script?

Stine answered 25/9, 2023 at 8:27 Comment(0)
G
0

Hey, i just started this tutorial and found that this solution seems to work.

@onready var cardDatabase = preload("res://Assets/Cards/CardsDatabase.gd")

var cardName = 'Footman'

@onready var cardIndex = cardDatabase[cardName]
@onready var cardInfo = cardDatabase.DATA[cardIndex]

hope this helps

Gallia answered 25/9, 2023 at 9:31 Comment(0)
S
0

Okay, so what was making a mess was the Autoload on my CardDatabase.gd (yeah, forgot to mention I put this script on Autoload ><)

So, with the preload line instead of the Autoload, it works, and you don't even need the var cardIndex (Debbydebee)

Soooo, the only thing that was not working well in my very first post here was actually the .get(Cardname) in @onready var CardInfo = CardDatabase.DATA[CardDatabase.get(Cardname)]

Facepalming a lot rn >< Thanks everyone !

Statant answered 25/9, 2023 at 12:53 Comment(0)
O
0

Well, shooting yourself in the foot is always the best way to learn. 😉

Also, everyone started this way and also everyone still does it, the difference is just the scale.

Oballa answered 25/9, 2023 at 13:8 Comment(0)
A
0

Hey Guys,

I have started watching the tutorial on Youtube and this is where Iam with epsisode one 🙁

I get this when I run the game in 4.2.1

extends MarginContainer


# Declare member variables here. Examples:
@onready var CardDatabase = preload("res://Assets/Cards/CardsDatabase.gd")
var Cardname = 'Footman'
@onready var CardInfo = CardDatabase.DATA[Cardname]
@onready var CardImg = str("res://Assets/Cards/",CardInfo[0],"/",Cardname,".png")


# Called when the node enters the scene tree for the first time.
func _ready():
	#print(CardInfo)
	var CardSize = size
	$Border.scale *= CardSize/$Border.texture.get_size()
	$Card.texture = load(CardImg)
	$Card.scale *= CardSize/$Card.texture.get_size()
	var Attack = str(CardInfo[1])
	var Retaliation = str(CardInfo[2])
	var Health = str(CardInfo[3])
	var Cost = str(CardInfo[4])
	var SpecialText = str(CardInfo[6])
	$Bars/TopBar/Name/CenterContainer/Name.text = Cardname
	$Bars/TopBar/Cost/CenterContainer/Cost.text = Cost
	$Bars/SpecialText/Text/CenterContainer/Type.text = SpecialText
	$Bars/BottomBar/Health/CenterContainer/Health.text = Health
	$Bars/BottomBar/Attack/CenterContainer/AandR.text = str(Attack,'/',Retaliation)
Archaeo answered 29/12, 2023 at 5:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.