AnimationTree parameters/conditions doesn't get back to previous state

Godot Version

4.2

Question

Hello all
I have AnimationTree which i change the state of the animations based on condition
I have 2 animations that are active “run” and “attack” , the scene start with “run” animation and when the “enemy” is less then 2.5 distance it changes it state to “attack” when the player run away i expect it to go back to “run” but it is stack on “Attack”


Here is my code with some prints:  
public partial class zombie : CharacterBody3D
{

	private player Player;
	private NavigationAgent3D NavigationAgent;
	private AnimationTree AnimationTree;
	private const float SPEED = 4.0f;
	private const float ATTACK_RANGE = 2.5f;
	private AnimationNodeStateMachinePlayback StateMachine;
	private AnimationPlayer AnimationPlayer;
    Animation animRun;
    Animation animAttack;
    Animation animStandUp;

    [Export]
	public NodePath PlayerPath;

	public override void _Ready()
	{
		Player = GetNode<player>(PlayerPath);
		NavigationAgent = GetNode<NavigationAgent3D>("NavigationAgent3D");
		AnimationTree = GetNode<AnimationTree>("AnimationTree");
        AnimationPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
        StateMachine = AnimationTree.Get("parameters/playback").As<AnimationNodeStateMachinePlayback>();
        animRun = AnimationPlayer.GetAnimation("run");
        animAttack = AnimationPlayer.GetAnimation("attack");
        animStandUp = AnimationPlayer.GetAnimation("standUp");
    }

	public override void _Process(double delta)
	{

		Velocity = Vector3.Zero;
		

		switch (StateMachine.GetCurrentNode().ToString())
        {
			case "run":
				
				animRun.LoopMode = Animation.LoopModeEnum.Linear;
                NavigationAgent.TargetPosition = Player.GlobalTransform.Origin;
                Vector3 NextNavPoition = NavigationAgent.GetNextPathPosition();
                Velocity = (NextNavPoition - GlobalTransform.Origin).Normalized() * SPEED;
				LookAt(new Vector3(GlobalPosition.X+Velocity.X,GlobalPosition.Y, GlobalPosition.Z+Velocity.Z),Vector3.Up);
                break;
            case "attack":
                animRun.LoopMode = Animation.LoopModeEnum.None;
                animAttack.LoopMode = Animation.LoopModeEnum.Linear;
                LookAt(new Vector3(Player.GlobalPosition.X,GlobalPosition.Y,Player.GlobalPosition.Z),Vector3.Up);
                break;
            case "standUp":
                break;
        }




        bool IsTargetInRange = TargetInRange();
        AnimationTree.Set("parameters/conditions/attack", IsTargetInRange);
        AnimationTree.Set("parameters/conditions/run", !IsTargetInRange);

        Print("IsTargetInRange: "+ IsTargetInRange);
        Print("!IsTargetInRange: "+!IsTargetInRange);

        var  bAttack = (bool)AnimationTree.Get("parameters/conditions/attack");
        var bRun = (bool)AnimationTree.Get("parameters/conditions/run");

        Print("bAttack:" + bAttack + "  bRun:" + bRun);
        Print(StateMachine.GetCurrentNode().ToString());

        


        MoveAndSlide();
	}

	private bool TargetInRange()
	{
		Print(GlobalPosition.DistanceTo(Player.GlobalPosition) + " < " + ATTACK_RANGE);
		return GlobalPosition.DistanceTo(Player.GlobalPosition) < ATTACK_RANGE;

	}

}

as you can see the lines :

AnimationTree.Set("parameters/conditions/attack", IsTargetInRange);
AnimationTree.Set("parameters/conditions/run", !IsTargetInRange);

responsibles for the changing of animation states .

when the zombie is far away the print looks like this :

run
25.84025 < 2.5
IsTargetInRange: False
!IsTargetInRange: True
bAttack:False  bRun:True
run
25.773579 < 2.5
IsTargetInRange: False
!IsTargetInRange: True
bAttack:False  bRun:True
run
25.70691 < 2.5
IsTargetInRange: False
!IsTargetInRange: True
bAttack:False  bRun:True
run
25.64024 < 2.5
IsTargetInRange: False
!IsTargetInRange: True
bAttack:False  bRun:True
run

when the zombie less then 2.5 in distance the logs looks like this

attack
2.3770602 < 2.5
IsTargetInRange: True
!IsTargetInRange: False
bAttack:True  bRun:False
attack
2.3770602 < 2.5
IsTargetInRange: True
!IsTargetInRange: False
bAttack:True  bRun:False
attack
2.3770602 < 2.5
IsTargetInRange: True
!IsTargetInRange: False
bAttack:True  bRun:False
attack
2.3770602 < 2.5
IsTargetInRange: True
!IsTargetInRange: False
bAttack:True  bRun:False
attack
2.3770602 < 2.5
IsTargetInRange: True
!IsTargetInRange: False
bAttack:True  bRun:False

now when i move from the zombie :
See it still stack on the attack even so the distance is more then 2.5
And the bRun varible is true and the bAttack is False .

attack
11.074618 < 2.5
IsTargetInRange: False
!IsTargetInRange: True
bAttack:False  bRun:True
attack
11.074618 < 2.5
IsTargetInRange: False
!IsTargetInRange: True
bAttack:False  bRun:True
attack
11.074618 < 2.5
IsTargetInRange: False
!IsTargetInRange: True
bAttack:False  bRun:True
attack
11.074618 < 2.5
IsTargetInRange: False
!IsTargetInRange: True
bAttack:False  bRun:True
attack

What is wrong here why the zombie doesn’t change state ?

It doesn’t look like the problem is on your code but in the state machine.

1 Like

na found the apparently when you control your animation states programatcly
you need to change the state according to which the state the zombie is .
no documentation on this …