How can I fix my raycast screen center

Godot Version

4.4.1

Question

I recently put my project into a 320 x 240 resolution to get a pixelated look. I also moved my raycast code into a Global script to call the functions anywhere I want. My problem is my raycast is detecting completely 90 degrees to the right instead of the center of the screen.

Raycast code in Global script

extends Node

var debug # Reference to DebugPanel for debug property assignment
var player
var ui_context
var interact_distance : float = 2
var interact_cast_result

func interact_cast() -> void:
	var camera = Global.player.CAMERA_CONTROLLER
	var space_state = camera.get_world_3d().direct_space_state
	var screen_center = get_viewport().size / 2
	var origin = camera.project_ray_origin(screen_center)
	var end = origin + camera.project_ray_normal(screen_center) * interact_distance
	var query = PhysicsRayQueryParameters3D.create(origin, end)
	query.collide_with_bodies = true
	var result = space_state.intersect_ray(query)
	var current_cast_result = result.get("collider")
	if current_cast_result != interact_cast_result:
		if interact_cast_result and interact_cast_result.has_user_signal("unfocused"):
			interact_cast_result.emit_signal("unfocused")
		interact_cast_result = current_cast_result
		if interact_cast_result and interact_cast_result.has_user_signal("focused"):
			interact_cast_result.emit_signal("focused")

func interact() -> void:
	if interact_cast_result and interact_cast_result.has_user_signal("interacted"):
		interact_cast_result.emit_signal("interacted")

Is there a better way to get the center of the screen without having to use the “get_viewport()” function. Or is there a way for me to connect the players viewport to the Global script.

When you only want the center-forward ray I believe you can get the Camera’s position and -basis.z instead of projecting from screen-space.

var camera: Camera3D = Global.player.CAMERA_CONTROLLER
var space_state := camera.get_world_3d().direct_space_state

var origin := camera.global_position
var end := origin + (-camera.basis.z * interact_distance)

var query := PhysicsRayQueryParameters3D.create(origin, end)

If this does help, then maybe your get_viewport() grabbed the window size instead of the rendering viewport of 320x240, you could print what screen_center gives you to confirm if it’s much higher than 320.

I wasn’t able to get this to work. But I found that if I change the project settings to full screen the screen_center prints back 960, 540. If I change the project settings to windowed then it returns the correct 160, 120. So the raycast works in windowed mode but I’m not sure how to have it work when the game is fullscreen.

Ah what went wrong with the sample?

How is your viewport set up? Is it all through the project settings? What do those settings look like?

The code did work partially. The problem with it was it would sometimes not work and other times would work but the raycast would be cast around the whole player. So you could interact with objects if you weren’t looking at them.


Here are my viewport settings and stretch settings.

I was able to get the raycast working by just simply dividing get_viewport.size by 4 instead of 2. It’s about as close to 320 x 240 as I can get. I figured the get_viewport.size gets your monitors resolution when fullscreened. So no matter what it would always divide 1920 x 1080 instead of any other resolution I tried putting in. So it was as simple as just dividing numbers for 1920 x 1080 until something got close enough. Probably a better way to do it but it works for now.

Sorry, I don’t know the answer to your question, but your solution sounds like it will break for anyone not using 1920 x 1080 resolution?

Seems like you might want to find a better solution if you plan on ever releasing your project for other people. You might want to do it sooner rather than later as well while the problem is fresh in your mind. I can foresee a situation where you forget about this, and then spend ages trying to debug why it isn’t working for someone else!

Feel free to ignore me, I’m possibly just projecting :sweat_smile:

1 Like

Definitely will be looking into it. I kind of figured it wasn’t the best way to go about doing it. I honestly hadn’t thought about people’s own monitor’s resolutions. Thanks for the advice I appreciate it and will be checking it out.

Better solution. I used get_viewport().get_visible_rect().size / 2 for my screen_center variable and it seems to be working better. Not only does it return the correct 320 x 240 when using 640 x 480 in my project settings, but it also will upscale and downscale with your monitor’s resolution.

1 Like