Rangefinder distance reading?

I have a rangefinder in my game but all it does is rotate and zoom in. People have asked me to make it actually work like a rangefinder and tell the distance of enemy ships when the crosshair is pointed at them.

How can I achieve a distance reading? I would think I would need to use extremely long raycasts, but is there a maximum raycast distance? My maps are 20480x20480 studs.

I’d like the rangefinder to aim at something in the distance, click a button, then present the distance from the rangefinder to the part hit by the raycast.

Hello ClassicMasterNoob.

I don’t think your range finder would need to use rays! Luckily for you mouse.Hit can give you a CFrame of whatever your mouse is hovering over. So if you want to find the distance from whatever your mouse is pointing at and your current player you can just do:

print("Distance from mouse Hit:", player:DistanceFromCharacter(mouse.Hit.Position))

If you want it to update from a button just have it use this to update the distance when the button is pressed. Good luck, and let me know if you need more help.

Thanks for responding, I didn’t think anyone would help with this.

As of right now, I can only get distance readings less than or equal to 5000 studs, but I want it to go further.

How it works is by using a rangefinder “turret” and placing a crosshair on the target. Then you press F to retrieve the distance (using raycast) as shown below.

What I do with this is put the information inside a calculation that results in the required barrel angle and use it to fire.



I don’t use the mouse to get a distance, and I’m pretty sure the mouse even has a limit to how far you can click on something (probably 2048 studs or something).

How can I extend my distance readings above 5000?

Ah I see, well the only way to do that is to stack your ray casts, lots of games do this for massive maps. This basically just means that if your ray doesn’t hit anything with the first ray cast you start another one from the end of the previous. You should really have a limit on this though or else your ray may go off into the void forever causing a memory leak.

Something like this probably:

local playerPos = plr.Character.PrimaryPart.CFrame.Position
local rayStart = playerPos
local rayDirection = (rayStart.Position - mouse.Hit.Position).Unit 

local maxDist = 20480

local function createRay(start, direction, char)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.FilterDescendantsInstances = plr.Character
	raycastParams.IgnoreWater = false

	return workspace:RayCast(start, direction * 5000, raycastParams)
end

local result = createRay(rayStart, rayDirection, plr.Character)

local distTraveled = 0
while not result.Instance and not distTraveled > maxDist do
	distTraveled += 5000
	rayStart = result.Position
	result = createRay(rayStart, rayDirection, plr.Character)
end

if distTraveled < maxDist then
	print("Target found at:", (playerPos - result.Position).Magnitude, "studs from the origin.")
end

I’m not very experienced with working with raycasts, but this was my initial script:

if control:Pressed(Enum.KeyCode.F) then
		if db == false then
			db = true
			
			local r = Ray.new(script.Parent.Elevation.RangefinderPart.Position,script.Parent.Elevation.RangefinderPart.CFrame.LookVector*5000);
			local part = workspace:FindPartOnRay(r,script.Parent);
			if part then
				script.Distance.Value = round((part.Position - script.Parent.Elevation.RangefinderPart.Position).Magnitude)
			end
			
			wait(5)
			db = false
		end
	end

How can I extend the ray to go twice as far with how I’m doing it?
I was told rays have a max distance of 5000.

I should have known I could not satisfy you with that pseudocode. The first thing you should know, yes the max distance for rays is 5000. The second thing FindPartOnRay is deprecated. WorldRoot | Documentation - Roblox Creator Hub

The way you would double the length of a ray over its max is to make another ray if it doesn’t encounter anything with the first cast. However, in order to do that you need to get to the end of the ray, which you can do with this:

local endOfRay = (CFrame.new(rayOrigin) * CFrame.new(Vector3.new(0,0,0), direction) * CFrame.new(0,0,-5000)).Position

To break this down, first, we make a frame with no direction at the origin, we then add on a CFrame that has the rotation pointing in the same direction, finally, we go -5000 studs on the z-axis to get to the end of the ray.

To wholly satisfy you, I actually tested my code this time and have made this solution:

local players = game:GetService("Players")
local uis = game:GetService("UserInputService")
local plr = players.LocalPlayer

local maxDist = 60000

local debounce = false

local function createRay(start, direction, char)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.FilterDescendantsInstances = {plr.Character}
	raycastParams.IgnoreWater = false

	return workspace:Raycast(start, direction * 5000, raycastParams)
end

uis.InputBegan:Connect(function(inp, gpe)
	if gpe then return end
	
	if inp.KeyCode == Enum.KeyCode.F then
		if debounce then return end
		debounce = true
		
		local mouse = plr:GetMouse()
		local originPos = plr.Character.PrimaryPart.CFrame.Position
		local startPos = originPos
		local direction = (mouse.Hit.Position - originPos).Unit
		print(direction)
		
		local result = createRay(startPos, direction, plr.Character)
		
		local reachedDist = 5000
		while not result and not (maxDist < reachedDist) do
			reachedDist += 5000
			local startPos = (CFrame.new(startPos) * CFrame.new(Vector3.new(0,0,0), direction) * CFrame.new(0,0,-5000)).Position
			result = createRay(startPos, direction, plr.Character)
		end
		if result then
			print("Distance from origin:", (result.Position - originPos).Magnitude)
		end
		
		debounce = false
	end
end)

This example may not be exactly what you want but I hope you can infer what to do using it. I noticed in your example code you provided you wanted to use the RangefinderPart and it’s look vector, that is fine just use that for the originPos and the look vector for the distance, be sure to add the rangefinder part to the ignore list in the createRay function. I hope this helps, let me know if you need anything more.