I’m trying to check the surroundings of a part, and if there is an unoccupied space, put the position of that space into a list, then choose a random space position, and spawn part there accordingly. But for some reason, the CFrame turns nil. Here is my code, its kind of messy, but I hope is understandable:
local TweenService = game:GetService("TweenService")
local RootList = {}
local heart = workspace.Overgrowth.OverGrowthHeart
table.insert(RootList, heart)
script.Parent.MouseClick:Connect(function()
repeat
local overlapParams = OverlapParams.new()
overlapParams.FilterDescendantsInstances = workspace.Overgrowth:GetChildren()
overlapParams.FilterType = Enum.RaycastFilterType.Include
local availableSpots = {}
-- Check Boxes
local UpCheckBoxResult = workspace:GetPartBoundsInBox(RootList[#RootList].CFrame * CFrame.new(0, 1, 0), Vector3.new(0.8, 0.8, 0.8), overlapParams)
local DownCheckBoxResult = workspace:GetPartBoundsInBox(RootList[#RootList].CFrame * CFrame.new(0, -1, 0), Vector3.new(0.8, 0.8, 0.8), overlapParams)
local LeftCheckBoxResult = workspace:GetPartBoundsInBox(RootList[#RootList].CFrame * CFrame.new(-1, 0, 0), Vector3.new(0.8, 0.8, 0.8), overlapParams)
local RightCheckBoxResult = workspace:GetPartBoundsInBox(RootList[#RootList].CFrame * CFrame.new(1, 0, 0), Vector3.new(0.8, 0.8, 0.8), overlapParams)
local FrontCheckBoxResult = workspace:GetPartBoundsInBox(RootList[#RootList].CFrame * CFrame.new(0, 0, -1), Vector3.new(0.8, 0.8, 0.8), overlapParams)
local BackCheckBoxResult = workspace:GetPartBoundsInBox(RootList[#RootList].CFrame * CFrame.new(0, 0, 1), Vector3.new(0.8, 0.8, 0.8), overlapParams)
--
if #UpCheckBoxResult == 0 then
table.insert(availableSpots, (RootList[#RootList].CFrame * CFrame.new(0, 1, 0)))
else
continue
end
if #DownCheckBoxResult == 0 then
table.insert(availableSpots, (RootList[#RootList].CFrame * CFrame.new(0, -1, 0)))
else
continue
end
if #LeftCheckBoxResult == 0 then
table.insert(availableSpots, (RootList[#RootList].CFrame * CFrame.new(-1, 0, 0)))
else
continue
end
if #RightCheckBoxResult == 0 then
table.insert(availableSpots, (RootList[#RootList].CFrame * CFrame.new(1, 0, 0)))
else
continue
end
if #FrontCheckBoxResult == 0 then
table.insert(availableSpots, (RootList[#RootList].CFrame * CFrame.new(0, 0, -1)))
else
continue
end
if #BackCheckBoxResult == 0 then
table.insert(availableSpots, (RootList[#RootList].CFrame * CFrame.new(0, 0, 1)))
else
continue
end
if #availableSpots > 0 then
local nextRootPosition = table.find(availableSpots, math.random(1, #availableSpots))
local spawnPosition
if nextRootPosition == RootList[#RootList].CFrame * CFrame.new(0, 1, 0) then
spawnPosition = nextRootPosition * CFrame.new(0, -0.5, 0)
elseif nextRootPosition == RootList[#RootList].CFrame * CFrame.new(0, -1, 0) then
spawnPosition = nextRootPosition * CFrame.new(0, 0.5, 0)
elseif nextRootPosition == RootList[#RootList].CFrame * CFrame.new(-1, 0, 0) then
spawnPosition = nextRootPosition * CFrame.new(0.5, 0, 0)
elseif nextRootPosition == RootList[#RootList].CFrame * CFrame.new(1, 0, 0) then
spawnPosition = nextRootPosition * CFrame.new(-0.5, 0, 0)
elseif nextRootPosition == RootList[#RootList].CFrame * CFrame.new(0, 0, -1) then
spawnPosition = nextRootPosition * CFrame.new(0, 0, 0.5)
elseif nextRootPosition == RootList[#RootList].CFrame * CFrame.new(0, 0, 1) then
spawnPosition = nextRootPosition * CFrame.new(0, 0, -0.5)
end
print(spawnPosition)
local newRoot = Instance.new("Part")
newRoot.Anchored = false
newRoot.Size = Vector3.new(0.002, 0.002, 0.002)
newRoot.CFrame = spawnPosition
newRoot.Color = Color3.fromRGB(80, 109, 84)
newRoot.Parent = workspace
newRoot.Name = tostring("root".. tostring(#RootList + 1))
local weld = Instance.new("WeldConstraint")
weld.Part0 = newRoot
weld.Part1 = RootList[#RootList]
weld.Parent = newRoot
local growthTweenGoals = {}
growthTweenGoals.CFrame = nextRootPosition
growthTweenGoals.Size = Vector3.new(1, 1, 1)
local growthTweenInfo = TweenInfo.new(1, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out, 0, false, 0)
local growthTween = TweenService:Create(newRoot, growthTweenInfo, growthTweenGoals)
growthTween:Play()
table.insert(RootList, newRoot)
print(RootList)
else
print("smth went wrong")
break
end
task.wait(1)
until #RootList == 100
end)
The nextRootPosition is the final destination where the part needs to be positioned, while the spawnPosition is a slightly changed nextRootPosition, where part is initially spawned, and then moved to the nextRootPosition with tweenService.