How can I cast a raycast from inside a spherical collision shape?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By tobo

I have a camera inside a sphere from which I cast a raycast to get the intersection point. I figured out that raycasting somehow only works if the origin point and the cast-to point are outside of the collision shape. Is there any way to cast it from inside a collision shape and still get the collision point?

Any help is appreciated!

:bust_in_silhouette: Reply From: miskotam

Try to set your CollisionObject’s (the one that you want to ignore) collision layer different from the RayCast’s collision masks.

Thanks for your answer! I just realized that my question is probably not so clear, as I don’t want to ignore the CollisionObject.

Here’s my setup:
I have a camera at the point 0,0,0 which is moveable by the mouse. It’s surrounded by a textured sphere (I am trying to copy the controls of games like Myst, where you have 360° pre rendered background and move through clicking “hotspots” on these backgrounds). I have one sphere where it’s really important to get the exact point on the sphere where it is clicked, so I need to cast a raycast from inside the sphere (where the camera is) and I want to get the point where it hits the shell of the sphere (which is a mesh with a static object as a child which has a spheric collision shape). This doesn’t work as the raycast from inside the sphere somehow ignores it. Sorry if it’s still a little confusing, English is not my first language.

tobo | 2020-10-05 20:00

I put together a quick example, which might could help you.
Here you can see my scene hierarchy:

enter image description here

And I have the following script on my Camera:

extends Camera

var ray = RayCast.new()
func _ready():
	add_child(ray)
	ray.enabled = true

func _input(event):
	var distance_from_camera = far 
	if event is InputEventMouseButton:
			var from = project_ray_origin(event.position);
			var to = from + project_ray_normal(event.position) * distance_from_camera;
			ray.cast_to = to-global_transform.origin
			if (event is InputEventMouseButton):
				if (event.pressed == false and event.button_index == 1):
					if ray.is_colliding():
						var raypoint = ray.get_collision_point()
						return print("raypoint:", raypoint)

Is this similar to your use case?

miskotam | 2020-10-05 22:28

Thanks again! It’s almost similar, but in my case the camera is not a child of the collision shape but is in another node that is higher on the hierarchy. I tried your code on my camera and again, got no results. Is it crucial that the camera is a child of the collision shape?

tobo | 2020-10-06 08:36

Ah and is your camera also “placed” on the inside of the collision shape? In my case, the camera has to be surrounded by the collision sphere and I think that is the problem. If I have any collision shapes that are in distance to the camera, it works with no problems.

tobo | 2020-10-06 08:38

How do I do this in Godot4? I need the exact thing but this code does not work in Godot4 unfortunately.