File size: 4,614 Bytes
0712d5f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | -- 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)
|