Godot Version
4.4
Question
I have created a test game map in blender for the purpose of learning the engine. It is imported and my character interacts with it fairly decently.
I am using Raycast3d objects to try and detect the StaticBody3d (and CollisionShape3d) that makes up the entirety of the map. The problem I’ve run into is the fact that the Raycast3d will only detect parts of the shape while ignoring others.
How would I be able to fix that?
Shouldn’t the Raycast3d be hitting the first face it sees then outputting true?
Extra notes:
- The parts the Raycast are excluding are thin pillars, ramps and a raised winding pathway
- My player character collides fine with everything the Raycast is ommiting.
- I’ve fiddled with the Raycast settings under, “Collide With,” as well as the, “Hit From Inside,” and, “Hit Back Faces,” settings and none remedy this problem
- The entire map is the same CollisionShape3d
- Currently there is no code attached to the Raycast or any of the test map
How did you determine that?
I see the ray change color in the debug mode while playing. I also had some code that would shoot the player up when the ray was detecting and that confirmed the issue further.
Can you make a minimal reproduction example?
Make a fresh project that does nothing else but a reproduction of the problem.
I’ve created it and still run into the same problems. Ive included my code but I’m quite confident this is a problem with the Raycast3d object itself.
extends CharacterBody3D
var speed
const WALK_SPEED = 5.0
const SPRINT = 10.0
const JUMP_VELOCITY = 5.5
const SENSITIVITY = 0.003
const GRAVITY = Vector3(0,-10,0)
#Bobbing Variables
const BOB_FREQ = 2.0
const BOB_AMP = 0.08
var t_bob = 0.0
#fov const
const BASE_FOV = 90
const FOV_CHANGE = 1.5
@onready var head := $PlayerMesh
@onready var playercam := $PlayerMesh/Node3D/PlayerCamera
func _ready():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
func _unhandled_input(event):
if event is InputEventMouseMotion:
head.rotate_y(-event.relative.x * SENSITIVITY)
playercam.rotate_x(-event.relative.y * SENSITIVITY)
playercam.rotation.x = clamp(playercam.rotation.x, deg_to_rad(-80), deg_to_rad(80))
## DEAFAULT PLAYER INSTRUCTIONS
func _physics_process(delta: float) -> void:
# Add the gravity.
if not is_on_floor():
velocity += GRAVITY * delta
# Handle jump.
if Input.is_action_just_pressed("Space") and is_on_floor():
velocity.y = JUMP_VELOCITY
# Handle Sprint
if Input.is_action_pressed("Shift_sprint"):
speed = SPRINT
else:
speed = WALK_SPEED
# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
var input_dir := Input.get_vector("A_left", "D_right", "W_forward", "S_back")
var direction = (head.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if is_on_floor():
if direction:
velocity.x = direction.x * speed
velocity.z = direction.z * speed
else:
velocity.x = 0.0
velocity.z = 0.0
else:
velocity.x = lerp(velocity.x, direction.x * speed, delta * 3.0)
velocity.z = lerp(velocity.z, direction.z * speed, delta * 3.0)
if Input.is_action_just_pressed("Esc_menu"):
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
#get_tree().quit()
#Head-BOBBING
t_bob += delta * velocity.length() * float(is_on_floor())
playercam.transform.origin = _headbob(t_bob)
# FOV
var velocity_clamped = clamp(velocity.length(), 1, SPRINT * 2)
var target_fov = BASE_FOV + FOV_CHANGE * velocity_clamped
if is_on_floor():
playercam.fov = lerp(playercam.fov, target_fov, delta * 10.0)
else:
playercam.fov = lerp(playercam.fov, target_fov * 1.2, delta * 2.0)
move_and_slide()
func _headbob(time) -> Vector3:
var pos = Vector3.ZERO
pos.y = sin(time * BOB_FREQ) * BOB_AMP
pos.x = cos(time * BOB_FREQ / 2) * BOB_AMP
return pos
A thing I’ve noticed with further testing is that only the meshes I create in blender do this. Other meshes I create static body children for work fine under similar conditions as my own mesh.
Can you post a problematic mesh?
I tried using the upload button but it doesn’t accept FBX files so I’ve put them in a google drive here.
RoundWe Go is the one I first noticed the problem on and RayTestMap is what I made to see if I could figure out the problem further.
I believe I have found a method that works. Instead of using FBX file format I used GLB. Using the same method to create collision as I did with FBX none of the problems with the Raycast3d arise.