0 votes

Hello, I recently moved from gdscript to C# in an attempt to improv my programming skills (I'm a newbie, using Godot to learn, and I just got into C#). Now, something very simple in gdscript. In gdscript, to access the property playback in the AnimationTree, and set up a state_machine.travel("state"), you simply do:

var state_machine = $AnimationTree.get("parameters/playback")
state_machine.travel("some_state")

How do I do this is C#? I tried:

public class Player : Node2D {

    public AnimationTree animTree;
    public AnimationNodeStateMachinePlayback stateMachine;

    public void _Ready() {
        animTree = GetNode<AnimationTree>("path/to/my/Animation/Tree");
        stateMachine = (AnimationNodeStateMachinePlayback)animTree.Get("/parameters/playback");
        // also tried with "as"

        stateMachine.Travel("state");
        // this line ^ gives an error only in Godot, SEE BELOW.
    }

}

The error that the Travel method gives me is:

E 0:00:00.520 void Player._Ready(): System.NullReferenceException:
Object reference not set to an instance of an object.

<C++ Error> Unhandled exception

<C++ Source> my/path/to/Player.cs:37 @ void Player._Ready()()

Player.cs:37 @ void Player._Ready()()

I can't call any method in stateMachine (like stateMachine.Start() / Stop() etc.), it always gives me this error.

I believe it is some C# "uniqueness", if one of you could elaborate to me, I'd be extremely happy! Thank you so much in advance!

asked Jan 22 in Engine by iPineapples (12 points)

Is your Tree Root an AnimationNodeStateMachine? If you have another kind and your state machine inside it you need to specify the path

"/parameters/StateMachine/playback"

I made a quick test an this works if your Tree Root is an AnimationNodeStateMachine:

    animationTree = player.GetNode<AnimationTree>("AnimationTree2");
    playBack = (AnimationNodeStateMachinePlayback)animationTree.Get("parameters/playback");
    playBack.Travel("Idle");

1 Answer

0 votes

hello I'm new to the engine, but digging and trying i got with this solution for accessing statemachines without declaring vars in the whole code, this leads to a bit of refactoring towards the code, hope this helps you

State Machine in C#:

  1. Declare a private AnimationStateMachineNodePlayback stateMachine;
  2. In the method you want to call the state machine you declare a animationTree
  3. Basicly with a var animTree = (AnimationTree)GetNode("AnimationTree");
  4. You access the stateMachine with stateMachine = (AnimationStateMachinePlayback)animTree.Get("parameters/playback");
  5. You can now call your variable stateMachine anywhere in the code.

Code Example:

public class Player : KinematicBody2D
{
 private AnimationNodeStateMachinePlayback _stateMachine;
public override void _PhysicsProcess(float delta)
    {
        var animTree = (AnimationTree)GetNode("AnimationTree");
        _stateMachine = (AnimationNodeStateMachinePlayback)animTree.Get("parameters/playback");
        MyFuncton();
    }


    void MyFuncton()
{
     GD.Print(stateMachine.GetCurrentNode());
}
}

Sorry i just created this account today to help you, I really hope this helps you with your ploblem, also sorry if my english isn't good, I'm more of a spanish talking guy hahaha
if you need more infomation on StateMachines please use this link: Godot Docs 3.2

answered Apr 12 by coBearCoding (26 points)
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 How to use this Q&A? before posting your first questions.