godotengine / godotengine/godot-cpp

Node::_ready() and Node::_enter_tree() silently fail unless they are registered in register_methods

Open
#562 6 comments 0 reactions 0 assignees View on GitHub
documentation
Dominant language
C++
Stars
2.7k
Forks
809
Avg merge
1d 3h
Merged PRs (30d)
8

Description

This is something I knew about already but it got me again recently. It is not mentioned in the docs here, as far as I can tell, and I think that's very important information that should at least be in the example (the readme example does not show _ready or _enter_tree being used).

These are very important functions and I think there should be a note in the read me drawing users attention to this fact.

This is the existing example with my proposed changes in it already:

```cpp
#include
#include

using namespace godot;

class SimpleClass : public Reference {
GODOT_CLASS(SimpleClass, Reference);
public:
SimpleClass() { }

/** `_init` must exist as it is called by Godot. */
void _init() { }

void test_void_method() {
Godot::print("This is test");
}

Variant method(Variant arg) {
Variant ret;
ret = arg;

return ret;
}

static void _register_methods() {
register_method("method", &SimpleClass::method);

// All built in functions MUST be registered or they will be never called
// and there will be no warnings. Only the first parameter must match the
// function name that godot expects. If you wish to have them point to different
// functions, you may do so they will be called at the normal times.
register_method("_ready", &SimpleClass::_ready);
register_method("_enter_tree", &SimpleClass::_enter_tree);
register_method("_process", &SimpleClass::_process);

/**
* The line below is equivalent to the following GDScript export:
* export var _name = "SimpleClass"
**/
register_property("base/name", &SimpleClass::_name, String("SimpleClass"));

/** Alternatively, with getter and setter methods: */
register_property("base/value", &SimpleClass::set_value, &SimpleClass::get_value, 0);

/** Registering a signal: **/
// register_signal("signal_name");
// register_signal("signal_name", "string_argument", GODOT_VARIANT_TYPE_STRING)
}

String _name;
int _value;

void set_value(int p_value) {
_value = p_value;
}

int get_value() const {
return _value;
}

void _ready() {
// Here the function does not have to be named "_ready", so long as it is still
// registered as "_ready", it will still work.
Godot:print("_ready");
}

void _enter_tree() {
Godot:print("_enter_tree");
}

void _process(float delta) {
Godot:print(delta);
}
};

/** GDNative Initialize **/
extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) {
godot::Godot::gdnative_init(o);
}

/** GDNative Terminate **/
extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *o) {
godot::Godot::gdnative_terminate(o);
}

/** NativeScript Initialize **/
extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) {
godot::Godot::nativescript_init(handle);

godot::register_class();
}
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.