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