Parent property locked

So it works fine a few times but its also constantly buggy and giving me warnings/errors but then the parent property is locked?

Error : ContextActionService: Unexpected error while invoking callback: The Parent property of she1ls is locked, current parent: NULL, new parent Workspace

local PlacementValidator = {}
PlacementValidator.__index = PlacementValidator

local CollectionService = game:GetService("CollectionService")
local CAS = game:GetService("ContextActionService")
local RunService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")

local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera


local Remote = game.ReplicatedStorage.Remotes.PlacementValidator
local RemoteEvent = game.ReplicatedStorage.Remotes.PlacementValidatorEvent


function PlacementValidator:CleanUp()
	CAS:UnbindAction("PreviewMode")
	CAS:UnbindAction("Place")

	if self.CurrentTower and self.CurrentTower.Parent then
		self.CurrentTower:Destroy()
	end
	self.CurrentTower = nil
	self.PreviewOn = false
	self.CanPlace = false
end

function PlacementValidator.new(tower)

	local self = setmetatable({}, PlacementValidator)

	self.PreviewOn = false
	self.CanPlace = false
	self.CurrentTower = tower 

	self:Init()
	return self
end


function PlacementValidator.EditTower(tower, color, transparency, material)
	for _, bodypart in tower:GetChildren() do
		if bodypart:IsA("BasePart") then
			bodypart.Color = color
			bodypart.Transparency = transparency 
			bodypart.Material = material 
		end
	end
end

function PlacementValidator:PreviewMode()

	if self.PreviewOn then
		self:CleanUp() 
		return 
	end

	if not self.CurrentTower then
		warn(self.CurrentTower.Name.. "Is not a valid tower")
	end

	if not self.CurrentTower.Parent then
		warn(self.CurrentTower.Name.. "Does not have a parent!")
	end

	self.CurrentTower.Parent = workspace
	self.PreviewOn = true

	RunService:BindToRenderStep("PreviewMode", Enum.RenderPriority.Camera.Value, function()
		self:Preview()
	end)

end



function PlacementValidator:Preview()
	if self.PreviewOn == true or self.CurrentTower then
		self:PlacementValidatorTower(self.CurrentTower)

		if not self.CurrentTower:FindFirstChild("HumanoidRootPart") or not self.CurrentTower:FindFirstChild("Humanoid") then
			warn("Tower is missing HRP or a Humanoid")
			return
		end

		local MousePos = UIS:GetMouseLocation()
		local MouseInfo = camera:ViewportPointToRay(MousePos.X, MousePos.Y)

		local Params = RaycastParams.new()
		Params.FilterDescendantsInstances = {self.CurrentTower, player.Character}
		Params.FilterType = Enum.RaycastFilterType.Exclude

		local raycast = workspace:Raycast(MouseInfo.Origin, MouseInfo.Direction * 200, Params)

		if raycast and raycast.Instance then
			local Pos = raycast.Position + Vector3.new(0, self.CurrentTower:WaitForChild("HumanoidRootPart").Size.Y + (self.CurrentTower.Humanoid.HipHeight + 1), 0)
			self.CurrentTower:PivotTo(CFrame.new(Pos))

			if raycast.Instance.Parent == workspace.ValidAreas and self.CanPlace == true then
				PlacementValidator.EditTower(self.CurrentTower, Color3.new(0,1,0), 0.5, Enum.Material.ForceField)
			else
				PlacementValidator.EditTower(self.CurrentTower, Color3.new(1,0,0), 0.5, Enum.Material.ForceField)
			end
		end
	end
end


function PlacementValidator:PlacementValidatorTower()
	if self.PreviewOn == true  and self.CurrentTower and self.CurrentTower:FindFirstChild("HumanoidRootPart") then

		local result = Remote:InvokeServer(self.CurrentTower.HumanoidRootPart.Position)
		if result == "Valid" then
			self.CanPlace = true
			print("Valid")
		else
			self.CanPlace = false
			print("Invalid")
		end
	end
end


function PlacementValidator:PlaceTower()
	if not self.CanPlace or not self.CurrentTower then return end
	print("yes")

	local OldTowerName = self.CurrentTower.Name
	local OldTowerCFrame = self.CurrentTower.HumanoidRootPart.CFrame

	self.CanPlace = false
	self.PreviewOn = false

	RunService:UnbindFromRenderStep("PreviewMode")

	if game.ReplicatedStorage.TowersToSpawn:FindFirstChild(OldTowerName) then

		local PlacedTower = game.ReplicatedStorage.TowersToSpawn[OldTowerName]:Clone()
		PlacedTower.Parent = workspace
		PlacedTower:PivotTo(OldTowerCFrame)

		task.defer(function()
			self.CurrentTower:Destroy()
			self.CurrentTower = nil
			
			self.CurrentTower = game.ReplicatedStorage.TowersToSpawn[OldTowerName]:Clone()
		end)
	end
end


function PlacementValidator:Init()
	CAS:BindAction("PreviewMode", function(_, state)
		if state == Enum.UserInputState.End then
			self:PreviewMode()
		end
	end, false, Enum.KeyCode.E)

	CAS:BindAction("Place", function(_, state)
		if state == Enum.UserInputState.End then
			self:PlaceTower()
		end
	end, false, Enum.UserInputType.MouseButton1)
end

return PlacementValidator

Not sure about it being buggy, but the parent property of ___ is locked generally happens when you try to change the parent of something that is being destroyed (through :Destroy() or other)

1 Like