algorembrant's picture
Upload 88 files
0712d5f verified
-- src/StarterPlayer/StarterCharacterScripts/BuildController.client.lua
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local BuildingConfig = require(ReplicatedStorage:WaitForChild("Shared"):WaitForChild("BuildingConfig"))
local PlaceBlueprintEvent = ReplicatedStorage:WaitForChild("Events"):WaitForChild("PlaceBlueprintEvent")
local player = Players.LocalPlayer
local mouse = player:GetMouse()
local character = player.Character or player.CharacterAdded:Wait()
local buildModeActive = false
local currentStructureIndex = 1
local currentStructure = BuildingConfig.StructureOrder[1]
local currentRotation = 0
local previewModel = nil
local function snapToGrid(position, gridSize)
return Vector3.new(
math.floor((position.X + gridSize/2) / gridSize) * gridSize,
position.Y,
math.floor((position.Z + gridSize/2) / gridSize) * gridSize
)
end
local function getStructureSize()
local config = BuildingConfig.Structures[currentStructure]
if config and config.Size then
return config.Size
end
return Vector3.new(10, 10, 1)
end
local function cleanupPreview()
if previewModel then
previewModel:Destroy()
previewModel = nil
end
end
local function createPreview()
cleanupPreview()
local size = getStructureSize()
previewModel = Instance.new("Part")
previewModel.Size = size
previewModel.Transparency = 0.5
previewModel.BrickColor = BrickColor.new("Neon blue")
previewModel.CanCollide = false
previewModel.Anchored = true
previewModel.Material = Enum.Material.ForceField
previewModel.Parent = workspace.Terrain
-- Add label
local billboard = Instance.new("BillboardGui")
billboard.Size = UDim2.new(0, 200, 0, 50)
billboard.StudsOffset = Vector3.new(0, size.Y/2 + 2, 0)
billboard.AlwaysOnTop = true
billboard.Parent = previewModel
local label = Instance.new("TextLabel")
label.Name = "StructureLabel"
label.Size = UDim2.new(1, 0, 1, 0)
label.BackgroundTransparency = 0.3
label.BackgroundColor3 = Color3.new(0, 0, 0)
label.TextColor3 = Color3.new(1, 1, 1)
label.TextScaled = true
label.Font = Enum.Font.GothamBold
local config = BuildingConfig.Structures[currentStructure]
label.Text = (config and config.Name or currentStructure) .. " [Q] Cycle [R] Rotate"
label.Parent = billboard
end
local function toggleBuildMode()
buildModeActive = not buildModeActive
if not buildModeActive then
cleanupPreview()
else
createPreview()
end
end
local function cycleStructure()
currentStructureIndex = currentStructureIndex + 1
if currentStructureIndex > #BuildingConfig.StructureOrder then
currentStructureIndex = 1
end
currentStructure = BuildingConfig.StructureOrder[currentStructureIndex]
if buildModeActive then
createPreview()
end
end
local function updatePreview()
if not buildModeActive or not previewModel then return end
local char = player.Character
if char and char:FindFirstChild("HumanoidRootPart") then
local distance = (char.HumanoidRootPart.Position - mouse.Hit.Position).Magnitude
if distance <= BuildingConfig.MaxPlacementDistance then
local snappedPos = snapToGrid(mouse.Hit.Position, BuildingConfig.GridSnap)
snappedPos = Vector3.new(snappedPos.X, mouse.Hit.Position.Y + (previewModel.Size.Y / 2), snappedPos.Z)
previewModel.CFrame = CFrame.new(snappedPos) * CFrame.Angles(0, math.rad(currentRotation), 0)
previewModel.BrickColor = BrickColor.new("Neon blue")
else
previewModel.Position = mouse.Hit.Position
previewModel.BrickColor = BrickColor.new("Really red")
end
end
end
local function onInputBegan(input, gameProcessed)
if gameProcessed then return end
if input.KeyCode == Enum.KeyCode.B then
toggleBuildMode()
end
if input.KeyCode == Enum.KeyCode.Q and buildModeActive then
cycleStructure()
end
if input.KeyCode == Enum.KeyCode.R and buildModeActive then
currentRotation = (currentRotation + 90) % 360
end
if input.UserInputType == Enum.UserInputType.MouseButton1 and buildModeActive then
if previewModel and previewModel.BrickColor.Name == "Neon blue" then
PlaceBlueprintEvent:FireServer(currentStructure, previewModel.CFrame)
end
end
end
player.CharacterAdded:Connect(function(char)
character = char
end)
UserInputService.InputBegan:Connect(onInputBegan)
RunService.RenderStepped:Connect(function()
if buildModeActive then
updatePreview()
end
end)