local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local CollectionService = game:GetService("CollectionService")
local HTTPService = game:GetService("HttpService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PhysicsService = game:GetService("PhysicsService")
local UiHandler = require(script.Parent.Parent:WaitForChild("Modules"):WaitForChild("UIHandler"))
local trove = require(ReplicatedStorage:WaitForChild("UtilityModules"):WaitForChild("Trove"))
local GoodSignal = require(ReplicatedStorage:WaitForChild("UtilityModules"):WaitForChild("GoodSignal"))
local placeTowerRemote = ReplicatedStorage:WaitForChild("PlayerRemotes"):WaitForChild("PlaceTower")
local TowerHandler = {}
TowerHandler.__newindex = function()
error("Unable to obtain tower!")
end
local isClient = RunService:IsClient()
if not isClient then return end
---------
local player = Players.LocalPlayer
local x, y, z
local towerBeingPlace = false
local towerRaycast = nil
local placeHolderTower
local rotationAngle = 0
local angleCFrame = nil
---------
local function mouseRaycast(tower)
if not placeHolderTower then print("NOT FOUND") return end
local raycastParamsTower = RaycastParams.new()
raycastParamsTower.FilterType = Enum.RaycastFilterType.Exclude
raycastParamsTower.FilterDescendantsInstances = {player.Character, tower}
local mousePosition = UserInputService:GetMouseLocation()
local mouseRay = workspace.CurrentCamera:ViewportPointToRay(mousePosition.X, mousePosition.Y)
local raycastResult = workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 1000, raycastParamsTower)
if raycastResult then
return raycastResult
else
return nil
end
end
function TowerHandler.InitializePlacement(player: Player, tower: Model)
if towerBeingPlace then print("Already being placed!") end
local self = {}
self.Tower = tower:Clone()
self.Player = player
self.TowerField = tower.TowerField
self.towerPrimaryPart = self.Tower.PrimaryPart
self.UIPart = tower.UIDisplay
self.Tower.Parent = game.Workspace
self.__trove = trove.new()
self.Tower:SetAttribute("UniqueID", player.UserId)
placeHolderTower = tower
towerBeingPlace = true
self.TowerConnection = RunService.Heartbeat:Connect(function(deltaTime)
local raycastResult = mouseRaycast(self.Tower)
if raycastResult and raycastResult.Position and towerBeingPlace then
x, y, z = raycastResult.Position.X, raycastResult.Position.Y + tower.Humanoid.HipHeight + (tower.PrimaryPart.Size.Y / 0.65), raycastResult.Position.Z
local positionCFrame = CFrame.new(x, y, z)
local rotationCFrame = CFrame.Angles(0, math.rad(rotationAngle), 0)
angleCFrame = angleCFrame and angleCFrame:Lerp(rotationCFrame, 0.15) or rotationCFrame
local finalCFrame = positionCFrame * angleCFrame
self.Tower:PivotTo(finalCFrame)
towerRaycast = finalCFrame
elseif not towerBeingPlace then
self.TowerConnection:Disconnect()
self.TowerConnection = nil
self.Tower:Destroy()
towerRaycast = nil
end
end)
TowerHandler:InitializeProperties(self)
return setmetatable(self, TowerHandler)
end
function TowerHandler:InitializeProperties(main)
UiHandler.InitializeGUI(player, main.UIPart, main.UIPart.SurfaceGui)
local properties = require(main.Tower:WaitForChild("Properties"))
if properties then
properties(main.Tower)
end
end
function TowerHandler:InitializeRotation()
rotationAngle = (rotationAngle - 90) % 360
end
function TowerHandler:InitializeClick()
print(self.Tower)
placeTowerRemote:FireServer(towerRaycast, placeHolderTower)
end
function TowerHandler:End()
towerBeingPlace = false
rotationAngle = 0
angleCFrame = nil
placeHolderTower = nil
setmetatable(self, nil)
end
return TowerHandler
self.Tower is printing nil? I’m not sure why. Self is considered nil outside of the TowerHandler.InitializePlacement constructor.