Godot Version
4.3
Question
I’m having trouble applying knockback on another player when he is hit by another player, the damage works, the knockback doesnt
here is my player script:
extends CharacterBody3D
@export var JUMP_VELOCITY = 4.5
const MOUSE_SENSITIVITY = 0.1
var SPEED = 5.0
@export var sprint_speed = 7.5
@export var crouch_speed = 3.5
@export var walk_speed = 5.0
@export var BASE_HEALTH = 250
var health = BASE_HEALTH
var knockback=Vector3.ZERO
@export var baseheight = 0.9
var HEIGHT = 0.9
@export var crouching_depth = -0.75
var base_pos
var base_velo
var wall_normal
var pull
var target_pos
var timer
var slide_indulgence_timer = 0.5
#movement_possible
@export var can_wall_run = true
@export var can_slide = true
#states
var on_wall = false
var walking = false
var sprinting = false
var crouching = false
var sliding = false
var slide_timer= 0.0
var slide_timer_max= 1.3
var slide_vector= Vector2.ZERO
var slide_speed = 10
var BOB_FREQ = 2.0
var BOB_AMP = 0.05
var t_bob=0.0
var BASE_FOV= 85.0
var FOV_CHANGE = 3.5
#anim
var PUNCH=1
# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = 9.8
@onready var standing_model=$standing_model
@onready var crouching_model=$crouching_model
@onready var crouching_collision_shape= $crouching_collision_shape
@onready var standing_collision_shape= $standing_collision_shape
@onready var camera = $CamRoot/Camera3D
@onready var ray_cast = $RayCast3D
@onready var ray_cast_l = $RayCast3D_left
@onready var ray_cast_r = $RayCast3D_right
@onready var tp_cast = $CamRoot/Camera3D/RayCast3D
@onready var hit_cast = $CamRoot/Camera3D/Hit_cast
@onready var hand_anim = $CamRoot/Camera3D/fps_rig/shotgun/PSX_First_Person_Arms/AnimationPlayer
func _enter_tree():
set_multiplayer_authority(name.to_int())
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
camera.current = is_multiplayer_authority()
func _process(delta):
window_activity()
func window_activity():
if Input.is_action_just_pressed("ui_cancel"):
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
else:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _input(event):
if is_multiplayer_authority():
if event is InputEventMouseMotion:
# Rotates the view vertically
$CamRoot.rotate_x(deg_to_rad(event.relative.y * MOUSE_SENSITIVITY * -1))
$CamRoot.rotation_degrees.x = clamp($CamRoot.rotation_degrees.x, -75, 75)
# Rotates the view horizontally
self.rotate_y(deg_to_rad(event.relative.x * MOUSE_SENSITIVITY * -1))
func _physics_process(delta):
if is_multiplayer_authority():
var input_dir = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if !sliding and !on_wall:
$CamRoot.rotation_degrees.z = lerp($CamRoot.rotation_degrees.z, -4.0*sign(input_dir.x),delta* 5)
else:
$CamRoot.rotation_degrees.z = lerp($CamRoot.rotation_degrees.z, 0.0,delta* 4)
#click logic
if Input.is_mouse_button_pressed( 1 ) and (hand_anim.current_animation != "Combat_punch_left" and hand_anim.current_animation != "Combat_punch_right"):
if hit_cast.is_colliding() :
if hit_cast.get_collider().is_in_group("player"):
var knock_direction = $CamRoot.position.direction_to(hit_cast.get_collider().position)
var knock_force = 7.0
hit_cast.get_collider().knockback= knock_direction*knock_force
hit_cast.get_collider().take_damage(5)
if PUNCH==1:
hand_anim.play("Combat_punch_left")
PUNCH=0
else:
hand_anim.play("Combat_punch_right")
PUNCH=1
else:
hand_anim.queue("Combat_idle")
#click logic end
#pull logic start
if Input.is_action_pressed("E_spec") and Global.E_spec_cooldown<=0 and position.distance_to(tp_cast.get_collision_point())>5:
if tp_cast.is_colliding():
Global.E_spec_cooldown = 5.0
hand_anim.play("Collect_something",-1)
hand_anim.queue("Combat_idle_start")
pull=true
base_pos=position
base_velo= velocity
timer = 0
target_pos= lerp(position,tp_cast.get_collision_point(),1-(1/(position.distance_to(tp_cast.get_collision_point()))))
Global.E_spec_cooldown-=delta
if pull == true:
if position.distance_to(target_pos)<1.5 or timer>1 :
pull = false
velocity.y=clamp(9*$CamRoot.rotation.x,0.0,10)
else:
if (target_pos-base_pos).length() < 10:
velocity = (target_pos-base_pos).normalized()*10 + (0.1*velocity)
else:
velocity = target_pos-base_pos + (0.1*velocity)
timer+=delta
#pull logic end
if Input.is_action_pressed("ui_crouch") and !on_wall:
SPEED = crouch_speed
standing_collision_shape.disabled = true
crouching_collision_shape.disabled = false
standing_model.visible = false
crouching_model.visible = true
HEIGHT= lerp(HEIGHT,baseheight + crouching_depth,delta*7)
#slide begin logic
if can_slide:
if (slide_indulgence_timer<0.5 or velocity.length()>5.0 or velocity.y < 0) and input_dir != Vector2.ZERO and !sliding and !is_on_wall():
sliding = true
slide_timer = slide_timer_max
slide_vector= input_dir
walking = false
sprinting = false
crouching = true
elif !ray_cast.is_colliding():
HEIGHT= lerp(HEIGHT, baseheight ,delta*7)
standing_collision_shape.disabled = false
crouching_collision_shape.disabled = true
standing_model.visible = true
crouching_model.visible = false
if Input.is_action_pressed("ui_sprint"):
SPEED = sprint_speed
walking = false
sprinting = true
slide_indulgence_timer=0.0
crouching = false
else:
SPEED = walk_speed
walking = true
sprinting = false
crouching = false
if can_slide:
slide_indulgence_timer+=delta
# handle sliding
if sliding:
slide_timer-=delta
$CamRoot.rotation.z= lerp($CamRoot.rotation.z, deg_to_rad(6.0),delta* 7)
HEIGHT= lerp(HEIGHT,baseheight + crouching_depth,delta*7)
if slide_timer<=0:
sliding=false
$CamRoot.rotation.z = lerp($CamRoot.rotation.z, 0.0, delta * 4.5)
HEIGHT= lerp(HEIGHT,baseheight ,delta* 1)
if can_wall_run:
if ((is_on_wall() and !is_on_floor())) or on_wall:
if !on_wall:
on_wall = true
wall_normal = get_slide_collision(0)
velocity.z*=2
velocity.y = 2
gravity = 2
if is_on_wall():
direction += -(wall_normal.get_normal(0)/1.5)
if ray_cast_l.is_colliding():
$CamRoot.rotation.z= lerp($CamRoot.rotation.z, deg_to_rad(20.0),delta* 4.5)
elif ray_cast_r.is_colliding():
$CamRoot.rotation.z= lerp($CamRoot.rotation.z, deg_to_rad(-20.0),delta* 4.5)
if (!(ray_cast_l.is_colliding() or ray_cast_r.is_colliding()) and !is_on_wall()) or is_on_floor() :
gravity = 9.8
$CamRoot.rotation.z = lerp($CamRoot.rotation.z, 0.0, delta * 4.5)
on_wall=false
# Add the gravity.
if not is_on_floor():
velocity.y -= gravity * delta
# Handle Jump.
if Input.is_action_just_pressed("ui_accept") and (is_on_floor() or on_wall) and !ray_cast.is_colliding():
if on_wall and is_on_wall():
velocity += wall_normal.get_normal(0) * JUMP_VELOCITY
if pull:
pull = false
velocity.y=clamp(9*$CamRoot.rotation.x,0.0,10)
if sliding:
sliding=false
$CamRoot.rotation.z = lerp($CamRoot.rotation.z, 0.0, delta * 7)
HEIGHT= lerp(HEIGHT,baseheight ,delta* 1)
velocity.y = JUMP_VELOCITY*1.5
sliding = false
slide_timer=0.0
# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
if sliding:
direction = (transform.basis * Vector3(slide_vector.x,0,slide_vector.y)).normalized()
if is_on_floor():
if !pull:
if direction:
velocity.x = direction.x * SPEED
velocity.z = direction.z * SPEED
if sliding:
velocity.x = direction.x * (slide_timer+0.15) * slide_speed
velocity.z = direction.z * (slide_timer+0.15) * slide_speed
else:
velocity.x = lerp(velocity.x, direction.x * SPEED, delta * 7.0)
velocity.z = lerp(velocity.z, direction.z * SPEED, delta * 7.0)
else:
velocity.x = lerp(velocity.x, direction.x * SPEED, delta * 3.0)
velocity.z = lerp(velocity.z, direction.z * SPEED, delta * 3.0)
velocity += knockback
knockback = lerp(knockback, Vector3.ZERO, 3)
t_bob += delta * velocity.length() * float(is_on_floor())
$CamRoot.transform.origin= _headbob(t_bob)
var velocity_clamped = clamp(velocity.length(), 0.5, 12)
var target_fov = BASE_FOV + FOV_CHANGE * velocity_clamped
camera.fov = lerp(camera.fov, target_fov, delta * 8.0)
move_and_slide()
func _headbob(time) -> Vector3:
var pos = Vector3.ZERO
pos.y = sin(time * BOB_FREQ) * BOB_AMP + HEIGHT
pos.x = cos(time * BOB_FREQ / 2) * BOB_AMP
return pos
func take_damage(amt):
health -= amt
$GPUParticles3D.restart()