I want to make it so that when i shoot the gun i the player gets knockbacked

Godot Version

4.3.Stable

Player Code

extends CharacterBody2D
 
const MAX_SPEED: int = 125
const ACCELERATION: int = 1400

@onready var animated_sprite: AnimatedSprite2D = $AnimatedSprite2D


func _process(_delta:) -> void:
	if get_global_mouse_position().x < global_position.x:
		animated_sprite.flip_h = true
	else:
		animated_sprite.flip_h = false
	if not is_on_floor():
		animated_sprite.play("Fall")
	else:
		animated_sprite.play("Idle")
	move_and_slide()

func _physics_process(delta):


	if not is_on_floor():
		velocity += get_gravity() * delta
	
	pass

Gun Code

extends Node2D


var can_shoot : bool = true
var knockback_dir = Vector2()


 
const BULLET = preload("res://Scenes/bullet.tscn")

@onready var muzzle: Marker2D = $Marker2D
@onready var gun_cooldown: Timer = $GunCooldown
@onready var randomized: AudioStreamPlayer = $Randomized


func _process(_delta: float) -> void:
	look_at(get_global_mouse_position())
 
	rotation_degrees = wrap(rotation_degrees, 0, 360)
	if rotation_degrees > 90 and rotation_degrees < 270:
		scale.y = -1
	else:
		scale.y = 1

	if Input.is_action_just_pressed("fire") and can_shoot:
		shoot()
func shoot() -> void:
	
	can_shoot = false
	$GunCooldown.start()
	
	var bullet_instance = BULLET.instantiate()
	get_tree().root.add_child(bullet_instance)
	bullet_instance.global_position = muzzle.global_position
	bullet_instance.rotation = rotation
	
	$Randomized.play_with_random_pitch() 

func _on_gun_cooldown_timeout() -> void:
	can_shoot = true

Question

So i want to add knockback to the player when i shoot the gun, can someone help me do that

All you really need to do is get the motion vector of your bullet, invert it (that is, negate all the components so it’s reversed) normalize it (so the vector is length 1), scale it by how much knockback you want, and apply that as an impulse to the player.

You should be able to do that all in shoot().

For future reference, code formats more nicely here on the forums if you do:

```gdscript
code
```

im pretty new can you show me some code and maybe explain it a bit more? (I also changed the format)

Is this top-down, or side view?

Assuming it’s top-down, you could do something like:

# in the gun code

const KNOCKBACK_SCALE: float = 100.0 # Probably not the right value, tune this...

func shoot() -> void:
    [...stuff...]

    # Make a vector that's a unit vector rotated as the bullet is, plus another
    # 180 degrees so it's heading in the opposite direction.  We do that by adding
    # PI, since there are 2*PI radians in a circle, so PI is half a circle, in
    # radians.

    var knockback: Vector2 = Vector2.RIGHT.rotated(rotation + PI)

    # Add the knockback to the player's velocity as an impulse, scaled by the
    # amount you want to kick the player.

    player.velocity += knockback * KNOCKBACK_SCALE

You’ll probably have to wire up access to the player from the gun.

its side view, will that still work?

Side view is easier, since you’ve only got two directions. Just add a velocity impulse (+100 or -100, say) to the player’s velocity.x.

If you can aim in all directions and want knockback at any angle of the circle, the more complex code will do it.

when i do the player velocity it gives me an error that says = identifier “Player” not declared in current scope

You’ll need to do something like:

   get_parent().velocity += knockback * KNOCKBACK_SCALE

Or something like that. It depends on where the gun and the player are relative to each other in the node hierarchy. If the gun is a child of the player, get_parent() or $".." will work. If they’re further apart, you’ll need the right node path.

Thank you so much this works but, where do i change the amount of knockback that the player is dealt?

Change the value of KNOCKBACK_SCALE; a smaller number means less knockback, a bigger number means more.

What’s going on here is we’re building a vector, knockback, which contains the direction we want the knockback to go in. We’re making that length 1.0 (that is, the length of the line from the origin to the vector (as a position) is a distance of 1.0).

We then change the amount of force by multiplying the knockback vector by KNOCKBACK_SCALE, which changes the length of the vector to be equal to that value, so if KNOCKBACK_SCALE was 5.0, the length of knockback will become 5.0.

ok thank you!

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