How to make RayCast3D rotate towards player?

Godot Version

4.3

Question

I wanted to make sound physics script (for every sound node) which rotates RayCast3D Node towards the player and checks if it collides him, but idk how to do it. (ik how to check what ray collides i just want how to make RayCast3D rotate towards player)

Here is a picture for you to understand what I mean:
image

1 Like

Could you use Node3D’s look_at() function? If not, would an Area3D work to change audio properties?

3 Likes

Well, I tried to do it, but the ray doesn’t look exactly at me, when I stepped under the ray creating a perpendicular axis the ray gone crazy

look_at takes an up Vector. In the documentation that @Opalion linked to it says:

"The local up axis (+Y) points as close to the up vector as possible while staying perpendicular to the local forward axis. The resulting transform is orthogonal, and the scale is preserved. Non-uniform scaling may not work correctly.

The target position cannot be the same as the node’s position, the up vector cannot be zero, and the direction from the node’s position to the target vector cannot be parallel to the up vector."

If it does a little dance or just starts acting oddly it’s probably because of that last part. Before calling the function you could (possibly using the dot product Vector math — Godot Engine (stable) documentation in English) check if the vector to the player and your chosen up vector are parallel, and if they are use a different up vector instead.

Which alternate up vector you use is up to you. It’s used to determine the roll, so if it’s just being used on a RayCast3D (which is invisible and doesn’t care about roll) then it doesn’t really matter, so long as you don’t use your original up vector or its opposite.

3 Likes

ye I even found an error


it will be fun to fix it

2 Likes

Ok, I found the solution (We don’t need any RayCast3D node we can just create a ray in the script that works properly):

extends AudioStreamPlayer3D

@onready var sound = self
@onready var target = self.get_tree().get_root().get_node("Node3D/CharacterBody3D")

func _physics_process(delta):
	var space = get_world_3d().direct_space_state
	var params = PhysicsRayQueryParameters3D.new()
	params.from = self.global_transform.origin
	params.to = target.global_transform.origin
	params.exclude = [self]
	params.collision_mask = 1
	var result = space.intersect_ray(params)
	if result.collider == target:
		sound.volume_db = 0
	else:
		sound.volume_db = -40
1 Like