Raycast3D not detecting collision with CSGBoxes

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

Make sure use_collision flag is enabled in csg nodes.

I suspected that, yes, it’s enabled

Well then check that collision layers/masks are set up properly. Also enable debug drawing of colliders to check if the raycast is pointing in the expected direction.

Suspected that too, they’re the same