I am new in C# and I am doing some practice in Godot. I have a "Mob" node (KinematicBody) and it's child, a "Sprite" node (Spatial). In the _Ready() method I get the "Sprite" object, that is "Mob's" child:

			public Node sprite;
        	public override void _Ready()
        		{
        			sprite = GetNode("Sprite"); 
        			GD.Print(sprite); // All good so far. It gets the correct object.
        		}

But, when I try to use a method from "Sprite" at another part of the code, it results in error.

The call code line:

    		sprite.SetAnimation(state, face);

The method I am trying to call from "Sprite:

        	public void SetAnimation(string state, string face)
        	{
        		GD.Print(state + "_" + face); // Just to test if it works.
        	}

The error I get:

'Node' does not contain a definition for 'SetAnimation' and no accessible extension method 'SetAnimation' accepting a first argument of type 'Node' could be found (are you missing a using directive or an assembly reference?)

What am I doing wrong?

I don't know if it has anything to do with it, but don't name a node that is a builtin class in Godot. Sprite is a built in node already for 2d. You took a spatial node and named it Sprite. It's just bad practice. Don't know if it's affecting your code. Name it something specific that can't be confused.

In your code you are casting the sprite node to a Node class, which is the base class, so you will only be able to access the base classes functions and properties. What instead you need to do is define the variable as public Sprite sprite on line 1 and then in line 4 use something like sprite = GetNode<Sprite>(“Sprite”) and then it should work.

Also, while the naming shouldn’t matter in this case since C# it’s capitalized (Sprite rather than sprite), I agree with @fire7side in that it’s probably a good idea to, if possible, name the variable something that doesn’t have the exact same name as the node, if nothing else than it will be easier to refactor later if you need to adjust the code :smile:

Edit: My bad, I just read it again and realized you are not trying to access a Sprite node like a Godot one, but rather a custom one. :sweat_smile: Thankfully it’s pretty much the same to fix it though, you just need to replace Sprite with the name of the class with the custom function. For example, if your class is called something like SpatialSprite In the .cs source file, then you want to use public SpatialSprite sprite on line 1 and sprite = GetNode<SpatialSprite>(“Sprite”) on line 4.

Thank you both! I fixed it. It seems like I need to read again about classes in C#. Also, thanks for telling me that it's a bad idea to use the name "Sprite". I used that because it's a parent of multiple Sprite3D nodes, but I forgot there is also the built-in Sprite node :)

5 days later

Sorry, the "It seems like I need to read again about classes in C#" sentence is unclear. What did you change to solve it? Thank you!

@33fred33 I have a Spatial node called “Sprites” (I renamed it from “Sprite” because, as others pointed out, it was bad practice). That node has a script attached. “Sprites” is a class (that inherits from the "Spatial" class), so:

	private Sprites sprites; // Our variable to hold the reference.
	public override void _Ready()
		{
			sprites = GetNode<Sprites>("Sprites"); // Get the node of type Sprites.
			sprites.SetAnimation(state, face); // Now I call call a method from sprites.
		}

What I did wrong before, was the fact that I typed Node sprites instead of Sprites sprites. The class name is Sprites, not Node. I hope that helps. If not, please post your code so we can find the problem.

a year later