im a newbie dev using godot 4, and ive been following tutorials for certain aspects of my game, lets say for this problem, wallrunning. Wallrunning by itself is working great, but the wall jumping however, is not. I know its something to do with me using the direction variable somehwere under the # Wallrun jump comment i made
extends CharacterBody3D
# Player Nodes
@onready var neck = $neck
@onready var head = $neck/Head
@onready var eyes = $neck/Head/eyes
@onready var camera = $neck/Head/eyes/Camera3D
@onready var standing_collision_shape = $standing_collision_shape
@onready var crouching_collision_shape = $crouching_collision_shape
@onready var crouching_raycast = $crouching_raycast
@onready var animation_player = $neck/Head/eyes/AnimationPlayer
# Speed Variables
var current_speed = 5.0
const walking_speed = 5.0
const sprinting_speed = 8.0
const crouching_speed = 3.0
const wallrun_speed = 4.0
# States
var walking = false
var sprinting = false
var crouching = false
var freelooking = false
var sliding = false
var jumping = false
var wallrunning = false
# Slide Vars
var slide_timer = 0.0
var slide_timer_max = 1.0
var slide_vector = Vector2.ZERO
var slide_speed = 10.0
# Headbobbing vars
const head_bobbing_sprinting_speed = 22.0
const head_bobbing_walking_speed = 14.0
const head_bobbing_crouching_speed = 10.0
const head_bobbing_sprinting_instensity = 0.2
const head_bobbing_walking_instensity = 0.1
const head_bobbing_crouching_instensity = 0.05
var head_bobbing_current_intensity = 0.0
var head_bobbing_vector = Vector2.ZERO
var head_bobbing_index = 0.0
# Wallrunning vars
var can_wallrun = false
var wallrun_delay = 0.2
@onready var wallrun_delay_default = wallrun_delay
@export var wallrun_angle = 15.0
var wallrun_current_angle = 0.0
var side = ""
var is_wallrun_jumping = false
var wall_jump_dir = Vector3.ZERO
@export var wall_jump_horizontal_power = 1.5
@export var wall_jump_vertical_power = 0.75
@export_flags_3d_physics var wall_jump_factor = 0.4
# Movement Variables
const jump_velocity = 4.5
var crouching_depth = -0.5
var freelook_lerp_speed = 15.0
var lerp_speed = 10.0
var air_lerp_speed = 3.0
var freelook_tilt_amount = 6.0
var last_velocity = Vector3.ZERO
# Input Variables
var direction = Vector3.ZERO
@export var mouse_sens = 0.25
# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _input(event):
# Mouse Movement
if event is InputEventMouseMotion:
if freelooking:
neck.rotate_y(deg_to_rad(-event.relative.x * mouse_sens))
neck.rotation.y = clamp(neck.rotation.y,deg_to_rad(-120),deg_to_rad(120))
else:
rotate_y(deg_to_rad(-event.relative.x * mouse_sens))
head.rotate_x(deg_to_rad(-event.relative.y * mouse_sens))
head.rotation.x = clamp(head.rotation.x,deg_to_rad(-89),deg_to_rad(89))
func _process(delta):
if Input.is_action_just_pressed("quit"):
get_tree().quit()
func _physics_process(delta):
# getting movement input
var input_dir = Input.get_vector("left", "right", "forward", "backward")
#Handle movement state
# crouching
if Input.is_action_pressed("crouch") || sliding:
current_speed = lerp(current_speed, crouching_speed, delta * lerp_speed)
head.position.y = lerp(head.position.y,crouching_depth, delta * lerp_speed)
# Slide begin logic
if sprinting && input_dir != Vector2.ZERO:
sliding = true
slide_timer = slide_timer_max
slide_vector = input_dir
freelooking = true
standing_collision_shape.disabled = true
crouching_collision_shape.disabled = false
walking = false
sprinting = false
crouching = true
elif !crouching_raycast.is_colliding():
# Standing
standing_collision_shape.disabled = false
crouching_collision_shape.disabled = true
head.position.y = lerp(head.position.y, 0.0, delta * lerp_speed)
if Input.is_action_pressed("sprint"):
# Sprinting and Walking
current_speed = lerp(current_speed, sprinting_speed, delta * lerp_speed)
walking = false
sprinting = true
crouching = false
else:
current_speed = lerp(current_speed, walking_speed, delta * lerp_speed)
walking = true
sprinting = false
crouching = false
# Handle Freelooking
if Input.is_action_pressed("freelook") || sliding:
freelooking = true
if sliding:
eyes.rotation.z = lerp(eyes.rotation.z, -deg_to_rad(7.0), lerp_speed * delta)
else:
eyes.rotation.z = -deg_to_rad(neck.rotation.y*freelook_tilt_amount)
else:
freelooking = false
neck.rotation.y = lerp(neck.rotation.y,0.0,freelook_lerp_speed * delta)
eyes.rotation.z = lerp(eyes.rotation.y,0.0,freelook_lerp_speed*delta)
# Add Gravity
if !is_on_floor():
velocity.y -= gravity * delta
# Handle Wallrunning
if is_on_floor():
wallrunning = false
can_wallrun = false
is_wallrun_jumping = false
wallrun_delay = wallrun_delay_default
else:
wallrun_delay = clamp(wallrun_delay - delta, 0 , wallrun_delay_default)
if wallrun_delay == 0.0:
can_wallrun = true
# Wallrun jump
if Input.is_action_just_pressed("jump") && wallrunning:
can_wallrun = false
wallrunning = false
velocity.y = jump_velocity * wall_jump_vertical_power
is_wallrun_jumping = true
if side == "LEFT":
wall_jump_dir = global_transform.basis.x * wall_jump_horizontal_power
elif side == "RIGHT":
wall_jump_dir = -global_transform.basis.x * wall_jump_horizontal_power
wall_jump_dir *= wall_jump_factor
if is_wallrun_jumping:
direction = (direction * (1 - wall_jump_factor)) + wall_jump_dir
return
process_wallrun()
wallrun_anims(delta)
# Handle jump.
if Input.is_action_pressed("jump") and is_on_floor():
velocity.y = jump_velocity
jumping = true
sliding = false
animation_player.play("jumping")
elif is_on_floor() && jumping:
jumping = false
# Handle Landing
if is_on_floor():
if last_velocity.y < -10.0:
animation_player.play("roll")
elif last_velocity.y < -4.0:
animation_player.play("landing")
# Handle Sliding
if sliding:
slide_timer -= delta
if slide_timer <= 0:
sliding = false
freelooking = false
# Handle Head Bobbing
if sprinting:
head_bobbing_current_intensity = head_bobbing_sprinting_instensity
head_bobbing_index += head_bobbing_sprinting_speed * delta
elif walking:
head_bobbing_current_intensity = head_bobbing_walking_instensity
head_bobbing_index += head_bobbing_walking_speed * delta
elif crouching:
head_bobbing_current_intensity = head_bobbing_crouching_instensity
head_bobbing_index += head_bobbing_crouching_speed * delta
if is_on_floor() && !sliding && input_dir != Vector2.ZERO:
head_bobbing_vector.y = sin(head_bobbing_index)
head_bobbing_vector.x = sin(head_bobbing_index/2) + 0.5
eyes.position.y = lerp(eyes.position.y, head_bobbing_vector.y * (head_bobbing_current_intensity / 2.0), delta * lerp_speed)
eyes.position.x = lerp(eyes.position.x, head_bobbing_vector.x * head_bobbing_current_intensity, delta * lerp_speed)
else:
eyes.position.y = lerp(eyes.position.y, 0.0, delta * lerp_speed)
eyes.position.x = lerp(eyes.position.x, 0.0, delta * lerp_speed)
# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
if is_on_floor():
direction = lerp(direction,(transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized(),delta*lerp_speed)
else:
if input_dir != Vector2.ZERO:
direction = lerp(direction,(transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized(),delta*air_lerp_speed)
if sliding:
direction = (transform.basis * Vector3(slide_vector.x,0,slide_vector.y)).normalized()
current_speed = direction.x * (slide_timer + 0.1) * slide_speed
if direction:
velocity.x = direction.x * current_speed
velocity.z = direction.z * current_speed
if sliding:
velocity.x = direction.x * (slide_timer + 0.1) * slide_speed
velocity.z = direction.z * (slide_timer + 0.1) * slide_speed
else:
velocity.x = move_toward(velocity.x, 0, current_speed)
velocity.z = move_toward(velocity.z, 0, current_speed)
last_velocity = velocity
move_and_slide()
func process_wallrun():
if can_wallrun:
if is_on_wall() && Input.is_action_pressed("forward") && Input.is_action_pressed("sprint"):
# Get collision data, and its normal
var collision = get_slide_collision(0)
var normal = collision.get_normal()
# Calculate direction on which we have to move
var wallrun_dir = Vector3.UP.cross(normal)
var player_view_dir = -camera.global_transform.basis.z
var dot = wallrun_dir.dot(player_view_dir)
if dot < 0:
wallrun_dir = -wallrun_dir
# Push against wall for stability
wallrun_dir += -normal * 0.01
# Enable Wallrunning
wallrunning = true
# sets side to a string, thats tells where the wall is
side = get_side(collision.get_position())
# Set gravity close to 0, and movement direction to new calculated wallrun direction
velocity.y = -0.01
direction = wallrun_dir
else:
wallrunning = false
func wallrun_anims(delta):
# Tilt the view
if wallrunning:
if side == "RIGHT":
wallrun_current_angle += delta * 60
wallrun_current_angle = clamp(wallrun_current_angle, -wallrun_angle, wallrun_angle)
elif side == "LEFT":
wallrun_current_angle -= delta * 60
wallrun_current_angle = clamp(wallrun_current_angle, -wallrun_angle, wallrun_angle)
# Return to normal view
else:
if wallrun_current_angle > 0:
wallrun_current_angle -= delta * 40
wallrun_current_angle = max(0, wallrun_current_angle)
elif wallrun_current_angle < 0:
wallrun_current_angle += delta * 40
wallrun_current_angle = min(wallrun_current_angle, 0)
neck.rotation_degrees = Vector3(0, 0, 1) * wallrun_current_angle
func get_side(point):
point = to_local(point)
if point.x > 0:
return "RIGHT"
elif point.x < 0:
return "LEFT"
else:
return "CENTER"
ive tried cutting the code, to figure out where the problem was happening. I also looked over the tutorials code 16 quadrillion times, to no avail