Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How can I fix my ground raycasting script?

I have a module script that is supposed to detect the ground by having several origins and looping through them. However, the script doesn't detect anything. I don't really understand raycasting well, so I have no idea what I'm missing here.

Module for Detecting Ground

function groundDetection:set(Character)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.FilterDescendantsInstances = {Character}
	raycastParams.IgnoreWater = true
	
	local humanoidRoot = Character.HumanoidRootPart
	local xRange = 0.95
	local yRange = 3.05
	local zRange = 0.475
	
	local origins = 
		{	humanoidRoot.Position, 
			humanoidRoot.CFrame.RightVector*xRange, humanoidRoot.CFrame.RightVector*-xRange, 
			humanoidRoot.CFrame.LookVector*zRange, humanoidRoot.CFrame.LookVector*-zRange,
		}
	
	local hitParts = {}
	
	for i,origin in pairs(origins) do
		local newOrigin = Vector3.new(origin)
		local destination = CFrame.new(origin).UpVector * -yRange
		
		local raycastResult = workspace:Raycast(newOrigin, destination, raycastParams)
		
		if raycastResult then
			local distance = (origin - raycastResult.Position).Magnitude
			local p = Instance.new("Part")
			p.Anchored = true
			p.CanCollide = false
			p.Size = Vector3.new(0.1, 0.1, distance)
			p.CFrame = CFrame.lookAt(origin, raycastResult.Position)*CFrame.new(0, 0, -distance/2)
			
			table.insert(hitParts, raycastResult.Instance:GetFullName())
		end
	end
	print(hitParts)
end

2 answers

✓ Accepted answer

It seems to me (although I may be mistaken) that your yRange is too small of a number.

I whipped up this script after seeing this post, and it works:

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(char)
		local params = RaycastParams.new()
		params.FilterType = Enum.RaycastFilterType.Blacklist
		params.FilterDescendantsInstances = {char}
		params.IgnoreWater = true
		
		local humanoidRoot = char:WaitForChild("HumanoidRootPart")
		local xRange = 0.95
		local yRange = 6.05
		local zRange = 0.475
		
		local hitParts = {}
		
		while true do
			local origins = 
				{   humanoidRoot.Position, 
					humanoidRoot.CFrame.RightVector*xRange, humanoidRoot.CFrame.RightVector*-xRange, 
					humanoidRoot.CFrame.LookVector*zRange, humanoidRoot.CFrame.LookVector*-zRange,
				}
			for _,v in pairs(origins) do
			
				local ray = workspace:Raycast(v, (v - Vector3.new(0,1000,0)).unit * yRange, params)
				
				-- ==== VISUAL DEBUGGING ==== --

				local display = Instance.new("Part")
				display.Anchored = true
				display.CanCollide = false
				display.Position = v
				display.Size = Vector3.new(1,1,1)
				display.Parent = workspace
				display.Name = "Display"
				
				local display2 = display:Clone()
				display2.Position = v-Vector3.new(0,yRange,0)
				display2.Color = Color3.fromRGB(255,0,0)
				display2.Parent = workspace
				display2.Name = "Display2"
				
				
				game:GetService("Debris"):AddItem(display,1.5)
				game:GetService("Debris"):AddItem(display2,1.5)
				
				-- ==== VISUAL DEBUGGING END ==== --
				
				if ray then
					print(tostring(ray.Instance)) -- Output: Baseplate (tested in a new baseplate)
					table.insert(hitParts,ray.Instance)
				end
			end
			wait(5)
		end
		
	end)
end)

Some mentions here:

local ray = workspace:Raycast(v, (v - Vector3.new(0,1000,0)).unit * yRange, params)

More specifically this:

(v - Vector3.new(0,1000,0)).unit -- the direction, straight down

multiplied by the range of the ray:

 (v - Vector3.new(0,1000,0)).unit * yRange -- the direction, and magnitude of the ray

If you have any further questions, you can feel free to contact me on Discord (phxntxsmic#2021)

EDIT

In addition to everything I have said, JustinWe12 is correct.

"To run a module script, you have to require() from a local script or a server script and fire it from there."

To run a module script, you have to require() from a local script or a server script and fire it from there.

This discussion is preserved as it was. New answers, comments, and votes are closed.