Place model distance limit / part touch?

So basically, I have a cooler that im trying to use to place and rummage thru etc, but im not exactly sure how id go about making distance limit on it, and how to stop it colliding with other parts?

I assumed with the touching parts id have to make sure i name everything ground related to specific names and just check the hit name, but as far as collisions/distance im stumped.

this video shows the distance/collision

this video shows this weird bug im having where it keeps trying to place it on itself?

any help is appreciated heres the placement script I have setup

local mouse = game.Players.LocalPlayer:GetMouse()
local off = false
function round(vector, unit)
	return vector - Vector3.new(vector.X%unit, vector.Y%unit, vector.Z%unit)
end
script.Parent.Equipped:Connect(function(toolMouse)
	if mouse ~= nil then
		local clonedBrick = game.ReplicatedStorage.Cooler:Clone()
		mouse.TargetFilter = clonedBrick.PrimaryPart
		clonedBrick.Close.Cooler.Transparency = .5
		clonedBrick.Close.Lid.Transparency = .5
		clonedBrick.Close.Cooler.CanCollide = false
		clonedBrick.Close.Lid.CanCollide = false
		clonedBrick.Parent = workspace
		while mouse ~= nil and mouse.TargetSurface.Name ~= "Cooler" and mouse.TargetSurface.Name ~= "Lid" and mouse.TargetSurface.Name ~= "Display" and mouse.TargetSurface.Name ~= "Ice" do
			local pos = (mouse.Hit.p)
			local posit2 = pos + Vector3.new(0,0.8,0)
			local posit3 = pos + Vector3.new(0,1.2,0)
			clonedBrick.PrimaryPart.Position = posit2
			clonedBrick.Close.Lid.Position = posit3
			wait()
			if off then
				clonedBrick:Destroy()
				off = false
				break
			end
		end
	end
end)

script.Parent.Activated:Connect(function()
	local BrickToPlace = game.ReplicatedStorage.Cooler:Clone()
	local pos = (mouse.Hit.p)
	local posit2 = pos + Vector3.new(0,0.8,0)
	script.Parent.AddBlock:FireServer(posit2)
end)

script.Parent.Unequipped:Connect(function()
	off = true
end)
1 Like

You might want to use raycasting instead of…wtv you are doing now. It’s much more straightforward and it fixes the issue where the brick is trying to place on itself. Here’s how to implement it, fit it where you think is appropriate

game.RunService.Heartbeat:Connect(function()
   local mray = mouse.UnitRay
   local rp = RaycastParams.new()
   rp.FilterDescendantsInstances = {game.Players.LocalPlayer.Character,clonedBrick}
   rp.FilterType = Enum.RaycastFilterType.Exclude
   local ray = workspace:Raycast(mray.Origin,mray.Direction,rp)
   if ray then
      if ray.Instance:IsA('Model') then clonedbrick.Position = ray.Position + Vector3.new(0,ray.Instance.PrimaryPart.Size.Y / 2,0) 
      elseif ray.Instance:IsA('BasePart') or ray.Instance:IsA('MeshPart') then
        clonedbrick.Position = ray.Position + Vector3.new(0,ray.Instance.Size.Y / 2,0) 
      end
   end
end)

As for the collision issue, you could have 2 collision groups to manage collision between template parts and real parts

SO i tried it out and got to a point where it spawns the cooler, but its not following the mouse?

local mouse = game.Players.LocalPlayer:GetMouse()
local RunService = game:GetService("RunService")
local off = false
function round(vector, unit)
	return vector - Vector3.new(vector.X%unit, vector.Y%unit, vector.Z%unit)
end

local clonedBrick = game.ReplicatedStorage.Cooler:Clone()
script.Parent.Equipped:Connect(function(toolMouse)
	if mouse ~= nil then
		local clonedBrick = game.ReplicatedStorage.Cooler:Clone()
		mouse.TargetFilter = clonedBrick.PrimaryPart
		clonedBrick.Close.Cooler.Transparency = .5
		clonedBrick.Close.Lid.Transparency = .5
		clonedBrick.Close.Cooler.CanCollide = false
		clonedBrick.Close.Lid.CanCollide = false
		clonedBrick.Parent = workspace
		RunService.RenderStepped:Connect(function(step)
			local mray = mouse.UnitRay
			local rp = RaycastParams.new()
			rp.FilterDescendantsInstances = {game.Players.LocalPlayer.Character,clonedBrick.PrimaryPart}
			rp.FilterType = Enum.RaycastFilterType.Exclude
			local ray = workspace:Raycast(mray.Origin,mray.Direction,rp)
			if ray then
				if ray.Instance:IsA('Model') then clonedBrick.PrimaryPart.Position = ray.Instance.PrimaryPart.Position + Vector3.new(0,ray.Instance.PrimaryPart.Size.Y / 2,0) 
				elseif ray.Instance:IsA('BasePart') or ray.Instance:IsA('MeshPart') then
					clonedBrick.PrimaryPart.Position = ray.Position + Vector3.new(0,ray.Instance.Size.Y / 2,0) 
				end
			end
		end)
		end
end)

script.Parent.Activated:Connect(function()
	local BrickToPlace = game.ReplicatedStorage.Cooler:Clone()
	local pos = (mouse.Hit.p)
	local posit2 = pos + Vector3.new(0,0.8,0)
	script.Parent.AddBlock:FireServer(posit2)
end)

script.Parent.Unequipped:Connect(function()
	off = true
end)

edit: never really worked with raycast before

Don’t know about the second bug, but to limit the placement distance, you can:

Use math.clamp(x: number, min: number, max: number) on the mouse’s position to keep the position coordinates between 25 studs away from the humanoid root part’s position.

while mouse ~= nil and mouse.TargetSurface.Name ~= "Cooler" and mouse.TargetSurface.Name ~= "Lid" and mouse.TargetSurface.Name ~= "Display" and mouse.TargetSurface.Name ~= "Ice" do
	local character = game.Players.LocalPlayer.Character
	local root = character:WaitForChild("HumanoidRootPart")

	local pos = (mouse.Hit.Position)
	pos = Vector3.new(math.clamp(pos.X - root.Position.X, root.Position.X, root.Position.X + 25), math.clamp(pos.Y - root.Position.Y, root.Position.Y, root.Position.Y + 25), math.clamp(pos.Z - root.Position.Z, root.Position.Z, root.Position.Z + 25))

	local posit2 = pos + Vector3.new(0,0.8,0)
	local posit3 = pos + Vector3.new(0,1.2,0)
	clonedBrick.PrimaryPart.Position = posit2
	clonedBrick.Close.Lid.Position = posit3

	task.wait()

	if off then
		clonedBrick:Destroy()
		off = false
		break
	end
end

I made this script without testing, so I might have messed something up. It’s worth a try tho

Yeah i tried it and it makes the cooler not be anywhere near the mouse

Can you send a video of what’s happening?

attempted re-Script
local mouse = game.Players.LocalPlayer:GetMouse()
local RunService = game:GetService("RunService")
local off = false

function round(vector, unit)
	return vector - Vector3.new(vector.X % unit, vector.Y % unit, vector.Z % unit)
end

local clonedBrick, hitPos = nil, nil
script.Parent.Equipped:Connect(function(toolMouse)
	if mouse then
		clonedBrick = game.ReplicatedStorage.Cooler:Clone()
		clonedBrick.PrimaryPart = clonedBrick:FindFirstChild("PrimaryPartName")
		mouse.TargetFilter = clonedBrick

		clonedBrick.Cooler.Transparency = 0.5
		clonedBrick.Lid.Transparency = 0.5
		clonedBrick.Cooler.CanCollide = false
		clonedBrick.Lid.CanCollide = false

		clonedBrick.Parent = workspace
		RunService.RenderStepped:Connect(function()
			if off then return end
			local mray = mouse.UnitRay
			local rp = RaycastParams.new()
			rp.FilterDescendantsInstances = {game.Players.LocalPlayer.Character, clonedBrick}
			rp.FilterType = Enum.RaycastFilterType.Exclude
			
			local ray = workspace:Raycast(mray.Origin, mray.Direction * 500, rp)
			if ray then hitPos = ray.Position
				clonedBrick:SetPrimaryPartCFrame(CFrame.new(hitPos
					+ Vector3.new(0, clonedBrick.PrimaryPart.Size.Y / 2, 0)))
			end
		end)
	end
end)

script.Parent.Activated:Connect(function()
	if clonedBrick then
		local pos = mouse.Hit.p + Vector3.new(0, 0.8, 0)
		script.Parent.AddBlock:FireServer(pos)
		clonedBrick = nil
	end
end)

script.Parent.Unequipped:Connect(function()
	off = true
	if clonedBrick then
		clonedBrick:Destroy()
		clonedBrick = nil
	end
end)

this works as should, and i was able to set the max distance, but how would I go about checking if what their hitting is ground or not?

Now I’m guessing.

Script
local mouse = game.Players.LocalPlayer:GetMouse()
local RunService = game:GetService("RunService")
local off = false

function round(vector, unit)
	return vector - Vector3.new(vector.X % unit, vector.Y % unit, vector.Z % unit)
end

local clonedBrick = nil

script.Parent.Equipped:Connect(function(toolMouse)
	if mouse then
		clonedBrick = game.ReplicatedStorage.Cooler:Clone()
		clonedBrick.PrimaryPart = clonedBrick:FindFirstChild("PrimaryPartName")
		mouse.TargetFilter = clonedBrick

		clonedBrick.Cooler.Transparency = 0.5
		clonedBrick.Lid.Transparency = 0.5
		clonedBrick.Cooler.CanCollide = false
		clonedBrick.Lid.CanCollide = false

		clonedBrick.Parent = workspace

		RunService.RenderStepped:Connect(function()
			if off then return end
			local mray = mouse.UnitRay
			local rp = RaycastParams.new()
			rp.FilterDescendantsInstances = {game.Players.LocalPlayer.Character, clonedBrick}
			rp.FilterType = Enum.RaycastFilterType.Exclude
			local ray = workspace:Raycast(mray.Origin, mray.Direction * 500, rp)

			if ray and (ray.Instance:IsA("Terrain") or ray.Instance.Name == "Ground") then
				local hitPos = ray.Position
				clonedBrick:SetPrimaryPartCFrame(CFrame.new(hitPos + Vector3.new(0, clonedBrick.PrimaryPart.Size.Y / 2, 0)))
			end
		end)
	end
end)

script.Parent.Activated:Connect(function()
	if clonedBrick then
		local pos = mouse.Hit.p + Vector3.new(0, 0.8, 0)
		script.Parent.AddBlock:FireServer(pos)
		clonedBrick = nil
	end
end)

script.Parent.Unequipped:Connect(function()
	off = true
	if clonedBrick then
		clonedBrick:Destroy()
		clonedBrick = nil
	end
end)