Rotation and inputs not working

Godot Version

4.6

Question

My physics wont work inputs get crossed and other things could someone help me

extends CharacterBody3D

class_name Player

@export var small_speed = 32.5
@export var big_speed = 48.75
@export var other_camera = Node3D
var speed_timer = 0
var land = false
@export var tauntsprite = preload("res://Newest_Beeder_Taunt.png")
var taunted = false
var SPEED = 17.5
var beforevel = Vector3.ZERO
var resetposs = Vector3.ZERO
var in_dir = Vector2.ZERO
var divespeed = 0.0
var dive = false
var reset = -20
var resetpos = Vector3.ZERO
var resettime = 0.0
@export var water = false
var health = 8:
	set(new_value):
		var old_trick = health
		health = new_value
		if health != old_trick:
			stuffering()
var groundpound = false
var walljump = false
const JUMP_VEVO = 8
var attacking = false
enum states { Normal, Air, Spindash, Roll, Dive, Homing, Hurt, Dead }
@export var music = Node3D
var homing = Node3D
var alreadyfound = Node3D
@export var thinger = Node3D
@export var level = 0
@export var linuxmusic = Node3D
@export var idle = preload("res://Newest_Beeder_Idle.png")
@export var run = preload("res://New_Beeder_Run.png")
@export var walk = preload("res://New_Beeder_Walk.png")
@export var diver = preload("res://New_Beeder_Dive.png")
@export var jump = preload("res://New_Beeder_Jump.png")
@export var landing = preload("res://New_Beeder_Land.png")
var small_sounds = [preload("res://output.wav"), preload("res://output (1).wav")]
var big_sounds = [preload("res://output (2).wav"), preload("res://output (3).wav"), preload("res://output (7).wav")]
var hurt_sounds = [preload("res://output (4).wav"), preload("res://output (5).wav")]
# Trick Template [Name,Time,Score]
var tricks = [["", 0, 0], ["Wall Jump", 0.5, 50], ["Big Boost", 2, 200], ["Show Off", 0.1, 10], ["Small Boost", 0.25, 25], ["Land", 0.45, 45], ["Max Speed", 0.2, 20], ["Homing Chain", 1, 100], ["Groundpound", 0.2, 20], ["Homing Start", 0.5, 50], ["Bad Bounce", 0.5, 50], ["Spring", 0.2, 20]]
var trickdone = tricks[0]:
	set(new_value):
		var old_trick = trickdone
		trickdone = new_value
		if trickdone != old_trick:
			stuff()
var tricksdone = []
var score = 0:
	set(new_value):
		var old = score
		score = new_value
		if score != old:
			scoreing()
var timer = 0:
	set(new_value):
		var old = timer
		timer = new_value
		if timer != old:
			thing()
var vevo = Vector3.ZERO
var state = states.Air
@export var boss = false
var v = Vector3.ZERO
@export var base_land = "Dirt"
var other_land = ""
var land_type = "Dirt"
var savevevo = vevo
@export var hurt = preload("res://New_Beeder_Hurt.png")
signal list(value: Array)
signal scoring(valueee: float)
signal timing(valuee: float)
signal coininger(valueeee: float)
signal adding(val: float)
signal halth(vall: float)
var time = 0:
	set(new_value):
		var old = time
		time = new_value
		if time != old:
			thing()
var direction = 0
var animation = 0
var slope = 0
var size = 0
var adding_up = 0:
	set(new_value):
		var oldd = adding_up
		adding_up = new_value
		if adding_up != oldd:
			timingtwo()
var coin = 0:
	set(new_value):
		var oldd = coin
		coin = new_value
		if coin != oldd:
			coining()
@export var gravity_scale = 1.2
var surface_normal = Vector3.ZERO
@export var camera = Node3D
var big_boost = false
var timert = 0
var taunt = false
@export var saving = true
var di = Vector3.FORWARD
var spindash = 0
var vx = 0
var homingchain = 0:
	set(new_value):
		var old = homingchain
		homingchain = new_value
		if homingchain != old && homingchain != 0:
			homingchainer()
# Build a stable orthonormal basis that uses `new_y` as the up vector


func stuffering():
	halth.emit(health)


func scoreing():
	scoring.emit(score)


func timingtwo():
	adding.emit(adding_up)


func coining():
	coininger.emit(coin)


func thing():
	if (tricksdone.size() >= 1):
		timing.emit(1 - timer)
	else:
		timing.emit(0)


func none():
	list.emit(tricksdone)


func stuff():
	if (tricksdone.size() == 0 or tricksdone[0] != trickdone[0] or trickdone[0] == "Show Off" or trickdone[0] == "Homing Chain" or trickdone[0] == "Groundpound" or trickdone[0] == "Mad Bounce") and (trickdone[0] != ""):
		tricksdone.insert(0, trickdone[0])
		score += (trickdone[2] * clamp(tricksdone.count(trickdone[0]) / 10.0, 1.0, 10.0))
		adding_up += (trickdone[2] * clamp(tricksdone.count(trickdone[0]) / 10.0, 1.0, 10.0))
		timer -= trickdone[1]
		list.emit(tricksdone)


func get_surface_tangent() -> Vector3:
	var up = surface_normal
	var forward = -global_transform.basis.z
	return (forward - up * forward.dot(up)).normalized()


func align_with_y(xform: Transform3D, new_y: Vector3) -> Transform3D:
	new_y = new_y.normalized()
	# choose a forward vector that's not parallel to new_y
	var forward = -xform.basis.z
	if abs(forward.dot(new_y)) > 0.999: # almost parallel -> pick another axis
		forward = xform.basis.x
	forward = (forward - new_y * forward.dot(new_y)).normalized() # project onto plane orthogonal to new_y
	var right = forward.cross(new_y).normalized()
	# set orthonormal basis: x = right, y = new_y, z = -forward (convention: z points forward)
	var b = Basis()
	b.x = right
	b.y = new_y
	b.z = -forward
	xform.basis = b.orthonormalized()
	return xform


func _ready() -> void:
	land_type = base_land
	resetposs = global_position
	if (land_type == "Dirt"):
		$AudioStreamPlayer5.volume_db = 24.0
		$AudioStreamPlayer5.stream = preload("res://dirt-footsteps-2-455146 (1).wav")
	if (land_type == "Metal"):
		$AudioStreamPlayer5.volume_db = 10
		$AudioStreamPlayer5.stream = preload("res://heavy-metal-footsteps-sound-effect-made-with-Voicemod.wav")


func _process(delta: float) -> void:
	if (state == states.Roll) || (state == states.Homing) || (state == states.Air):
		attacking = true
	else:
		attacking = false
	timer = clamp(timer, -1, 2)
	$CollisionShape3D.disabled = state == states.Roll
	$CollisionShape3D2.disabled = state != states.Roll
	if SaveManager.data.Scores[level] < score && saving:
		SaveManager.data.Scores[level] = score
	$Sprite3D.scale = lerp($Sprite3D.scale, Vector3(1.917, 1.917, 1.917), delta * 5)
	$Sprite3D.rotation.x = camera.rotation.x - global_rotation.x
	$Sprite3D.rotation.z = camera.rotation.z - global_rotation.z
	speed_timer -= delta
	if (timer > 0.1):
		trickdone = tricks[0]
	if (big_boost) && (timert < 0.1) && (taunt):
		timert += delta
	else:
		taunt = false
		trickdone = tricks[0]
	if (adding_up > 10000.0):
		speed_timer = 5
	if (speed_timer > 0):
		linuxmusic.pitch_scale = music.play_speed
		music.play_speed = lerp(float(music.play_speed), 3.0, delta * 5.0)
		SPEED = lerp(SPEED, big_speed, 5.0 * delta)
	else:
		linuxmusic.pitch_scale = music.play_speed
		music.play_speed = lerp(music.play_speed, 1.0, delta * 5.0)
		SPEED = lerp(SPEED, small_speed, 5.0 * delta)
	if (tricksdone.size() >= 1):
		timer += delta / 1.5
	else:
		adding_up = 0
	$Sprite3D.frame_coords.x = fmod(time, 40)
	$Sprite3D.frame_coords.y = slope + (direction * 1)
	slope = 0
	var p_fwd = -thinger.global_transform.basis.z
	var fwd = -$Node3D.transform.basis.z
	var left = -$Node3D.transform.basis.x
	var l_dot = left.dot(p_fwd)
	var f_dot = fwd.dot(p_fwd)
	if f_dot < -0.85:
		direction = 0
	elif f_dot > 0.85:
		direction = 4
	else:
		if (!taunted):
			$Sprite3D.flip_h = l_dot < 0
		else:
			$Sprite3D.flip_h = false
		if abs(f_dot) < 0.3:
			direction = 2
		elif f_dot < 0:
			direction = 1
		else:
			direction = 3


func homingchainer():
	trickdone = tricks[7]


func _physics_process(delta: float) -> void:
	resettime += delta
	if (health <= 0) && (state != states.Dead):
		state = states.Dead
	if (reset > global_position.y) && (state != states.Dead):
		global_position = resetpos
	if (resettime > 0.3) && ($RayCast3D.is_colliding()):
		resettime = 0
		resetpos = global_position
	if (homing == null):
		homing = Node3D
	if (timer > 0.1):
		trickdone = tricks[0]
	if ($RayCast3D.is_colliding()) and (state == states.Normal || state == states.Roll):
		homingchain = 0
	if (timer > 1) && (tricksdone.size() >= 1):
		trickdone = tricks[0]
		timer = 0
		if tricksdone.count("Show Off") > ((tricksdone.size()) - tricksdone.count("Show Off")):
			$AudioStreamPlayer.play()
			tricksdone.clear()
			stuff()
		else:
			tricksdone.clear()
			stuff()
		none()
	pass
	if (($Sprite3D2.position.y + 10) / 10) > 0:
		size = ($Sprite3D2.position.y + 10) / 10
	else:
		size = 0
	$Sprite3D2.scale = Vector3(size, size, size)
	$Sprite3D2.global_position = $RayCast3D2.get_collision_point() + (Vector3(0, 0.10, 0) * Basis(-basis.x, basis.y, -basis.z))
	match state:
		states.Normal:
			taunted = false
			spindash = 0
			$GPUParticles3D.emitting = ((abs(Vector3(vevo.x, 0, vevo.z).length()) > (SPEED / 2)))
			$Sprite3D.position.y = 0.728
			Idle(delta)
			if (land):
				if (time > 10):
					land = false
				time += delta * 30
				$Sprite3D.texture = landing
			else:
				if (abs(Vector3(vevo.x, 0, vevo.z).length()) > (SPEED / 1.1)):
					if ((round(fmod(time, 40)) == 3) || (round(fmod(time, 40)) == 7) || (round(fmod(time, 40)) == 11) || (round(fmod(time, 40)) == 15)) || (round(fmod(time, 40)) == 19) || (round(fmod(time, 40)) == 23) || (round(fmod(time, 40)) == 27) || (round(fmod(time, 40)) == 31) || (round(fmod(time, 40)) == 35) || (round(fmod(time, 40)) == 39):
						$AudioStreamPlayer5.play()
					time += delta * (30 * (abs(Vector3(vevo.x, 0, vevo.z).length()) / SPEED))
					$Sprite3D.texture = run
				elif (round(abs(Vector3(vevo.x, 0, vevo.z).length())) > 0):
					if ((round(fmod(time, 40)) == 5) || (round(fmod(time, 40)) == 15) || (round(fmod(time, 40)) == 25) || (round(fmod(time, 40)) == 35)):
						$AudioStreamPlayer5.play()
					time += delta * (30 * (abs(Vector3(vevo.x, 0, vevo.z).length()) / SPEED))
					$Sprite3D.texture = walk
				else:
					time += delta * 30
					$Sprite3D.texture = idle
		states.Air:
			$GPUParticles3D.emitting = false
			spindash = 0
			$Sprite3D.position.y = 0.728
			Jump(delta)
			if (taunted):
				$Sprite3D.texture = tauntsprite
			else:
				time += delta * (abs(vevo.y) * 5)
				$Sprite3D.texture = jump
		states.Roll:
			taunted = false
			$GPUParticles3D.emitting = true
			spindash = 0
			$Sprite3D.position.y = 0.288
			time += delta * (30 * (abs(Vector3(vevo.x, 0, vevo.z).length()) / SPEED))
			$Sprite3D.texture = jump
			Roll(delta)
		states.Spindash:
			taunted = false
			$GPUParticles3D.emitting = true
			spindash += delta * 10
			$Sprite3D.position.y = 0.288
			$Sprite3D.texture = jump
			time += spindash / SPEED
			spindash = clamp(spindash, 0, 60)
			if (spindash >= 59):
				trickdone = tricks[6]
			if (!Input.is_action_pressed("roll")):
				vevo = di * spindash
				state = states.Roll
		states.Dive:
			taunted = false
			$GPUParticles3D.emitting = false
			$Sprite3D.texture = diver
			if (time >= 39):
				time = 39
			else:
				time += delta * 30
			Dive(delta)
		states.Homing:
			taunted = false
			$Sprite3D.texture = jump
			$GPUParticles3D.emitting = false
			time += delta * 30
			Homing(delta)
		states.Hurt:
			taunted = false
			$Sprite3D.texture = hurt
			time += delta * 30
			$GPUParticles3D.emitting = false
			Hurt(delta)
		states.Dead:
			taunted = false
			$Sprite3D.texture = hurt
			$GPUParticles3D.emitting = false
			time += delta * 30
			if (reset > global_position.y):
				global_position = resetposs
				health = 8
				vevo.y = 0.0
				SaveManager.data.Lives -= 1
				state = states.Normal
			else:
				vevo.y -= gravity_scale * 9.8 * delta
				global_position.y += vevo.y * delta


func hurtvoice():
	$AudioStreamPlayer8.stream = hurt_sounds[randi_range(0, 1)]
	$AudioStreamPlayer8.play()


func voice():
	$AudioStreamPlayer8.stream = big_sounds[randi_range(0, 2)]
	$AudioStreamPlayer8.play()


func converting():
	velocity = global_transform.basis * vevo


func Jump(delta: float):
	if(is_on_floor()):
		state = states.Normal
	if vevo.y <= 0.0:
		apply_floor_snap()
	if (Input.is_action_just_pressed("ui_accept")) && water:
		if (vevo.y < (JUMP_VEVO / 2.0)):
			vevo.y = JUMP_VEVO / 2.0
		else:
			vevo.y += JUMP_VEVO / 2.0
	if (up_direction != Vector3.UP):
		state = states.Normal
	else:
		up_direction = lerp(up_direction, Vector3.UP, delta * 5)
	$Node3D/RayCast3D3.target_position.z = -0.35
	if (Input.is_action_just_pressed("roll")):
		groundpound = true

	if (Input.is_action_just_pressed("dive")) and !walljump:
		vevo.x += di.x * 5.0
		vevo.z += di.z * 5.0
		state = states.Dive
		divespeed = Vector3(vevo.x, 0, vevo.z).length()
		$AudioStreamPlayer8.stream = small_sounds[randi_range(0, 1)]
		$AudioStreamPlayer8.play()
		$AudioStreamPlayer7.play()
		time = 0
		vevo.y = JUMP_VEVO
	if ($Node3D/RayCast3D3.is_colliding()):
		vevo.x = 0
		vevo.z = 0
	if (abs(vevo.y) > 8):
		if (!$AudioStreamPlayer3.playing):
			$AudioStreamPlayer3.play()
			$AudioStreamPlayer3.pitch_scale = ((abs(vevo.y) / 32) + 0.75)
	else:
		$AudioStreamPlayer3.stop()
	if (big_boost && Input.is_action_just_pressed("taunt")) && timer != 0:
		taunt = true
		taunted = true
		time = randi_range(0, 19)
		$Sprite3D.scale = Vector3((1.917 * 0.9), (1.917 * 1.1), (1.917 * 0.9))
		trickdone = tricks[3]
		$AudioStreamPlayer2.play()
		$AudioStreamPlayer2.pitch_scale = (tricksdone.count("Show Off") + 5.0) / 5.0
		timert = 0
	surface_normal = Vector3(0, 1, 0)
	if vevo.y < 20.5 && (!$RayCast3D.is_colliding()) && (!$Node3D/RayCast3D.is_colliding() && !$Node3D/RayCast3D2.is_colliding()):
		rotation.y = lerp(rotation.y, 0.0, delta * 5)
		global_transform = lerp(global_transform, align_with_y(global_transform, Vector3(0, 1, 0)), delta * 5)
	# Gravity (only when not on floor)
	if not $RayCast3D.is_colliding():
		if (round(global_basis.y) != Vector3(0, 1, 0)):
			vevo = savevevo
			global_transform = lerp(global_transform, align_with_y(global_transform, Vector3(0, 1, 0)), delta * 20)
			if (vevo.y > 10) && (!big_boost):
				big_boost = true
				taunt = false
				timert = 0.2
				trickdone = tricks[2]
				$AudioStreamPlayer8.stream = big_sounds[randi_range(0, 2)]
				$AudioStreamPlayer8.play()
			elif (!big_boost) && (!Input.is_action_pressed("ui_accept")):
				taunt = false
				timert = 0.2
				trickdone = tricks[4]
		if (groundpound):
			if (water):
				vevo += Vector3(0, -9.8 * gravity_scale * 2, 0) * delta
			else:
				vevo += Vector3(0, -9.8 * gravity_scale * 4, 0) * delta
		else:
			if (water):
				vevo += Vector3(0, -9.8 * gravity_scale, 0) * delta
			else:
				vevo += Vector3(0, -9.8 * gravity_scale * 2, 0) * delta
	elif (vevo.y < 0):
		big_boost = false
		groundpound = false
		walljump = false
		$AudioStreamPlayer5.play()
		$AudioStreamPlayer3.stop()
		if (abs(vevo.y) > 20):
			land = true
			time = 0
			trickdone = tricks[5]
		$Sprite3D.scale = Vector3((1.917 * 1.5), (1.917 * 0.5), (1.917 * 1.5))
		state = states.Normal

	horizontal(delta)
	converting()
	move_and_slide()


func angle():
	var angle_rad := acos(clamp(surface_normal.dot(Vector3.UP), -1.0, 1.0))
	return rad_to_deg(angle_rad)


func dire(delta: float):
	var input_dir := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	var direction_local = Vector3(input_dir.x, 0.0, input_dir.y)
	var dir = Vector3(input_dir.x, 0.0, input_dir.y) * camera.basis
	if direction_local.length() > 0.001 && !$Node3D/RayCast3D3.is_colliding():
		direction_local = direction_local.normalized() * camera.basis
		di = Vector3((direction_local.x), 0, (direction_local.z))
		in_dir = Vector2(dir.x, dir.z)
		$Node3D.rotation.y = (-in_dir.angle()) + -1.57079637050629


func horizontal(delta: float):
	var input_dir := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	var direction_local = Vector3(input_dir.x, 0.0, input_dir.y)
	var dir = Vector3(input_dir.x, 0.0, input_dir.y) * camera.basis
	if direction_local.length() > 0.001 && !$Node3D/RayCast3D3.is_colliding():
		if (boss):
			$Node3D.rotation.y = (-in_dir.angle()) + -1.57079637050629
			direction_local = direction_local.normalized()
			di = Vector3((direction_local.x * SPEED), 0, (direction_local.z * SPEED))
			v.x = move_toward(v.x, (direction_local.x * SPEED), SPEED * delta * 1.5)
			v.z = move_toward(v.z, (direction_local.z * SPEED), SPEED * delta * 1.5)
		else:
			$Node3D.rotation.y = (-in_dir.angle()) + -1.57079637050629
			direction_local = direction_local.normalized() * basis
			di = Vector3((direction_local.x), 0, (direction_local.z))
			in_dir = Vector2(dir.x, dir.z)
			vevo.x = move_toward(vevo.x, (direction_local.x * SPEED), SPEED * delta * 1.5)
			vevo.z = move_toward(vevo.z, (direction_local.z * SPEED), SPEED * delta * 1.5)
	else:
		# smoothly decelerate (tweak the third argument if you want faster/slower stop)
		if (boss):
			v.x = move_toward(v.x, 0.0, SPEED * delta * 1.0)
			v.z = move_toward(v.z, 0.0, SPEED * delta * 1.0)
		else:
			if (direction_local.length() > 0.001):
				in_dir = Vector2(dir.x, dir.z)
				$Node3D.rotation.y = (-in_dir.angle()) + -1.57079637050629
				di = Vector3((direction_local.x), 0, (direction_local.z))
			vevo.x = move_toward(vevo.x, 0.0, SPEED * delta * 1.0)
			vevo.z = move_toward(vevo.z, 0.0, SPEED * delta * 1.0)
	if (boss):
		vevo.x = (v * camera.basis).x
		vevo.z = (v * camera.basis).z


func Idle(delta: float):
	#Slope Collision'
	$Node3D/RayCast3D3.target_position.z = -0.35
	if (Input.is_action_pressed("roll")):
		if (vevo.x == 0) && (vevo.z == 0):
			state = states.Spindash
		else:
			state = states.Roll
	if ($Node3D/RayCast3D3.is_colliding()):
		vevo.x = 0
		vevo.z = 0
	if (basis.y == Vector3.UP) && (basis.x != Vector3.RIGHT):
		basis.x = Vector3.RIGHT
		basis.z = Vector3.FORWARD
	if (abs(angle()) > 45) && (Vector3(vevo.x, 0, vevo.z).length() < 2):
		vevo.y = 10
	vevo += Vector3((surface_normal.cross(Vector3.UP) * -0.70).z, 0, (surface_normal.cross(Vector3.UP) * -0.70).x)
	# Get valid collision normals from raycasts, only if they hit.
	var n_sum = Vector3.ZERO
	var count = 0
	if $Node3D/RayCast3D.is_colliding():
		n_sum += $Node3D/RayCast3D.get_collision_normal()
		count += 1
	if $Node3D/RayCast3D2.is_colliding():
		n_sum += $Node3D/RayCast3D2.get_collision_normal()
		count += 1

	#Ground Collision
	var n = Vector3.UP
	$RayCast3D.target_position = Vector3(0, -0.4, 0)

	if count > 0:
		n = (n_sum / float(count)).normalized()
	surface_normal = n
	# Align to slope when on floor
	if $RayCast3D.is_colliding() && !dive:
		vevo.y = 0
		up_direction = n
		global_transform = lerp(global_transform, align_with_y(global_transform, n), delta * 20)
	else:
		up_direction = Vector3.UP
		if (dive):
			dive = false
			time = 0
			state = states.Dive
			divespeed = Vector3(vevo.x, 0, vevo.z).length()
			$AudioStreamPlayer7.play()
		else:
			state = states.Air
	# Jump
	if Input.is_action_pressed("ui_accept") and $RayCast3D.is_colliding():
		$AudioStreamPlayer4.play()
		$AudioStreamPlayer8.stream = small_sounds[randi_range(0, 1)]
		$AudioStreamPlayer8.play()
		if (abs(angle()) >= 90) && (trickdone != tricks[1]):
			trickdone = tricks[1]
		$Sprite3D.scale = Vector3((1.917 * 0.5), (1.917 * 1.5), (1.917 * 0.5))
		vevo.y = JUMP_VEVO * 1.5
	if (Input.is_action_just_pressed("dive")) and $RayCast3D.is_colliding():
		vevo.x += di.x * 5.0
		vevo.z += di.z * 5.0
		dive = true
		$AudioStreamPlayer8.stream = small_sounds[randi_range(0, 1)]
		$AudioStreamPlayer8.play()
		vevo.y = JUMP_VEVO

	# Input-based movement in *local* X/Z (X = right, Z = forward)

	# If falling, snap to floor (optional)
	if vevo.y <= 0.0:
		apply_floor_snap()

	# **Important:** convert local `vevo` into global velocity correctly
	# Use basis.xform to transform a local vector into global space

	if (abs(angle()) > 90):
		savevevo = Vector3((global_transform.basis * vevo).x, (global_transform.basis * vevo).z, (global_transform.basis * vevo).y)
	else:
		savevevo = global_transform.basis * vevo
	horizontal(delta)
	converting()
	# Move; pass the slope normal as the up direction so CharacterBody3D handles slopes correctly
	move_and_slide()


func Homing(delta: float):
	if ($Node3D/RayCast3D3.is_colliding()):
		walljump = true
		$AudioStreamPlayer8.stream = big_sounds[randi_range(0, 2)]
		$AudioStreamPlayer8.play()
		$AudioStreamPlayer9.play()
		trickdone = tricks[1]
		$Node3D/RayCast3D3.target_position.z = 0
		vevo.y = 15.0
		vevo.x = -vevo.x / 2.5
		vevo.z = -vevo.z / 2.5
		state = states.Air
	if (time == 2.5):
		$AudioStreamPlayer6.play()
	if (time < 2.5):
		vevo = Vector3(0, 2, 0)
	else:
		if (!is_instance_valid(homing)) || (homing.position.distance_to(position) > 25):
			homing = Node3D
			state = states.Air
		else:
			vevo = (homing.position - position).normalized() * 50
	if (Input.is_action_just_pressed("roll")):
		groundpound = false
		state = states.Air
		$AudioStreamPlayer8.stream = big_sounds[randi_range(0, 2)]
		$AudioStreamPlayer8.play()
		trickdone = tricks[8]
		vevo = Vector3(0, -50, 0)
	converting()
	move_and_slide()


func Dive(delta: float):
	dire(delta)
	beforevel = vevo
	vevo.x = lerp(vevo.x, (di * divespeed).x, delta * 25)
	vevo.z = lerp(vevo.z, (di * divespeed).z, delta * 25)
	if (Input.is_action_just_pressed("roll")):
		groundpound = false
		state = states.Air
		$AudioStreamPlayer8.stream = big_sounds[randi_range(0, 2)]
		$AudioStreamPlayer8.play()
		trickdone = tricks[8]
		vevo = Vector3(0, -50, 0)
	if (alreadyfound != Node3D) && (homing != Node3D):
		homing = alreadyfound
		time = 0
		state = states.Homing
		if (timer > 0.75):
			trickdone = tricks[9]
	if ($Node3D/RayCast3D3.is_colliding()):
		walljump = true
		$AudioStreamPlayer8.stream = big_sounds[randi_range(0, 2)]
		$AudioStreamPlayer8.play()
		$AudioStreamPlayer9.play()
		trickdone = tricks[1]
		$Node3D/RayCast3D3.target_position.z = 0
		vevo.y = 15.0
		vevo.x = -vevo.x / 2.5
		vevo.z = -vevo.z / 2.5
		state = states.Air
	surface_normal = Vector3(0, 1, 0)
	if vevo.y < 90.5 && (!$RayCast3D.is_colliding()) && (!$Node3D/RayCast3D.is_colliding() && !$Node3D/RayCast3D2.is_colliding()):
		up_direction = lerp(up_direction, Vector3.UP, delta * 5)
		rotation.y = lerp(rotation.y, 0.0, delta * 5)
		global_transform = lerp(global_transform, align_with_y(global_transform, Vector3(0, 1, 0)), delta * 5)
	# Gravity (only when not on floor)
	if not $RayCast3D.is_colliding() or (vevo.y > 0.0):
		if (round(global_basis.y) != Vector3(0, 1, 0)):
			vevo = savevevo
			global_transform = lerp(global_transform, align_with_y(global_transform, Vector3(0, 1, 0)), delta * 20)
		vevo += Vector3(0, -9.8 * gravity_scale, 0) * delta
	elif (vevo.y < 0.0):
		$Sprite3D.scale = Vector3((1.917 * 1.5), (1.917 * 0.5), (1.917 * 1.5))
		state = states.Roll

	converting()
	move_and_slide()


func Hurt(delta: float):
	if ($Node3D/RayCast3D4.is_colliding()) && ($RayCast3D.is_colliding()):
		state = states.Normal
		vevo = Vector3.ZERO
	if ($Node3D/RayCast3D3.is_colliding()) && ($RayCast3D.is_colliding()):
		state = states.Normal
		vevo = Vector3.ZERO
	if ($Node3D/RayCast3D4.is_colliding()) && (!$RayCast3D.is_colliding()):
		state = states.Air
		vevo = Vector3.ZERO
	if ($Node3D/RayCast3D3.is_colliding()) && (!$RayCast3D.is_colliding()):
		state = states.Air
		vevo = Vector3.ZERO
	surface_normal = Vector3(0, 1, 0)
	if vevo.y < 90.5 && (!$RayCast3D.is_colliding()) && (!$Node3D/RayCast3D.is_colliding() && !$Node3D/RayCast3D2.is_colliding()):
		up_direction = lerp(up_direction, Vector3.UP, delta * 5)
		rotation.y = lerp(rotation.y, 0.0, delta * 5)
		global_transform = lerp(global_transform, align_with_y(global_transform, Vector3(0, 1, 0)), delta * 5)
	# Gravity (only when not on floor)
	if not $RayCast3D.is_colliding() or (vevo.y > 0.0):
		if (round(global_basis.y) != Vector3(0, 1, 0)):
			vevo = savevevo
			global_transform = lerp(global_transform, align_with_y(global_transform, Vector3(0, 1, 0)), delta * 20)
		vevo += Vector3(0, -9.8 * gravity_scale, 0) * delta
	elif (vevo.y < 0.0):
		$Sprite3D.scale = Vector3((1.917 * 1.5), (1.917 * 0.5), (1.917 * 1.5))
		state = states.Normal

	converting()
	move_and_slide()


func Roll(delta: float):
	#Slope Collision
	$Node3D/RayCast3D3.target_position.z = -0.35
	if (round(vevo.x) == 0) && (round(vevo.z) == 0):
		state = states.Normal

	if ($Node3D/RayCast3D3.is_colliding()):
		vevo.x = 0
		vevo.z = 0
	if (basis.y == Vector3.UP) && (basis.x != Vector3.RIGHT):
		basis.x = Vector3.RIGHT
		basis.z = Vector3.FORWARD
	if (abs(angle()) > 45) && (Vector3(vevo.x, 0, vevo.z).length() < 2):
		vevo.y = 10
	vevo += Vector3((surface_normal.cross(Vector3.UP) * -0.70).z, 0, (surface_normal.cross(Vector3.UP) * -0.70).x)
	# Get valid collision normals from raycasts, only if they hit.
	var n_sum = Vector3.ZERO
	var count = 0
	if $Node3D/RayCast3D.is_colliding():
		n_sum += $Node3D/RayCast3D.get_collision_normal()
		count += 1
	if $Node3D/RayCast3D2.is_colliding():
		n_sum += $Node3D/RayCast3D2.get_collision_normal()
		count += 1

	#Ground Collision
	var n = Vector3.UP
	$RayCast3D.target_position = Vector3(0, -0.4, 0)

	if count > 0:
		n = (n_sum / float(count)).normalized()
	surface_normal = n
	# Align to slope when on floor
	if $RayCast3D.is_colliding():
		vevo.y = 0
		up_direction = n
		global_transform = lerp(global_transform, align_with_y(global_transform, n), delta * 20)
	else:
		up_direction = Vector3.UP
		state = states.Air
	# Jump
	if Input.is_action_pressed("ui_accept") and $RayCast3D.is_colliding():
		$AudioStreamPlayer4.play()
		$AudioStreamPlayer8.stream = small_sounds[randi_range(0, 1)]
		$AudioStreamPlayer8.play()
		if (abs(angle()) >= 90) && (trickdone != tricks[1]):
			trickdone = tricks[1]
		$Sprite3D.scale = Vector3((1.917 * 0.5), (1.917 * 1.5), (1.917 * 0.5))
		vevo.y = JUMP_VEVO

	# Input-based movement in *local* X/Z (X = right, Z = forward)

	# If falling, snap to floor (optional)
	if vevo.y <= 0.0:
		apply_floor_snap()

	# **Important:** convert local `vevo` into global velocity correctly
	# Use basis.xform to transform a local vector into global space

	if (abs(angle()) > 90):
		savevevo = Vector3((global_transform.basis * vevo).x, (global_transform.basis * vevo).z, (global_transform.basis * vevo).y)
	else:
		savevevo = global_transform.basis * vevo

	converting()
	vevo.x = move_toward(vevo.x, 0.0, SPEED * delta * 1.0)
	vevo.z = move_toward(vevo.z, 0.0, SPEED * delta * 1.0)
	# Move; pass the slope normal as the up direction so CharacterBody3D handles slopes correctly
	move_and_slide()


func _on_area_3d_body_entered(body: Enemy) -> void:
	if (body.visible):
		body.thing()
		if (state == states.Dive):
			if (homing != body) && (homing != Node3D):
				homing.thineg()
			homing = body
			if (timer > 0.75):
				trickdone = tricks[9]
			state = states.Homing
			time = 0
		else:
			alreadyfound = body


func _on_area_3d_2_body_entered(body: Enemy) -> void:
	if (body.visible):
		body.thing()
		if (state == states.Dive):
			if (homing != body) && (homing != Node3D):
				homing.thineg()
			homing = body
			if (timer > 0.75):
				trickdone = tricks[9]
			state = states.Homing
			time = 0
		else:
			alreadyfound = body


func _on_area_3d_3_body_entered(body: Enemy) -> void:
	if (body.visible):
		body.thing()
		if (state == states.Dive):
			if (homing != body) && (homing != Node3D):
				homing.thineg()
			homing = body
			if (timer > 0.75):
				trickdone = tricks[9]
			state = states.Homing
			time = 0
		else:
			alreadyfound = body


func _on_area_3d_body_exited(body: Enemy) -> void:
	body.thineg()


func _on_area_3d_4_body_entered(body: Enemy) -> void:
	if (body.visible):
		body.thing()
		if (state == states.Dive):
			if (homing != body) && (homing != Node3D):
				homing.thineg()
			homing = body
			if (timer > 0.75):
				trickdone = tricks[9]
			state = states.Homing
			time = 0
		else:
			alreadyfound = body


func _on_area_3d_5_body_entered(body: Enemy) -> void:
	if (body.visible):
		body.thing()
		if (state == states.Dive):
			if (homing != body) && (homing != Node3D):
				homing.thineg()
			homing = body
			if (timer > 0.75):
				trickdone = tricks[9]
			state = states.Homing
			time = 0
		else:
			alreadyfound = body


func _on_area_3d_6_body_entered(body: Enemy) -> void:
	if (body.visible):
		body.thing()
		if (state == states.Dive):
			if (homing != body) && (homing != Node3D):
				homing.thineg()
			homing = body
			if (timer > 0.75):
				trickdone = tricks[9]
			state = states.Homing
			time = 0
		else:
			alreadyfound = body


func _on_area_3d_7_body_entered(body: Enemy) -> void:
	if (body.visible):
		body.thing()
		if (state == states.Dive):
			if (homing != body) && (homing != Node3D):
				homing.thineg()
			homing = body
			if (timer > 0.75):
				trickdone = tricks[9]
			state = states.Homing
			time = 0
		else:
			alreadyfound = body


func _on_hurt_box_body_entered(body: Enemy) -> void:
	if (state != states.Hurt) && (!attacking) && (body.visible) && (state != states.Dead):
		health -= 1
		hurtvoice()
		state = states.Hurt
		vevo = Vector3(di.x * -10.0, 5.0, di.z * -10.0)


func _on_area_3d_8_body_entered(body: Metal) -> void:
	if ($AudioStreamPlayer5.stream != load("res://heavy-metal-footsteps-sound-effect-made-with-Voicemod.wav")):
		$AudioStreamPlayer5.volume_db = 10
		$AudioStreamPlayer5.stream = load("res://heavy-metal-footsteps-sound-effect-made-with-Voicemod.wav")


func _on_area_3d_8_body_exited(body: Metal) -> void:
	if (land_type == "Dirt") && ($AudioStreamPlayer5.stream != load("res://dirt-footsteps-2-455146 (1).wav")):
		$AudioStreamPlayer5.volume_db = 24.0
		$AudioStreamPlayer5.stream = load("res://dirt-footsteps-2-455146 (1).wav")
	if (land_type == "Metal") && ($AudioStreamPlayer5.stream != load("res://heavy-metal-footsteps-sound-effect-made-with-Voicemod.wav")):
		$AudioStreamPlayer5.volume_db = 10
		$AudioStreamPlayer5.stream = load("res://heavy-metal-footsteps-sound-effect-made-with-Voicemod.wav")


func _on_sprinh_area_entered(body: Spring) -> void:
	if (body.visible):
		if (state == states.Dive):
			if (homing != body) && (homing != Node3D):
				homing.thineg()
			homing = body
			if (timer > 0.75):
				trickdone = tricks[9]
			state = states.Homing
			time = 0
		else:
			alreadyfound = body

This is a very long script. Could you explain what you expect to happen versus what really happens? Do you have multiple issues? Do you have any error messages? Where do you think the error(s) occur?

2 Likes

A few questions:

  1. What’s the purpose of the vevo variable? What does the name mean?
  2. What does the variable thinger represent?
  3. What’s up with all the dot product math in _process()? And why did you choose to put it in _process() instead of _physics_process()?
  4. Is this a 2.5D game? It appears that your character is represented by a Sprite.
  5. Since you chose not to use @onready variables for some reason, can you show us a screenshot of the Scene Node tree?
3 Likes

the vevo is for slope rotation so they rotate when running up a wall and dont get stuck and run up the wall, no its not 2.5D but I do use a sprite3D for a Sega Saturn look and I dont know why I did mixed up the physics process and the procces I think some of it was for the hud and none movement stuff, I need to look through my code to tell you what thinger, i think it is for the trick system and here is a screenshot of the screen structure

Sadly, that was not as helpful as I was hoping. How do you keep track of what each node is for if you do not rename them?

I remeber, I can just read my code, I am mostly a solo dev

Great! So, back to what @gertkeno said, it would be helpful if you explained what part of that giant codeblock isn’t working. Then what it’s doing in-game and what you expect it to do in-game. Then maybe we can help you pin it down.

It’s fine if you’re a solo dev and you can look at the code and figure it out. But compare that to my last game and the node tree for my player scene:

I do not have to look at my code to know what each one does. Additionally, I use @onready variables instead of node references. That means that if I move something in the tree, I only have one line of code to update. It also makes my code much clearer.

# HUD
@onready var missile_hud: PanelContainer = %"Missile HUD"
@onready var shield_hud: ShieldHUD = %"Shield HUD"
@onready var respawn_hud: PanelContainer = $"HUD/MarginContainer/Respawn HUD"
@onready var respawn_button: Button = %"Respawn Button"
# Comms HUD
@onready var monitor_2: PanelContainer = %Monitor2
# Death
@onready var explosion_sound: AudioStreamPlayer2D = $"Explosion Sound"
@onready var explosion: GPUParticles2D = $Explosion
#Shields
@onready var shield_visual_effect: Sprite2D = $"Shield Visual Effect"
@onready var shield_hit_sound: AudioStreamPlayer2D = $"Shield Hit Sound"
@onready var shield_destroyed_sound: AudioStreamPlayer2D = $"Shield Destroyed Sound"
#Trash
@onready var trash_collector: Node2D = %"Trash Collector"

You can do the same by renaming your nodes. Then click and drag the node into the top of your code and press Ctrl before releasing it. You’ll get variables created just like mine.

It will also help you in situations like this, where you want help with your code. Because you will have to do a lot less explaining.

I think its its mix of the horizontal and n_sum surface normal stuff

Ok, so n_sum is a Vector3.

  1. What does that variable name mean?
  2. What is RayCast3D colliding with? What masks and layers are set on it? What direction is pointing?
  3. Same questions for RayCast3D2.
  4. Why are you adding them together?
  5. You’re sticking that in n, also a Vector3. What does that variable name mean? What’s the value represent?
  6. You immediately assign n to surface_normal. So why create n at all?
  7. What does surface_normal, another Vector3 do?

First, why not call it slope_rotation or slope_vector? What does vevo mean?

Second, you could do all of that by using the gravity settings in Area3D nodes and all that math you are doing and raycasting would go away.

vevo is a version of velocity that I changes because there is already another var, Raycast3D collides with everything and I forgot what the variables mean, I need to clean up my code

and the reason for n_sum is a kids can code tutorial

CharacterBody3D: Align with Surface :: Godot 4 Recipes

Time to delete all of this and start over from scratch, using the newly acquired wisdom.

2 Likes

Aww man this always happens I don’t want to restart again, but if I have too