Attack Animation Stuck On 1st Frame in C#

Godot Version

4.2.2

Question

Currently I have a very basic 2D game set up. I have a player that is able to move in 8 directions, and there are animations to go along with that as well as an idle one. Just recently I started working on implementing an attack animation, however the issue is that whenever I click the mouse for the attack animation to run, it briefly appears for 1 frame and then stops. I did some research about this and learned that it has to do with a constant call on the other movement animations being done at the same time as the attack animation. I’ve tried following tutorials online on how to fix this, but I have been unsuccessful since they are all in GDScript. What is an efficient way to fix this issue in C#?

Here is my code for my player node for reference (it’s a bit messy since this is my first project)

using Godot;

public partial class player : CharacterBody2D
{
	[Export] private float Speed = 150.0f;
	[Export] private float JumpVelocity = -400.0f;
	public override void _PhysicsProcess(double delta)
	{
		Vector2 velocity = Velocity;

		Vector2 direction = Input.GetVector("left", "right", "up", "down");
		if (direction != Vector2.Zero)
		{
			velocity.X = direction.X * Speed;
			velocity.Y = direction.Y * Speed;
		}
		else
		{
			velocity.X = Mathf.MoveToward(Velocity.X, 0, Speed);
			velocity.Y = Mathf.MoveToward(Velocity.Y, 0, Speed);
		}

		Velocity = velocity;
		ActionAnimation();
		MovementAnimation();
		MoveAndSlide();
	}

	//handles movement animation
	void MovementAnimation()
	{
		Vector2 velocity = Velocity;
		var animatedSprite = GetNode("AnimatedSprite2D") as AnimatedSprite2D;

		// handles movement animations
		if (velocity.X < 0)
		{
			animatedSprite.Play("left");
		}
		else if (velocity.X > 0)
		{
			animatedSprite.Play("right");
		}
		else if (velocity.Y < 0)
		{
			animatedSprite.Play("up");
		}
		else if (velocity.Y > 0)
		{
			animatedSprite.Play("down");
		}
		else
		{
			animatedSprite.Play("idle");
		}

		// handles diagonal direction facing
		if (velocity.X > 0 && velocity.Y != 0)
		{
			animatedSprite.Play("right");
		}
		if (velocity.X < 0 && velocity.Y != 0)
		{
			animatedSprite.Play("left");

		}
	}

	void ActionAnimation()
	{
		var attackAnim = GetNode("AnimatedSprite2D") as AnimatedSprite2D;

		// handles action animation
		if (Input.IsActionJustPressed("action"))
		{
			attackAnim.Play("attackdown");
		}
	}
}

It dosen’t matter what language you are using, it is all the same logic. You need a boolean called "“isAttacking” or something. Set it to true when you’re attacking and call the attack animation. Only call the other animations when isAttacking equals false.

There is a method called IsPlaying() which you can use to set the isAttacking boolean assuming it’s not set to loop.

I tried setting my isAttacking variable to true whenever the attack animation is playing, and I added an if condition that says whenever isAttacking is false it will run through the movement animations, but now all of my movement animations are stuck at 1 frame and my attack animation still has the same issue.

void MovementAnimation()
	{
		Vector2 velocity = Velocity;
		var animatedSprite = GetNode("AnimatedSprite2D") as AnimatedSprite2D;

		// handles movement animations
		if (isAttacking == false)
		{
			if (velocity.X < 0)
			{
				animatedSprite.Play("left");
			}
			else if (velocity.X > 0)
			{
				animatedSprite.Play("right");
			}
			else if (velocity.Y < 0)
			{
				animatedSprite.Play("up");
			}
			else if (velocity.Y > 0)
			{
				animatedSprite.Play("down");
			}
			else
			{
				animatedSprite.Play("idle");
			}

			// handles diagonal direction facing
			if (velocity.X > 0 && velocity.Y != 0)
			{
				animatedSprite.Play("right");
			}
			if (velocity.X < 0 && velocity.Y != 0)
			{
				animatedSprite.Play("left");

			}
		}
		else
		{
			animatedSprite.Stop();
		}

	}

	void ActionAnimation()
	{
		var attackAnim = GetNode("AnimatedSprite2D") as AnimatedSprite2D;

		// handles action animation
		if (Input.IsActionJustPressed("action"))
		{
			attackAnim.Play("attackdown");
		}
		if (attackAnim.IsPlaying())
		{
			isAttacking = true;

		}
		else
		{
			isAttacking = false;
		}
	}

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.