Currently, I am making a FPS system where when the player shoots a ray will go through the Ray.new(player.Character:FindFirstChild("Head").Position, mouse.UnitRay.Direction.Unit * 300) And now I am trying to find characters near the ray I casted
Let’s say the ray goes like this:
It is not going to be detected because it did not hit the character BUT what I would like to do is to make the character DETECTED by the ray.
Are their any ideas I can use?
This is my current code:
for _, charactersaffected:Model in pairs(workspace:GetChildren()) do
if charactersaffected:IsA("Model") and charactersaffected:FindFirstChild("Torso") then
local newray = Ray.new(player.Character:FindFirstChild("Head").Position, realhit.Direction.Unit * 300)
local distance_character = newray:Distance(charactersaffected.PrimaryPart.Position)
end
end
The easiest way would be to get the ray to hit the thing. Try using shapecasts for a wider ray, or weld an invisible hitbox part to each character and detect hits on that instead.
You need to calculate the distance between each player and the ray. If the player is below a certain distance then you should count that as being “detected”. Here is some code that will allow you to do that
local DETECTION_DISTANCE = 20 -- Under this distance a player will be detected by a ray
local function getClosestPointOnRay(ray: Ray, point: Vector3): Vector3
local toPoint = point - ray.Origin
local alpha = toPoint:Dot(ray.Direction.Unit)
local pointOnRay = ray.Origin + ray.Direction.Unit * alpha
local direction = (pointOnRay - ray.Origin).Unit
local length = (pointOnRay - ray.Origin).Magnitude
--Rays mathematically have infinite length so we need to limit this to our preferred length
if direction:Dot(ray.Direction.Unit) < 0 then --Dont allow going behind the ray
return ray.Origin
elseif length > ray.Direction.Magnitude then --Dont allow going beyond max length of ray
return ray.Origin + ray.Direction
else
return pointOnRay
end
end
local function isDetectedByRay(ray: Ray, point: Vector3): boolean
local closestPoint = getClosestPointOnRay(ray, point)
local dist = (point - closestPoint).Magnitude
if dist <= DETECTION_DISTANCE then
return true
else
return false
end
end
To implement this, iterate over every player and call isDetectedByRay. Provide it the ray and the position of the player