godotengine / godotengine/godot-cpp
How to register a custom class as a property
- Dominant language
- C++
- Stars
- 2.7k
- Forks
- 809
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 8
Description
I originally logged a question as part of the Godot QA as:
[https://godotengine.org/qa/46239/how-register-properties-with-custom-classes-nativescript](https://godotengine.org/qa/46239/how-register-properties-with-custom-classes-nativescript)
... but upon diving into this further I thought the issues section of the godot-cpp project might be more appropriate.
I am trying to define and register a subclass within Godot. I would like to be able to pass complex structures into the engine itself using NativeScript. The principle is a "User" might have lots of data and be used in many places in the engine and I do not want to pass each variable individually.
I thought that maybe a Godot-derived object could be passed through another, but I cannot seem to register the object directly. I am receiving the error:
> Error:
```
Godot.hpp: In instantiation of 'void godot::register_property(const char*, P T::*, P, godot_method_rpc_mode, godot_property_usage_flags, godot_property_hint, godot::String) [with T = godot::GdUserManager; P = godot::GdUser]':
Godot.hpp:314:10: error: conversion from 'godot::GdUser' to non-scalar type 'godot::Variant' requested
Variant def_val = default_value;
^~~~~~~
```
The issue stems from registration with `register_property()` (Godot.hpp:313). The default field is immediately assigned to a Variant, but Variant does not resolve custom objects.
Is there actually a way to register custom classes as properties? If not, is there explicit reason for the functionality not to exist already? It seems to be a highly-desirable feature to me for projects with a certain degree of complexity.
> Source:
**gd-user-manager.h**
```
#ifndef _GD_USER_MANAGER_H_
#define _GD_USER_MANAGER_H_
#include
#include
#include "gd-user.h"
namespace godot {
class GdUserManager : public Object {
GODOT_CLASS(GdUserManager, Object)
public:
GdUser m_user;
public:
static void _register_methods() {
GdUser blah;
// Doesn't work
register_property("user", &GdUserManager::m_user, blah);
// Getter-setter variant also doesn't work
//register_property("user", &GdUserManager::set_user, &GdUserManager::get_user);
}
GdUserManager();
~GdUserManager();
void _init() { }
GdUser get_user() {
return m_user;
}
void set_user(GdUser user) {
m_user = user;
}
};
}
#endif
```
**gd-user.h**
```
#ifndef _GD_USER_H_
#define _GD_USER_H_
#include
#include
namespace godot {
class GdUser : public Object {
GODOT_CLASS(GdUser, Object)
private:
int m_test = 42;
public:
static void _register_methods() {
register_property("test", &GdUser::set_test, &GdUser::get_test, 41);
}
GdUser();
~GdUser();
void _init() {}
int get_test() {
return m_test;
}
void set_test(int test) {
m_test = test;
}
};
}
#endif
```
edit - including the *.gdns file
**user-manager.gdns**
```
[gd_resource type="NativeScript" load_steps=2 format=2]
[ext_resource path="res://lib/user-manager/bin/user-manager.gdnlib" type="GDNativeLibrary" id=1]
[resource]
resource_name = "user-manager"
class_name = "GdUserManager"
library = ExtResource( 1 )
_sections_unfolded = [ "Object" ]
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.