Okay, I think I may have gotten it. I have not tested it, but I think the following should work. I added a few notes around what I changed, explaining what it does and/or why I changed it. If I understand the situation correctly, the code should now allow you to dash in all four directions (relative to the rotation of the player) and you can dash in a different direction than the one the player is facing.
extends KinematicBody
var run_speed = 25
var run_acceleration = 4#6
var run_decceleration = 6
var gravity = 90
var jump_power = 22
var dash_speed = 100
var mouse_sensitivty = 0.3
var ground_contact = false
onready var head = $Head
onready var camera = $Head/Camera
var velocity = Vector3()
var camera_x_rotation = 0
var dash_count = 0
var is_dash = false
var may_dash = true
# For performance reasons, we probably want to store dash_direction
# outside of the _physics_process function. Additionally, it will make it
# easier to make the player unable to change directions while dashing
# in the future, if you choose to implement it.
var dash_direction = Vector3.ZERO
func _physics_process(delta):
var head_basis = head.get_global_transform().basis
var direction = Vector3()
var velocity_xz = Vector3(velocity.x, 0, velocity.z)
var velocity_y = Vector3(0, velocity.y, 0)
# if we have a node that is the direction the head is looking at, we can
# instead use it directly to get the direction using basis.x, basis.y, and basis.z
# (which will correspond to the directions of the red, green, and blue arrows
# in the Godot editor when "local space", the box icon, is selected)
#run
if Input.is_action_pressed("Move_Forward"):
direction -= head_basis.z
elif Input.is_action_pressed("Move_Backward"):
direction += head_basis.z
#dash
# (minor note: with this code, the player will dash whenever they move. Also,
# you may want to check if the player is already dashing before staring a new dash.)
if Input.is_action_just_pressed("Move_Forward"):
$DashTimer.start()
dash_count += 1
# set the dash direction to so it points forward
# (also, we optionally normalize so the scale of the head
# node does not affect the dash speed)
dash_direction = head_basis.z.normalized()
elif Input.is_action_just_pressed("Move_Backward"):
$DashTimer.start()
dash_count += 1
# set the dash direction to so it points backward
dash_direction = -head_basis.z.normalized()
#run
if Input.is_action_pressed("Move_Left"):
direction -= head_basis.x
elif Input.is_action_pressed("Move_Right"):
direction += head_basis.x
#dash
if Input.is_action_just_pressed("Move_Left"):
$DashTimer.start()
dash_count += 1
# set the dash direction to so it points backward
dash_direction = -head_basis.x.normalized()
elif Input.is_action_just_pressed("Move_Right"):
$DashTimer.start()
dash_count += 1
# set the dash direction to so it points backward
dash_direction = head_basis.x.normalized()
if ground_contact and Input.is_action_just_pressed("Jump"):
velocity_y.y = jump_power
if not direction.dot(velocity_xz) > 0:
run_acceleration = run_decceleration
#Dash
if ground_contact and may_dash and dash_count >= 2:
$DashCooldown.start()
is_dash = true
velocity_y.y = jump_power
#dash_dir *= dash_speed
may_dash = false
print(dash_dir)
# if we are dashing, then set the velocity to the dash direction!
if (is_dash == true):
# Set the X and Z velocity to the direction of the dash
velocity.x = dash_direction.x * dash_speed
velocity.z = dash_direction.z * dash_speed
direction = direction.normalized()
velocity_xz = velocity_xz.linear_interpolate(direction * run_speed, run_acceleration * delta)
velocity_y.y -= gravity * delta
velocity = velocity_xz + velocity_y
velocity = move_and_slide(velocity, Vector3.UP)
func _on_DashTimer_timeout():
dash_count = 0
is_dash = false
# optional: reset dash_direction
dash_direction = Vector3.ZERO
pass
func _on_DashCooldown_timeout():
may_dash = true
pass
Again, I have not tested it, but I think that should do it. At very least, hopefully it is somewhat helpful :smile: