2
\$\begingroup\$

I would like to create and import a class in GDScript. Here is some non-functional pseudo code to explain what I'm trying to do:

class_name WordPrinter

var my_word: String

func _init(word: String)
  my_word = word

func print_word()
  print(my_word)
const word_printer = import("./word_printer.gd").new("Hello World")

word_printer.print_word()

I've found various tutorials on classes and imports, but I have yet to find a straightforward code example that works. Here are some places I've looked:

The second link above does show working code, but the imported class does not have any type definitions, and is not very useful.

\$\endgroup\$

2 Answers 2

4
\$\begingroup\$

You have specified a class_name for your class:

class_name WordPrinter

var my_word: String

func _init(word: String)
  my_word = word

func print_word()
  print(my_word)

Thus, you should be able to use it directly:

func _ready():
    var say_hello := WordPrinter.new("Hello World")
    say_hello.print_word()

By the way, here I'm setting the type of say_hello implicitly by using :=. We can do it explicitly too:

func _ready():
    var say_hello:WordPrinter = WordPrinter.new("Hello World")
    say_hello.print_word()

And yes, you could instead use preload with the path:

const word_printer := preload("res://path/to/word_printer.gd")

The preload is resolved while the script is being parsed, which is how this is a constant expression (and thus can be set to a const).

In this case word_printer holds a GDScript object, which you can use like this:

func _ready():
    var say_hello := word_printer.new("Hello World")
    say_hello.print_word()

And setting the type explicitly still works:

func _ready():
    var say_hello:word_printer = word_printer.new("Hello World")
    say_hello.print_word()

Since what you are actually using is a GDScript object, the same should also work if you get it by other means. For example using load, which would allow you to use a variable for the path (for example if you want to decide dynamically which script to load):

func _ready():
    var my_word_printer := load("res://path/to/word_printer.gd")
    var say_hello = my_word_printer.new("Hello World")
    say_hello.print_word()

However, since load is resolved in runtime (instead of being resolved while parsing the script like preload) Godot does not know the type until runtime.

Consequently, the variable instantiated from the the script cannot be statically typed (it will be a Variant), and we won't get auto-completion.

Despite not having auto-completion the code still works in runtime.


This is all covered in the official documentation under Classes and under Static typing.


Addendum: You don't need class_name for preload or load to work.

\$\endgroup\$
0
\$\begingroup\$

Importing a class in gdscript can be done with the preload() command. To make the code above usable, all that needs to change is the import line, like so:

const word_printer = import("res://path/to/word_printer.gd")

func _ready():
  var say_hello = word_printer.new("Hello World")
  say_hello.print_word()
\$\endgroup\$
1
  • \$\begingroup\$ Are you sure you didn't mean to write preload instead of import? \$\endgroup\$
    – Theraot
    Jul 18, 2023 at 0:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .