Raycast returning nil

i am trying to do random item spawning around the map. its supposed to spawn only in designated areas, drop zones. raycastResult always prints nil and i dont knwo how to fix this, its my first time using raycasting.

local ServerStorage = game:GetService("ServerStorage")

local itemDropList = ServerStorage.Drops:GetChildren()

while true do
	local itemDrop = itemDropList[math.random(1, #itemDropList)]
	
	local xPosition = math.random(-256, 256)
	local zPosition = math.random(-256, 256)
	local raycastOrigin = Vector3.new(xPosition, 128, zPosition)
	local raycastDirection = Vector3.new(xPosition, -128, zPosition)
	
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = game.Workspace.DropZones:GetChildren()
	raycastParams.FilterType = Enum.RaycastFilterType.Whitelist
	
	local raycast = Ray.new(raycastOrigin, raycastDirection)
	
	
	local raycastResult = workspace:Raycast(raycastOrigin, raycastDirection, raycastParams)
	
	local start = Instance.new("Part")
	start.Parent = game.Workspace
	start.Position = raycastOrigin
	start.Color = Color3.fromRGB(255,0,0)
	start.Anchored = true
	
	local endd = Instance.new("Part")
	endd.Parent = game.Workspace
	endd.Position = raycastDirection
	endd.Color = Color3.fromRGB(0,255,0)
	endd.Anchored = true
	
	if raycastResult then
		local itemDropClone = itemDrop:Clone()
		itemDropClone.Position = raycastResult.Position
		itemDropClone.Parent = game.Workspace
		itemDropClone.Anchored = false
		
		print(raycastResult.Position)
	else
		print("failed")
	end
	wait(4)
end

thanks

I doubt that this is actually a valid direction vector. Instead a direction should be a unit vector (a vector with a lenght of 1). For example, a valid direction vector that faces downwards would be Vector3.new(0, -1, 0).

You should multiply raycastDirection with the length of your raycast here. Otherwise, your raycast will have a length of 1 (if raycastDirection is a unit vector).

It should be.

local xPosition = math.random(-256, 256)
local zPosition = math.random(-256, 256)
local raycastOrigin = Vector3.new(xPosition, 128, zPosition) -- It starts in the sky
local raycastDirection = Vector3.new(xPosition, 0, zPosition) -- It goes down to 0 in Y

but in this article no .Unit is used

It might be that it is finding a random place that is not facing a valid drop point? You set the filter type to whitelist, meaning it will only accept a drop point.

It is not mandatory to use .Unit, but it makes it easier to specify the lenght of your raycast (raycastDirection = unitVector * raycastLength).

image

whole baseplate is whitelisted (for the test)

would it look like this?

local raycastDirection = Vector3.new(xPosition, -1, zPosition).Unit * 128

Try this:

local raycastOrigin = Vector3.new(xPosition, 128, zPosition)
local raycastDirection = Vector3.new(xPosition, -128, zPosition)

Because its the direction, it’s not actually going down, its going back to it’s original position, I just realised it. @Brickman808 was correct.

Edit: @Brickman808 's version still works, it returns the same value, he got there first.

1 Like

i added parts to visualize the points
image

dont know why but raycast gives the result sometimes
image

no idea why, it should be 100% successful rays, since

local xPosition = math.random(-256, 256)
local zPosition = math.random(-256, 256)

covers the whole baseplate

Okay, I’m going to try some code in studio and see if it works. I’ll be back with you in a second.

1 Like

OH MY GOSH
so, the direction is incorrect… once again…

local raycastDirection = Vector3.new(0, -128, 0)

its the direction, is the same reason. Try this:

while wait(4) do
	local itemDrop = itemDropList[math.random(1, #itemDropList)]

	local xPosition = math.random(-256, 256)
	local zPosition = math.random(-256, 256)
	local raycastOrigin = Vector3.new(xPosition, 128, zPosition)
	local raycastDirection = Vector3.new(0, -128, 0)

	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = game.Workspace.DropZones:GetChildren()
	raycastParams.FilterType = Enum.RaycastFilterType.Whitelist

	local raycast = Ray.new(raycastOrigin, raycastDirection)


	local raycastResult = workspace:Raycast(raycastOrigin, raycastDirection, raycastParams)

	if raycastResult then
		local itemDropClone = itemDrop:Clone()
		itemDropClone.Parent = game.Workspace
		itemDropClone.Position = raycastResult.Position
		itemDropClone.Anchored = false

		print(raycastResult.Position)
	else
		print("failed")
	end
end

by the way, you don’t need to use game.Workspace you could just do workspace it saves a lot of characters

2 Likes

seems to work, thanks. ill try it with non flat terrain and different shape of dropzone to check out if it works properly.

edit: all good, thanks again

1 Like