How to make multiple raycasts easily

Hello developers

I’m doing a cooking system, it currently looks like this:

The red lines are the raycasts, and here comes the problem.

I need to make one ray in every corner of the ingredient, the thing is that i don’t know how to make more than one without making a lot of variables and configuring them all for all the ingredients because of the sizes and more.

This would be for better collisions, to detect with the rays, which is the higher ingredient to land the next on.

This is an example:

image

i need to achieve something like that.

I saw that some people uses Raycast Hitbox 4.01: For all your melee needs! to make more than one raycast easily, but i don’t know how to use that for this type of job.

This is my code:

 --//Services local Players = game:GetService("Players") local TweenService = game:GetService("TweenService") --//Variables local LocalPlayer = Players.LocalPlayer local Mouse = LocalPlayer:GetMouse() local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait() local Humanoid = Character:WaitForChild("Humanoid") local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart") local CurrentCamera = workspace.CurrentCamera local RS = game:GetService("ReplicatedStorage") --//Controls local Point = nil local Clicking = false local tweenInfo = TweenInfo.new(0.1) --//Initialization if game.Loaded then	CurrentCamera.CameraType = Enum.CameraType.Scriptable	CurrentCamera.CFrame = workspace.CamaraMostrador.CFrame end --//Functions Mouse.Button1Up:Connect(function()	Clicking = false	if Point then	local RayParams = RaycastParams.new()	RayParams.FilterDescendantsInstances = {game.Workspace.Mostrador,game.Workspace.Baseplate}	RayParams.FilterType = Enum.RaycastFilterType.Blacklist	local NewRay = Ray.new(Point.Position,Point.CFrame.YVector * -3)	local Result = workspace:Raycast(NewRay.Origin,NewRay.Direction)	local MidPoint = NewRay.Origin + NewRay.Direction/2	local Part = Instance.new("Part")	Part.Parent = game.Workspace	Part.Anchored = true	Part.CanCollide = false	Part.CanTouch = false	Part.CanQuery = false	Part.BrickColor = BrickColor.new("Really red")	Part.Transparency = 0.6	Part.Size = Vector3.new(0.1,0.1,NewRay.Direction.Magnitude)	Part.CFrame = CFrame.lookAt(MidPoint,NewRay.Origin)	local TSinfo = TweenInfo.new(0.2)	local TsAnim = TweenService:Create(Point,TSinfo,{Position = Result.Position + Vector3.new(0,0.12,0)})	TsAnim:Play()	--Point.Position = Result.Position	end	Point = nil	Mouse.TargetFilter = nil end) Mouse.Button1Down:Connect(function()	if Mouse.Target and not Mouse.Target.Locked and Mouse.Target:IsA("BasePart") and Mouse.Target:FindFirstChild("Value") then	Point = Mouse.Target	Mouse.TargetFilter = Point	Clicking = true	RS.Sounds.GrabSound:Play()	local TweenAnimation = TweenService:Create(Point, TweenInfo.new(0.2), {Position = Point.Position + Vector3.new(0, Point.Size.Y + 0.5, 0)})	TweenAnimation:Play()	end end) Mouse.Move:Connect(function()	if Clicking == true and Point then	local TweenAnimation = TweenService:Create(Point, tweenInfo, {Position = Mouse.Hit.Position + Vector3.new(0, Point.Size.Y + 0.5, 0)})	TweenAnimation:Play()	--[[	Point.Position = Vector3.new(PosX,PosY,PosZ)	]] end end) 

(It’s a local script)

Any help is appreciated

Thank you!! :slightly_smiling_face:

2 Likes

I wrote a function that takes a part as an argument and will raycast downwards from any attachments named “RaycastAttachment” in the part, and returns a dictionary of results that are keyed by the attachments.

I took a similar approach to using RaycastHitbox with the attachments, and you can change any part of the function if necessary, such as the RaycastParams.

function raycastDownward(part)	local results = {};	local raycastParams = RaycastParams.new();	raycastParams.FilterDescendantsInstances = {part};	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist;	for _, attachment in next, part:GetChildren() do	if attachment:IsA("Attachment") and attachment.Name == "RaycastAttachment" then	local origin = attachment.WorldPosition;	local direction = Vector3.new(0, -5, 0);	results[attachment] = workspace:Raycast(origin, direction, raycastParams);	end	end	return results; end 
4 Likes

I tried to implement it to the code like this:

 --//Services local Players = game:GetService("Players") local TweenService = game:GetService("TweenService") --//Variables local LocalPlayer = Players.LocalPlayer local Mouse = LocalPlayer:GetMouse() local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait() local Humanoid = Character:WaitForChild("Humanoid") local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart") local CurrentCamera = workspace.CurrentCamera local RS = game:GetService("ReplicatedStorage") --//Controls local Point = nil local Clicking = false local tweenInfo = TweenInfo.new(0.1) --//Initialization if game.Loaded then	CurrentCamera.CameraType = Enum.CameraType.Scriptable	CurrentCamera.CFrame = workspace.CamaraMostrador.CFrame end --//Functions function raycastDownward(part)	local results = {};	local raycastParams = RaycastParams.new();	raycastParams.FilterDescendantsInstances = {part};	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist;	for _, attachment in next, part:GetChildren() do -- Line 35	if attachment:IsA("Attachment") and attachment.Name == "RaycastAttachment" then	local origin = attachment.WorldPosition;	local direction = Vector3.new(0, -5, 0);	results[attachment] = workspace:Raycast(origin, direction, raycastParams);	end	end	return results; end Mouse.Button1Up:Connect(function()	Clicking = false	if Point then	raycastDownward(Point)	local Highest = nil	-- Check highest part	local Results = raycastDownward() -- Line 62	for _,TheRay in pairs(Results) do	if not Highest then	Highest = TheRay	continue	end	if TheRay.Instance.Position.Y > Highest.Instance.Position.Y then	Highest = TheRay	end	end	local TSinfo = TweenInfo.new(0.2)	local TsAnim = TweenService:Create(Point,TSinfo,{Position = Highest.Position + Vector3.new(0,0.12,0)})	TsAnim:Play()	--Point.Position = Result.Position	end	Point = nil	Mouse.TargetFilter = nil end) Mouse.Button1Down:Connect(function()	if Mouse.Target and not Mouse.Target.Locked and Mouse.Target:IsA("BasePart") and Mouse.Target:FindFirstChild("Value") then	Point = Mouse.Target	Mouse.TargetFilter = Point	Clicking = true	RS.Sounds.GrabSound:Play()	local TweenAnimation = TweenService:Create(Point, TweenInfo.new(0.2), {Position = Point.Position + Vector3.new(0, Point.Size.Y + 0.5, 0)})	TweenAnimation:Play()	end end) Mouse.Move:Connect(function()	if Clicking == true and Point then	local TweenAnimation = TweenService:Create(Point, tweenInfo, {Position = Mouse.Hit.Position + Vector3.new(0, Point.Size.Y + 0.5, 0)})	TweenAnimation:Play()	--[[	Point.Position = Vector3.new(PosX,PosY,PosZ)	]] end end) 

But i got these errors:

The parts have the attachments with the right name

Also, i think that the problem comes when i return the “Results” variable

1 Like

You have to pass the part argument when calling the function.

1 Like