Godot Version
4.2
Question
Hi,
In C++ I create a class:
class A: public Node {
GDCLASS(A, Node)
public
TypedArray<B> b;
B class:
class B: public Resource {
GDCLASS(B, Resource)
public:
enum Type {
NONE = 0,
TEST= 1,
};
B::Type type;
now I want to do the following:
for (int i=0; i < b.size(); i++) {
if (b[I].type == B::Type::TEST) {
// Do Something
}
}
but I get an error:
class "godot::Variant" has no member "type"C/C++(135)
any solution?
TypedArray<T>::operator[]
, which is inherited from Array
, is actually returning a Variant
.
You could use Variant::get()
for getting a property (of course only if you’ve registered that property), or cast it before using it, this could be the most useful way.
can you give me an example?
for (int i=0; i < b.size(); i++) {
B item = static_cast<B>(b[i]);
if (b[i].type == B::Type::TEST) {
// Do Something
}
}
Still the error:
no suitable user-defined conversion from "godot::Variant" to "godot::B" existsC/C++(312)
I just remembered that we should use Ref<B>
instead of B
because all RefCounted
objects should be wrapped with Ref<T>
. I realized this when I found out that Resource
doesn’t have a copy/move constructor/operator, and I noticed that Sprite2D
contains a Ref<Texture2D>
instead of a non-wrapped one. Try using TypedArray<Ref<B>>
, and use b[i]->type
or store it in a variable first.
operator -> or ->* applied to "godot::Variant" instead of to a pointer typeC/C++(3364)
Edit:
Ref<B>new_b = b[i]
solve the problem
1 Like
So storing b[i]
into Ref<b>
first does implicitly cast it correctly
Did you modify it to inherit from Ref<Resource>
?
No, don’t do that. What did you modify before the error?
I was writing my methods
this error only happens if I want to compile: scons -j2
I just attempted to run this
TypedArray<Image> images;
# Apending a bunch of Image resources...
images.append(Image::create(grid_size.x, grid_size.y, false, Image::Format::FORMAT_RGBAF));
images.append(Image::create(grid_size.x, grid_size.y, false, Image::Format::FORMAT_RGBAF));
images.append(Image::create(grid_size.x, grid_size.y, false, Image::Format::FORMAT_RGBAF));
for (size_t i = 0; i < images.size(); i++)
{
Ref<Image> image = images[i];
}
So this should work
TypedArray<B> b;
for (size_t i = 0; i < b.size(); i++)
{
Ref<B> item = b[i];
if (item.type == B::Type::TEST)
{
// Do Something
}
}
I looked at the code and found that the Ref
has an implicit constructor.
Ref(T *p_reference);
And the Variant
has an implicit operator.
operator Object *() const;
This explains everything we’ve been doing.
I think I understand what the problem is
Let me test it
TypedArray<B> b;
for (size_t i = 0; i < b.size(); i++)
{
Ref<B> item = b[i];
if (item.type == B::Type::TEST)
{
test(item);
}
}
void test(B new_b) {
//Do something with new_b
}
how to pass the item
to the method?
no suitable user-defined conversion from "godot::Ref<godot::B>" to "godot::B" existsC/C++(312)
I came up with a simple conclusion: use raw resource type when stored in arrays, but use Ref
as a wrapper when passing as a reference. So define it as void test(Ref<B> new_b);
since this is passing the reference.
If I do this, will this work?
gdscript:
var b = B.new()
A.test(b)
This should do, I’ve looked upon sprite_2d.h
, and here is the declaration:
Ref<Texture2D> texture;
void set_texture(const Ref<Texture2D> &p_texture);
Ref<Texture2D> get_texture() const;
And we know we’re always using MySprite.texture = some_texture_resource
.
so TypedArray<B> bs
or TypedArray<Ref<B>> bs
?