Godot Version
Godot 4.5.1
Question
Here is my code:
extends CharacterBody3D
class_name mainChar
#Define Variables
@export_group(“Camera”)
var _camera_input_direction := Vector2.ZERO
var fall_speed = 1500
var coyote_timer = 0.0
var coyote_time = 0.1
var gravity = -800
var Speed = 0
var ground_Speed = Speed
var jump_time = 1.0
var jump_timer = 0.0
var jump_velocity = 500
var can_Jump = false
var momen = 1
var acc = 10
var dec = 10
var rot = 0.0
var slope_angle = 0.0
var direction = 0
var motion = Vector3(0,0,0)
var grounded = false
var fall_off_wall = false
var slope_factor = 0.0
var control_lock = false
var stuck = false
@onready var Player: MeshInstance3D = %Model
@onready var FloorCast: RayCast3D = %FloorCast
@onready var WallCast: RayCast3D = $WallCast
@onready var IdleCollisionShape: CollisionShape3D = %“Hitbox-Idle”
var angle = 0
var friction = gravity * $“.”.rotation.z
var last_movement_direction := Vector3.BACK
var Max_Speed = 200
var Left_Stick_Sensitivity := 0.1
var Right_Stick_Sensitivity := 0.1
var Jump_Velocity = 250
var count = 0
var rotationSpeed = 12.0
@onready var camera: Node3D = %CameraPivot
@onready var _camera: Camera3D = %Camera3D
var moving = 0
var mouse_sensitivity := 0.25
var rayRot = Vector3.ZERO
var x_input = 0
var y_input = 0
#func _slopeDetection():
#if %FloorCast.is_colliding() or not %SlopeCast.is_colliding():
#angle = 0
#elif %SlopeCast.is_colliding():
#angle = 1
#gravity
func _ready() → void:
Autoload.player = self
#print(FloorCast)
add_to_group(“Player”)
add_to_group(“Bad Guys”)
func _gravity(delta: float) → void:
if not is_on_floor() and rot == 0:
count == 1
velocity.y = move_toward(velocity.y, fall_speed, gravity * delta)
else:
if abs(slope_factor) == 1: #gets the slope factor to prepare for physics
velocity.y = 0
else:
velocity.y = 80
func _refresh():
grounded = false
func _input(event: InputEvent) → void:
if event.is_action_pressed(“left_click”): #K&M input
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
if event.is_action_pressed(“ui_cancel”):
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
func _physics_process(delta: float) → void:
_jump(1)
_refresh()
#print(FloorCast)
if FloorCast.is_colliding():
can_Jump = true#Jumping failsafe, bandaid if anything but as long as it works
if Input.is_action_just_pressed(“Jump”) and can_Jump:
velocity.y += jump_velocity
if not is_on_floor():
_gravity(delta)
camera.rotation.x += _camera_input_direction.y * delta #camera script
camera.rotation.x = clamp(camera.rotation.x, -PI / 6.0, PI / 3.0) #Restricts movement of the camera to help player maintain control
camera.rotation.y -= _camera_input_direction.x * delta #rotates the camera
_camera_input_direction = Vector2.ZERO #gets the camera input
#var camera_direction := Input.get_action_strength(“Look_Left”) - Input.get_action_strength(“Look_Right”);
#var character_direction := Input.get_action_strength(“Left”) - Input.get_action_strength(“Right”);
#camera.rotation.y += camera_direction * Right_Stick_Sensitivity;
#Player.rotation.y += character_direction * Right_Stick_Sensitivity;
#print(Speed)
if Input.is_action_pressed(“Up”) or Input.is_action_pressed(“Down”) or Input.is_action_pressed(“Left”) or Input.is_action_pressed(“Right”):
moving = true
if Speed != Max_Speed: #builds the momemtum for the player
Speed += momen
else:
moving = false
if Speed > 0:
Speed -= dec #decelerates the Speed so the player slows down
#var look_direction = Vector2(velocity.z, velocity.x)
#Player.rotation.y = lerp_angle(Player.rotation.y, look_direction.angle(), delta * 12)
var raw_input := Input.get_vector("Left", "Right", "Up", "Down") #gets the inputs
var forward := _camera.global_basis.z #gets the forwars inputs
var right := _camera.global_basis.x #gets the x inputs
var move_direction = forward * raw_input.y + right * raw_input.x #calculates the movement direction based on the input from they player
move_direction.y = 0.0 #Failsafe
move_direction = move_direction.normalized()
var target_velocity = move_direction * Speed #Sets the velocity the game hopes to acheive
var smoothing_factor = 0.1 #adds a bit of force so the speed can bee maintained
if angle == 0:
target_velocity = move_direction * Speed
velocity = velocity.lerp(target_velocity, smoothing_factor)
else:
target_velocity = move_direction * Speed * friction #Alternate movement for when on slopes
#var move_acc = acc * 0.9
#if moving:
#velocity = velocity.move_toward(move_direction * Speed, move_acc * delta)
move_and_slide()
if is_on_floor():
if count == 0:
print("On floor")
count = 1
can_Jump = true
slope_angle = get_floor_angle() + (PI / 2) #gets the slope of the ground
slope_factor = get_floor_normal().z
else:
slope_angle = 0.0 #sets angle mode back to default when in the air
#Player.rotation.y = rot
rayRot = rot
Player.rotation.x = rot
Player.rotation.z = rot
#WallCast.look_at(WallCast.global_position + Player.rotation)
if %FloorCast.is_colliding():
if not grounded:
if abs(slope_angle) >= abs(velocity.y) and abs(velocity.y) > abs(velocity.z):
print("On Slope")
velocity.z = (velocity * slope_factor) #Changes the movement according to the slope
grounded = true
up_direction.normalized() #Normalises the direction
rot = slope_angle
else:
if not FloorCast.is_colliding() and grounded: #gets the velocity for when not on ground
velocity = get_real_velocity()
rot = 0
up_direction = Vector3(0, -1, 0)
if FloorCast.is_colliding(): #Self explanatory
can_Jump = true
if move_direction.length() > 0.2:
last_movement_direction = move_direction #gets the last direction the player moved in
var targetAngle := Vector3.BACK.signed_angle_to(last_movement_direction, Vector3.UP) #sets a tarhet for the angle
Player.global_rotation.y = lerp(Player.rotation.y, targetAngle, rotationSpeed * delta) #rotates the player accordinlgy
if $WallCast.is_colliding():
print("Collision Detected")
func _unhandled_input(event: InputEvent) → void: #mouse controls
var is_camera_motion := (
event is InputEventMouseMotion and
Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED
)
if is_camera_motion:
_camera_input_direction = event.screen_relative * mouse_sensitivity
func _coyote_time(delta):#coyote timer for jumping
if coyote_time > 0:
coyote_time -= delta
else:
coyote_time = coyote_timer
if coyote_timer > 0:
can_Jump = true
else:
if not is_on_floor():
can_Jump = false
func _slopeDetection():
var slopeMode = 0
if $WallCast.is_colliding():
if not %SlopeCast.is_colliding() and %FloorCast.is_colliding():
slopeMode = 1
if slopeMode == 1:
print(slopeMode)
func _jump(delta: float) → void: #on floor detector really. Misleading name on my part but long story there
if is_on_floor():
can_Jump = true
else:
can_Jump = false
if Input.is_action_just_pressed(“check”): #tester for key variables
print(“Speed:”, Speed)
print(“can_Jump:”, can_Jump)
print(“coyote_time:”, coyote_time)
print(“is_on_floor():”, is_on_floor())
print(“jump_timer:”, jump_timer, “/”, jump_time)
print(“Friction:”, friction)
print(“Angle:”, angle)
print(“is_on_wall:”, is_on_wall())
print(“Slope_Angle:”, slope_angle)
print(“Rotation:”, rotation.z)
func _on_area_3d_body_shape_entered(body_rid: RID, body: Node3D, body_shape_index: int, local_shape_index: int) → void:
if body in get_tree().get_nodes_in_group(“Speed Boost”):
Speed = 300
For some very odd reason WallCast doesn’t detect collision with CSGBodies. This is a CSGBody specific thing as the raycast can detect anything else which is exactly what’s confusing me.
Just wondering if anyone else has any idea why this is happening.
Thanks