Child gets off centered when the parent is rotated

Godot Version

4.2

Question

I’m trying to create a LOS (Line of sight) system for my game. In the code it returns if the target is within the users LOS, and if the target is than the user gets rotated to look at the target, by the look_at() function. But once the user looks at the target the RayCast3D that detects if the target is within the LOS gets off centered. I’m unsure of how to make it stay centered.

extends Node
class_name LOS

var los: bool

var view_cast: RayCast3D
var ray_created: bool = false

func get_LOS(user: CharacterBody3D, target: CharacterBody3D)-> bool:
	# Create the RayCast3D once
	if !ray_created:
		create_view_raycast(user)
	# Target view_cast at the target
	view_cast.target_position = target.global_position - user.global_position
	# Get collider
	var collider = view_cast.get_collider()

	# User FOV
	var FOV: float = 0.6
	# Calculate the FOV
	var FA = -user.global_transform.basis.z.normalized()
	var to_target = (target.global_position - user.global_position).normalized()
	var dot_product: float = to_target.dot(FA)

	if collider == target and dot_product > FOV:
		los = true
	else:
		los = false

	return los

func create_view_raycast(user: CharacterBody3D):
	view_cast = RayCast3D.new()
	# Add view_cast to scene
	get_parent().add_child(view_cast)
	view_cast.global_position = user.global_position

	ray_created = true

I’m not sure if that’s the problem but is there a reason you’re not adding view_cast as a child to user?
Generally if you want view_cast to move and rotate together with user then adding it as a child should do it.

I’m trying to make most things in my game modular, and I found that me adding the child by code is easier than by hand. By the way the script gets added as a child of the user node, I probably should have mentioned it above.

This is how the scene tree is layed out:
image_2024-04-18_074456044

So turns out that having the raycast be parented to the LOS node fixes the issue. Such as just doing this instead of getting the users node and adding it as a child to that.

# Add view_cast to scene
add_child(view_cast)
view_cast.global_position = user.global_position

I realize this now, but it only works because the LOS node doesn’t have a position, meaning that the origin for the view_cast will be at the origin of the user. But if the user gets moved then the view_cast doesn’t follow.

I fixed it, although I find the way I did it boring, oh well it works. I just defined the length of the view_cast during the creation of it, and used the look_at() function to make it face the target.

var view_cast_length = Vector3(0, 0, -20)

func create_view_raycast(user: CharacterBody3D):
	Set view_cast length
	view_cast.target_position = view_cast_length

func get_LOS(user: CharacterBody3D, target: CharacterBody3D)-> bool:
	# Target view_cast at the target
	view_cast.look_at(Vector3(target.global_position.x, user.global_position.y, target.global_position.z))