Godot Version
v4.2.2.stable.mono.official [15073afe3]
Question
Hi there, first project in godot, i hope you can help me
I’m working on a little top down game with currently 3 animations: idle, run and roll. I use an AnimationPlayer and I need the length of my animation in order to set the activeTime of my skills. For example my skill roll should last as long as its animation. GD.Print(currentAnimation) tells me that the animation never changes, it’s always “player_idle/player_idle_down”. the frames are changing and correct but the animation length is always the length of the idle animation.
Do I need to key the time aswell? And how can that be achieved?
AnimationController class:
using Godot;
using System;
using System.Collections.Generic;
public enum Skills{NO_STATE, IDLE, RUN, ROLL, DASH, BACKHOP};
public partial class AnimationController : AnimationPlayer
{
Skills state = Skills.IDLE;
int direction = 0;
String[] directionArray = null;
static String[] IdleDirections = {"player_idle/player_idle_up", "player_idle/player_idle_up_right","player_idle/player_idle_right","player_idle/player_idle_down_right", "player_idle/player_idle_down","player_idle/player_idle_down_left", "player_idle/player_idle_left","player_idle/player_idle_up_left"};
static String[] RunDirections = {"player_run/player_run_up", "player_run/player_run_up_right","player_run/player_run_right","player_run/player_run_down_right", "player_run/player_run_down","player_run/player_run_down_left", "player_run/player_run_left","player_run/player_run_up_left"};
static String[] RollDirections = {"player_roll/player_roll_up", "player_roll/player_roll_up_right", "player_roll/player_roll_right", "player_roll/player_roll_down_right", "player_roll/player_roll_down", "player_roll/player_roll_down_left", "player_roll/player_roll_left", "player_roll/player_roll_up_left"};
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
SetAnimation(state);
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
PlayAnimation();
}
void PlayAnimation()
{
if (directionArray != null)
{
Play(directionArray[direction]);
}
}
public void SetAnimation(Skills state)
{
if (state == Skills.ROLL)
{
this.state = Skills.ROLL;
directionArray = RollDirections;
}
else if (state == Skills.RUN)
{
this.state = Skills.RUN;
directionArray = RunDirections;
}
else if (state == Skills.IDLE)
{
this.state = Skills.IDLE;
directionArray = IdleDirections;
}
direction = DirectionToIndex(8);
}
int DirectionToIndex(int sliceCount)
{
Vector2 dir = GetParent<PlayerController>().GetDirection();
float step = (float)(360/sliceCount);
float angle = Vector2.Up.AngleTo(dir);
angle = (float)(angle * (180/3.1415926));
if (angle < 0)
{
angle += 360;
}
float stepCount = angle/step;
if (stepCount > 7.5)
{
stepCount = 0;
}
return (int)stepCount;
}
}
_Process function in SkillManager:
public override void _Process(double delta)
{
if (skills != null)
{
for (int i = 0; i < skills.Count; i++)
{
switch (skills[i].GetState())
{
case Skill.State.READY:
if (Input.IsActionJustPressed(skills[i].GetKey()) && !skillIsActive)
{
skillIsInterruptable = skills[i].GetIsInterruptable();
skillIsActive = true;
skills[i].Use(GetParent<PlayerController>());
activeTime = skills[i].GetActiveTime();
skills[i].SetState(Skill.State.ACTIVE);
}
break;
case Skill.State.ACTIVE:
if (activeTime > 0)
{
activeTime -= delta;
}
else
{
skillIsInterruptable = true;
skillIsActive = false;
cooldownTime = skills[i].GetCooldownTime();
skills[i].SetState(Skill.State.COOLDOWN);
}
break;
case Skill.State.COOLDOWN:
if (cooldownTime > 0)
{
cooldownTime -= delta;
}
else
{
skills[i].SetState(Skill.State.READY);
}
break;
}
}
}
if (!skillIsActive! || skillIsInterruptable)
{
if (GetParent<PlayerController>().GetIsMoving())
{
run.Use(GetParent<PlayerController>());
}
else
{
idle.Use(GetParent<PlayerController>());
}
}
}
Use method in Roll class:
public override void Use(PlayerController player)
{
player.GetNode<AnimationController>("AnimationPlayer").SetAnimation(Skills.ROLL);
activeTime = player.GetNode<AnimationPlayer>("AnimationPlayer").CurrentAnimationLength;
}