use godot::{ classes::{PhysicsRayQueryParameters3D, World3D}, prelude::*, }; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct NetVector3 { pub x: f32, pub y: f32, pub z: f32, } impl From for NetVector3 { fn from(value: Vector3) -> Self { NetVector3 { x: value.x, y: value.y, z: value.z, } } } impl From for Vector3 { fn from(value: NetVector3) -> Self { Vector3::new(value.x, value.y, value.z) } } pub fn cast_ray( from: Vector3, to: Vector3, world: Option>, exclude: Array, ) -> Option { let ray = PhysicsRayQueryParameters3D::create(from, to); if let Some(mut ray) = ray { ray.set_collision_mask(0b111); ray.set_hit_back_faces(false); ray.set_hit_from_inside(false); ray.set_collide_with_bodies(true); ray.set_exclude(&exclude); if let Some(world) = world && let Some(mut space) = world.get_direct_space_state() { let results = space.intersect_ray(&ray); if let (Some(position), Some(collider)) = (results.get("position"), results.get("collider")) { Some(RaycastResult { position: Vector3::from_variant(&position), collider: Gd::from_variant(&collider), }) } else { None } } else { None } } else { None } } pub struct RaycastResult { pub position: Vector3, pub collider: Gd, }