Godot Version
Godot 4
Question
Ask your question here! Try to give as many details as possible.
If you share code, please wrap it inside three backticks or replace the code in the next block:
extends CharacterBody2D
class_name PlayerController
@onready var animation_player: AnimationPlayer = $Animation_Controls/AnimationPlayer
@onready var currenthealth: int = max_health
# Movement Variables
@export var speed : float = 300.0
@export var jump_force : float = -250.0
@export var jump_time : float = 0.25
@export var coyote_time : float = 0.075
@export var gravity_multiplier : float = 3.0
@export var max_health = 3
(@export var Min_Knockback := 100
@export var Slow_Knockback := 1.3) ------------------> This is knockback
var direction = 0
var is_jumping : bool = false
var jump_timer : float = 0
var coyote_timer : float = 0
var can_control : bool = true
var Knockback : Vector2 = Vector2.ZERO
func _physics_process(delta: float) -> void:
var direction2 = global_position - Knockback
(if Knockback.length() > Min_Knockback:
Knockback /= Slow_Knockback
velocity = direction2.normalized() * Knockback
move_and_slide()
return) -----------------------------------------------------------------------> This is the issues in this whole line line
if not can_control: return
# Add the gravity.
if not is_on_floor() and not is_jumping:
velocity += get_gravity() * gravity_multiplier * delta
coyote_timer += delta
else:
coyote_timer = 0
# Handle jump.
if Input.is_action_just_pressed("Jump") and (is_on_floor() or coyote_timer < coyote_time):
velocity.y = jump_force
is_jumping = true
elif Input.is_action_pressed("Jump") and is_jumping:
velocity.y = jump_force
if is_jumping and Input.is_action_pressed("Jump") and jump_timer < jump_time:
jump_timer += delta
else:
is_jumping = false
jump_timer = 0
# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
direction = Input.get_axis("Left", "Right")
if direction:
velocity.x = direction * speed
else:
velocity.x = move_toward(velocity.x, 0, speed)
move_and_slide()
func handle_danger() -> void:
currenthealth -= 1
if currenthealth == 0:
print("You Died")
visible = false
can_control = false
await get_tree().create_timer(1).timeout
reset_player()
func reset_player() -> void:
currenthealth = 3
global_position = Vector2(0,-78.0)
visible = true
can_control = true
i also have a seperate scene with an area 2d that i transfer for knockback i drag and drop on entities
[ extends Area2D
@export var Knockback := 1000
func _on_body_entered(body: Node2D) -> void:
if body is PlayerController:
body.Knockback = (body.position - position).normalized() * Knockback
print("KIK")
]
The problem is he always move to the right or left if i negate knockback how do i fix that
This will always instantly reset the player’s speed, the else hints towards how to fix it but the template is flawed
This moves velocity towards zero by speed each frame, though it should be per-second.
If you want to simplify this using the same acceleration value you can remove the if/else, create an acceleration variable 8x the player’s speed should feel pretty snappy
direction = Input.get_axis("Left", "Right")
velocity.x = move_toward(velocity.x, direction * speed, acceleration * delta)
you’re asking me to make a new acceleration value just to be sure ?
You would need one to implement the sample I posted
1 Like
ok so how would i fix the direction that i knockback in i fixed the speed
The direction of your knockback seems influenced by repeating equations, these do similar things to Knockback but their effect stacks; you probably mean to remove direction2 and just use Knockback in your physics_process.
Or with your new acceleration based movement you can avoid the Knockback variables entirely by editing the player’s velocity directly on impact
func _on_body_entered(body: Node2D) -> void:
if body is PlayerController:
var direction := position.direction_to(body.position)
body.velocity = direction * Knockback
This is the improvised player code he still only goes 1 direction
extends CharacterBody2D
class_name PlayerController
@onready var animation_player: AnimationPlayer = $Animation_Controls/AnimationPlayer
@onready var currenthealth: int = max_health
# Movement Variables
@export var acceleration := 2400.0
@export var speed : float = 300.0
@export var jump_force : float = -250.0
@export var jump_time : float = 0.25
@export var coyote_time : float = 0.075
@export var gravity_multiplier : float = 3.0
@export var max_health = 3
@export var Min_Knockback := 100
@export var Slow_Knockback := 1.3
var direction = 0
var is_jumping : bool = false
var jump_timer : float = 0
var coyote_timer : float = 0
var can_control : bool = true
var Knockback : Vector2 = Vector2.ZERO
func _physics_process(delta: float) -> void:
if Knockback.length() > Min_Knockback:
Knockback /= Slow_Knockback
velocity = direction * Knockback
move_and_slide()
return
if not can_control: return
# Add the gravity.
if not is_on_floor() and not is_jumping:
velocity += get_gravity() * gravity_multiplier * delta
coyote_timer += delta
else:
coyote_timer = 0
# Handle jump.
if Input.is_action_just_pressed("Jump") and (is_on_floor() or coyote_timer < coyote_time):
velocity.y = jump_force
is_jumping = true
elif Input.is_action_pressed("Jump") and is_jumping:
velocity.y = jump_force
if is_jumping and Input.is_action_pressed("Jump") and jump_timer < jump_time:
jump_timer += delta
else:
is_jumping = false
jump_timer = 0
# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
direction = Input.get_axis("Left", "Right")
velocity.x = move_toward(velocity.x, direction * speed, acceleration * delta)
move_and_slide()
func handle_danger() -> void:
currenthealth -= 1
if currenthealth == 0:
print("You Died")
visible = false
can_control = false
await get_tree().create_timer(1).timeout
reset_player()
func reset_player() -> void:
currenthealth = 3
global_position = Vector2(0,-78.0)
visible = true
can_control = true
Here is the improvised Knockback area code still doesn’t work i tried some other things it didn’t work
extends Area2D
@export var Knockback := 1000
func _on_body_entered(body: Node2D) -> void:
if body is PlayerController:
var direction := position.direction_to(body.position)
body.velocity = direction * Knockback
print("KIK")
This is overriding the acceleration based movement, should be removed too.
If it still calculates the wrong direction then you should try using global_position instead of position, are the enemies and players siblings in the scene tree? Or do enemies end up children of a different node?
func _on_body_entered(body: Node2D) -> void:
if body is PlayerController:
var direction := global_position.direction_to(body.global_position)
body.velocity = direction * Knockback