0 votes

I have a script "UniversalBehavior" with universal behavior that fits different nodes, in my case I used "Sprite3D" and "MeshInstance3D". To be able to attach this script to both types, I used my class's inheritance from "Node". (this is the common ancestor of both types)

public partial class UniversalBehavior : Node
{
    public override void _Process(double delta)
    {
        //Do something universal for different types of nodes
    }
}

There is another script "OtherScript" that I created for demonstration purposes. To simplify, it works directly with the "Sprite3D" node that is in the scene.

public partial class OtherScript : Node
{
    [Export] Texture2D tex1, tex2;
    Sprite3D spriteNode;
    int a;
    public override void _Ready()
    {
        spriteNode = GetNode("/root/Node3D/Sprite3D") as Sprite3D;
        GD.Print(spriteNode.GetType());
    }

    public override void _Process(double delta)
    {
        a++;
        if(a%200 > 100) spriteNode.Texture = tex1; 
        else spriteNode.Texture = tex2;
    }
}

The "OtherScript" script only works correctly if "UniversalBehavior" inherits from "Sprite3D", but then "UniversalBehavior" cannot be attached to other types of nodes. (in my case to "MeshInstance3D")

The problem is that I can't access the fields of the "Sprite3D" node, because it has a script attached to it that inherits from "Node". But the fact that these fields still exist is undeniable, I can change them in the Inspector. (and I want to understand how to do it through the code)

The string "GD.Print(spriteNode.GetType());" says that the received node is of type "UniversalBehavior" and not "Sprite3D", but I want to have access to the node itself and not to the script that is connected to it.
Is this the correct behavior of the GetNode() method?

How to access "Sprite3D" fields from "OtherScript" script?
(and don't change "UniversalBehavior : Node" to "UniversalBehavior : Sprite3D")

Godot version godot 4.0.1 stable
in Engine by (58 points)

2 Answers

+1 vote
Best answer

There is GetClass() but return string instead object, and IsClass and this return bool as suspected... but i dint find anyway to access them.
Only solution what i can give you now is make your make your class Child of target and get parent
var sprite = GetParentOrNull<Sprite3D>();
or opposite and get child

by (372 points)
selected by
+1 vote

You could try using an interface and use proper inheritance, by having the class inherit from node, the object in Net will only have those properties that belong to the base class, in this case node.

So as first mentioned you could try an interface.

public interface UniversalBehavoir
{
    public virtual void DoSomethingUniversal()
    {
        GD.Print("Did something universal");
    }
}

Note the method is declared virtual so it can be overridden if desired. Then your Sprite3D class might look like:

public partial class SomeSprite : Sprite3D, UniversalBehavoir
{
    public override void _Ready()
    {
        UniversalBehavoir ub = this;
        ub.DoSomethingUniversal();
    }
}

And your mesh like this:

public partial class SomeMesh : MeshInstance3D, UniversalBehavoir
{
    public override void _Ready()
    {
        UniversalBehavoir ub = this;
        ub.DoSomethingUniversal();
    }

}

Hopefully this helps.

by (20 points)

Thanks for the answer, but this doesn't scale well, if hypothetically I have 50 different types then I would have to create 50 separate scripts

I suspect that accessing the fields is somehow easier, it's just not obvious

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.