How to initialize inner class member with data derived from outer scope

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By AnarcoPhysic

I would like to create a inner class (potentialy a singleton) that works over a child of the current node. To do this in a clean way, I would like to initialize its members in a single statement. Even after reading a lot of forum and GDScript reference texts. I was unable to achieve my code goals. So, is it possible? If not, what would be the better approach?

Example

 class VelocityObserver:
    onready var velocity : Vector2 = (outer_scope).get_node("child_of_current_scope").speed
    func display_speed():
        print("Component X :+velocity.x)

Yet, my doubt creates one more question. Instances of VelocityObserver, in the above example, don’t derive/inherit from outer class but prefix “.” still seems to have a mean (compile and runs normally). In this case, is it refer to the global scope? To be more clear about what I want to mean, this next line

var velocity : Vector2 = .get_node( "child_of_current_scope" ).speed

makes sense to the compiler.

Thanks in advance

Your example should not compile if you perform assignment with := operator (but it should with =) because there is not a valid value at the right side to inference its type. What version are you using?

unlut | 2020-09-27 20:26

Have you thought about setting the member variables of the inner class (really an object of the class) from the parent class? Either set them directly when the inner class object is created, or have a member function which sets the desired data in the inner class object.

Ertain | 2020-09-28 08:36

@unlutYou are right! I’ve forgot to declare the type of variable as Vector2!!! But even declaring that, it doesn’t work (I got a null value).

AnarcoPhysic | 2020-09-28 20:41

@Ertain, there is no parent class to this inner classI Look its definition. Or am I wrong? Anyway, thanks for your suggestion. It was really good! has showed me that I was “misusing” inner classes. Some properties are to be initialized by the constructor!

Thanks for all help! I am going to make changes in the code.

AnarcoPhysic | 2020-09-28 20:52

:bust_in_silhouette: Reply From: unlut

I was going to write an answer about that part but I was confused because you said code was compiling okay. Here is the thing.
1- What you assume is true, inner class is not derived from outer class so you cannot access its stuff without having a reference to outer class object. Easiest way is to just pass a reference to outer class during constructor (init function).
2- “.” means self. You can test with with a small script where you print “.get_instance_id()” and “self.get_instance_id()” in a class function.

func _ready():
    print(.get_instance_id())
    print(self.get_instance_id())

3- You are getting null when you use onready variable in your inner class, because _ready function is called when a node enters the scene tree. When you instantiate an inner class with var velObs = VelocityObserver.new(), its _init method is called (_init is called when an object is created), but its _ready function is not, so your onready variables are not initialized.

VelocityObserver’s _ready() won’t ever be called because it doesn’t exist :slight_smile: The class isn’t a Node.Same thing with get_node().

GDScript’s interpreter should be complaining about onready making no sense for non-Node classes but it doesn’t :frowning: Removing that keyword will uncover an error with get_node().

hilfazer | 2020-09-29 05:25