Using a custom class in Godot
Asked Answered
W

1

10

I have a simple network chat program created in Godot that I am using to teach basic encryption to high school students with. I would like to add a custom built encryption class to allow students to create their own cyphers. Here is a simple implementation I created to test the class:

class Security:
    extends Resource

    func _init():
        print("Started.")

    func encrypt():
        print("Encrypting.")

In my main script, I have this code to initialise the class (I have this at the top, in the variable space, before any function definition):

const Security = preload("res://scripts/security.gd")
var sec = Security.new()

And then this in one of my functions within the script:

func send_message():
    sec.encrypt()

At no point does either print message appear in the console. When I trigger the send_message function, I get the following error:

Invalid call. Nonexistent function 'encrypt' in base 'Rederence (security.gd)'.

Is there something I am doing wrong with the creation of the class, or how I add it to my script? Or is what I am trying not really doable (e.g. should I just be adding a node, adding a script to that and using that node in my scene)?

Thanks.

Waterloo answered 7/6, 2021 at 11:54 Comment(0)
B
9

The class syntax creates a inner class. That is class Security is not the class of the script.

As a consequence, when you do this:

const Security = preload("res://scripts/security.gd")

You are not getting the security class you defined. Instead it is a class that contains the class you defined.

You can instance your class like this:

var sec = Security.Security.new()

There the first Security is the name of the constant that refers to the class of the script. And the second Security is the inner class Security you defined.

See Inner Classes.


I suggest you define your class with class_name syntax:

class_name Security extends Resource

func _init():
    print("Started.")

func encrypt():
    print("Encrypting.")

Notice also the change in indentation.

Then the class will be global (which also means there is no need to preload), so you can simply do this:

var sec = Security.new()

Again, no preload needed, the class is global.


Alternatively, do not use a class name, instead have the functions directly on the script. And use preload:

scurity.gd:

extends Resource

func _init():
    print("Started.")

func encrypt():
    print("Encrypting.")

Somewhere else:

const Security = preload("res://scripts/security.gd")
var sec = Security.new()
Briolette answered 7/6, 2021 at 18:20 Comment(1)
Thanks, this exactly answered my question.Waterloo

© 2022 - 2024 — McMap. All rights reserved.