Jumping on the enemy doesn't make the Player bounce

Godot Version

4.2.2

Question

I’m trying to make the player bounce off of the enemy, but it for some reason wont. The function to bounce is called, but nothing actually happens.

Code:

player code to actually bounce

public void StompEnemy()
	{
		GD.Print("Velocity: "+velocity.Y);
		velocity.Y = -120.0f;
		GD.Print("Velocity: "+velocity.Y);
	}

code for jumping in physics_process

velocity = Velocity;

		if (!IsOnFloor())
		{
			velocity.Y += Gravity * (float)delta;
		}

		if (Input.IsActionPressed("Jump") && IsOnFloor())
		{
			JumpSound.Play();
			CanCancelJump = true;
			velocity.Y = JumpVelocity;
		}
		if (Input.IsActionJustReleased("Jump") && CanCancelJump == true)
		{
			velocity.Y *= 0.3f;
			if(!IsOnFloor())
			{
				velocity.Y--;
			}
			CanCancelJump = false;
		}

Where do you call your StompEnemy function ?

BTW GD.Print("Velocity: "+velocity.Y); can be replace by GD.Print("Velocity: ", velocity.Y);

velocity = Velocity;

Seems like you are removing any work done on velocity with this line at the start of _physics_process

I call the function in the Enemy script:

private void OnHit(Node2D body)
	{
		if (body is Player)
		{
			var Player = new Player();
			Player.StompEnemy();
		}
	}

(also the print line is only temporary, so it doesn’t matter that much)

How is velocity defined? I’ve never seen it done this way to copy Velocity to a lowercase version

I could of sworn that’s how it was done in Godot C#, but I just tried without it and it makes sliding down slopes possible. But it still doesn’t make bouncing off the enemy possible.

did you remove lowercase velocity and replace it with capitalized Velocity or only removed that one line I pointed out?

I removed lowercase velocity, in Godot C# it doesn’t allow you to edit the uppercase Velocity (the built in one) easily (so I can’t change Velocity.Y directly), so using a separate velocity variable fixes this.

Yeah the whole new Vector3(velocity.x, 10, velocity.z) thing gets annoying. Is there anywhere else Velocity is set (=) rather than added/subtracted(+=) to?

Here are all the instances of Velocity changed in general:

if (!IsOnFloor())
		{
			velocity.Y += Gravity * (float)delta;
		}
if (Input.IsActionJustReleased("Jump") && CanCancelJump == true)
		{
			velocity.Y *= 0.3f;
			if(!IsOnFloor())
			{
				velocity.Y--;
			}
			CanCancelJump = false;
		}
if (direction != Vector2.Zero)
		{
			velocity.X = direction.X * Speed;
			if (velocity.X > 0)
			{
				Sprite.FlipH = false;
			}
			else if (velocity.X < 0)
			{
				Sprite.FlipH = true;
			}
		}
		else
		{
			velocity.X = velocity.X * 0.8f;
		}
Velocity = velocity;

you can move StompEnemy() to
physics_process and make private.
make boolean variable to check if in this physics_process frame you stomped on enemy.

private void OnHit(Node2D body)
	{
		if (body is Player)
		{
			var Player = new Player();
			Player.StompEnemy();
		}
	}

On you don’t want make new player, you don’t added new player to tree anyway.

if (body is Player player)
		{
			player.stompEnemy = true; // if stompEnemy is boolean variable, you can use first capital later if is property with {get;set;} 
		}
1 Like

alternative casting is like this
var player = (Player)body;

Usually, when you’re trying to modify the velocity but you notice that it isn’t visibly affecting the character, it’s because the new modifications of the Velocity property weren’t included by the MoveAndSlide() method.

So I think you should maybe try to add it as the last line of your StompEnemy() function as such:

public void StompEnemy()
{
	Velocity.Y = -120.0f;
	MoveAndSlide();
}

and get instantly overwritten in physic process

apart from making it private, that worked completely.

physics_process is already private, and local functions can’t have their protection level changed, it inherits from the function it’s apart of.

for anyone wondering, here’s the bit of code changed:

Player.cs

public bool StompedEnemy = false;
public override void _PhysicsProcess(double delta)
{
	*(rest of the code before this)*
	if (StompedEnemy == true)
		{
			StompEnemy();
		}

		void StompEnemy()
		{
			velocity.Y = -120.0f;
			StompedEnemy = false;
		}
	*(code after)*
}

Enemy.cs

private void OnHit(Node2D body)
	{
		if (body is Player player)
		{
			player.StompedEnemy = true;
		}
	}
1 Like

you can
if (StompedEnemy)
you don’t needed check if true == true or false == true :slight_smile:

public bool StompedEnemy = false;
private Vector2 velocity;
public override void _PhysicsProcess(double delta)
{
	*(rest of the code before this)*
	if (StompedEnemy)
	{
		StompEnemy();
	}
	*(code after)*
}

private void StompEnemy()
{
	velocity.Y = -120.0f;
	StompedEnemy = false;
}

in this move vector to to class variable and move method back to class,
other version with less code and keeping vector locally

public bool StompedEnemy = false;
public override void _PhysicsProcess(double delta)
{
	*(rest of the code before this)*
	if (StompedEnemy)
	{
		velocity.Y = -120.0f;
		StompedEnemy = false;
	}
	*(code after)*
}
1 Like

I know about not needing to do “== true”, just made this in a bit of a rush.