I have a building system I adapted to work for placing farmland.
This function handles the events for the hoe tool. It’s hooked up to CollectionService events.
local function HoeEvents(Hoe)
local ActiveHoe = nil
Hoe.Equipped:Connect(function()
ActiveHoe = Hoe
end)
Hoe.Unequipped:Connect(function()
if ActiveHoe == Hoe then
ActiveHoe = nil
end
end)
UIS.InputBegan:Connect(function(input)
if not ActiveHoe then return end
if input.KeyCode == Enum.KeyCode.F and ClientState.BuildMode == false then
TillingMode = not TillingMode
if TillingMode then
local FarmlandSquare = BuildingFolder.Hollogram.FarmlandSquare:Clone()
FarmlandSquare.Parent = workspace
warn(FarmlandSquare,FarmlandSquare:GetDescendants(),FarmlandSquare.PrimaryPart)
UpdatePosition(FarmlandSquare,true)
CurrentItem = FarmlandSquare
PlacingState = true
UpdateClickDetector()
else
if CurrentItem then
CurrentItem:Destroy()
end
PlacingState = false
end
end
end)
Hoe.Activated:Connect(function()
if GoodToPlace then
game.ReplicatedStorage.PlaceBuildingItem:FireServer(CurrentItem.Name,CurrentItem:GetPrimaryPartCFrame(),LockedItem,true)
end
end)
game.ReplicatedStorage.Tools.HoeBroke.OnClientEvent:Connect(function()
CurrentItem:Destroy()
RenderSteppedConnection:Disconnect()
RenderSteppedConnection = nil
end)
end
This part of the function clones the hollogram of the farmland to the workspace so it can be dragged around on screen
local FarmlandSquare = BuildingFolder.Hollogram.FarmlandSquare:Clone()
FarmlandSquare.Parent = workspace
warn(FarmlandSquare,FarmlandSquare:GetDescendants(),FarmlandSquare.PrimaryPart)
UpdatePosition(FarmlandSquare,true)
CurrentItem = FarmlandSquare
PlacingState = true
UpdateClickDetector()
The warn() statement prints a set of descendants and the primary part.
However, when I pass it to the UpdatePosition() function, the Farmland no longer has any descendants
local function UpdatePosition(BuildingItem,TerrainParams)
local IgnoreList = {BuildingItem,Character}
local Params = RaycastParams.new()
Params.FilterDescendantsInstances = IgnoreList
RenderSteppedConnection = game:GetService("RunService").RenderStepped:Connect(function()
local RaycastResult = workspace:Raycast(Mouse.UnitRay.Origin, Mouse.UnitRay.Direction * 1000, Params)
local Hit, Position = RaycastResult and RaycastResult.Instance, RaycastResult and RaycastResult.Position
local MaterialAllowed = false
if TerrainParams and Hit == workspace.Terrain then
if RaycastResult.Material == Enum.Material.Grass or RaycastResult.Material == Enum.Material.Ground then
MaterialAllowed = true
end
end
local Pos
if Hit then
if BuildPositionLocking[BuildingItem.Name] and Hit:HasTag(BuildPositionLocking[BuildingItem.Name]) then
LockedItem = Hit
Pos = Hit.CFrame
else
LockedItem = nil
Pos = CFrame.new(
Vector3.new(
math.ceil(Position.X/GridSizes[CurrentGridSize])*GridSizes[CurrentGridSize],
math.ceil(Position.Y),
math.ceil(Position.Z/GridSizes[CurrentGridSize])*GridSizes[CurrentGridSize])
)*CFrame.Angles(0,math.rad(CurrentRoation),0)
end
BuildingItem:PivotTo(Pos)
print(BuildingItem,BuildingItem:GetDescendants(),BuildingItem.PrimaryPart)
local PrimaryPart = BuildingItem.PrimaryPart
local PrimaryPartPos = PrimaryPart.Position
local DownRaycastResult = workspace:Raycast(PrimaryPartPos, Vector3.new(0, -1, 0) * 2, Params)
local DownHit = DownRaycastResult and DownRaycastResult.Instance
local DownHitPos = DownRaycastResult and DownRaycastResult.Position
local InsideRayOrigin = PrimaryPartPos - Vector3.new(0, 2.5, 0)
local UpRaycastResult = workspace:Raycast(InsideRayOrigin, Vector3.new(0, 1, 0) * 2.5, Params)
local UpHit = UpRaycastResult and UpRaycastResult.Instance
local UpHitPos = UpRaycastResult and UpRaycastResult.Position
if (PrimaryPartPos-Character.HumanoidRootPart.Position).Magnitude >= MaxPlacingDistance then--Part is too far away
GoodToPlace = false
for i,v in BuildingItem.Structure:GetChildren() do
v.Color = Color3.new(1, 0.54902, 0)
end
elseif (DownHit or UpHit) and (not TerrainParams or MaterialAllowed) then
GoodToPlace = true
for i,v in BuildingItem.Structure:GetChildren() do
v.Color = Color3.new(0.101961, 1, 0)
end
else
GoodToPlace = false
for i,v in BuildingItem.Structure:GetChildren() do
v.Color = Color3.new(1, 0, 0)
end
end
end
wait()
end)
end
print(BuildingItem,BuildingItem:GetDescendants(),BuildingItem.PrimaryPart) prints “FarmlandSquare, {}, nil” meaning somewhere along the way the famland lost all its descendants. Why does this happen?
If this is useful information, this issue didn’t happen until I moved the code in HoeEvents() into a function. it used to just be contained in this:
for i, Hoe in CollectionService:GetTagged("Hoe") do
...
end
But I change it into a function so I could have that code run for current and existing hoes
for i, Hoe in CollectionService:GetTagged("Hoe") do
HoeEvents(Hoe)
end
CollectionService:GetInstanceAddedSignal("Hoe"):Connect(function(Hoe)
HoeEvents(Hoe)
end)
Once I did this is when the problem came about.