I’m making a fortnite building system and I cannot figure out how to make a “gravity” system
I followed this tutorial: Creating A Fortnite Building - Tutorial for Intermediate Developers
Server Script:
local RS = game:GetService("ReplicatedStorage")
local RemoteEvents = RS.RemoteEvents
local PlaceBuildEvent = RemoteEvents:WaitForChild("PlaceBuild")
PlaceBuildEvent.OnServerEvent:Connect(function(Player, BuildName, BuildPosition, BuildRotation)
local BuildComponent = script:FindFirstChild(BuildName)
if BuildComponent then
print("built")
BuildComponent = BuildComponent:Clone()
BuildComponent.Parent = workspace:FindFirstChild("Builds") or workspace
BuildComponent.Position = BuildPosition
BuildComponent.Orientation = BuildRotation
BuildComponent.Anchored = true
BuildComponent.CanCollide = true
end
end)
Module Script:
local BuildManager = {}
local ContextActionService = game:GetService("ContextActionService")
local RS = game:GetService("ReplicatedStorage")
local RemoteEvents = RS.RemoteEvents
local PlaceBuildEvent = RemoteEvents:WaitForChild("PlaceBuild")
BuildManager.GridSize = 16
BuildManager.BuildDistance = 10
BuildManager.isBuilding = false
BuildManager.SelectedBuild = "Wall"
local BuildingKeybinds = {
[Enum.KeyCode.Z] = "Wall",
[Enum.KeyCode.X] = "Floor",
[Enum.KeyCode.C] = "Ramp"
}
local function GridSnap(Value, Size)
return (math.floor(Value/Size + 0.5) * Size) -- Rounding down the Quotient of Value and Size + 0.5 then multiplying it by the size.
end
function BuildManager.GetNextBuildPosition(HumanoidRootPartPosition, MouseLookVector3)
local DirectionVector3 = MouseLookVector3 * BuildManager.BuildDistance
DirectionVector3 += HumanoidRootPartPosition
return Vector3.new(
GridSnap(DirectionVector3.X, BuildManager.GridSize),
GridSnap(DirectionVector3.Y, BuildManager.GridSize) + BuildManager.GridSize/2,
GridSnap(DirectionVector3.Z, BuildManager.GridSize)
)
end
function BuildManager.GetNextBuildRotation(Vector)
if(typeof(Vector) == "Vector3") then
local Y = math.atan2(Vector.X, Vector.Z)
return Vector3.new(0,GridSnap(Y, math.rad(-90)), 0)
end
end
function BuildManager.ToggleBuildMode(ActionName, InputState, InputObject)
if ActionName == "ToggleBuild" then
if InputState == Enum.UserInputState.Begin then
BuildManager.isBuilding = not BuildManager.isBuilding
warn("Toggled Build Mode: ", BuildManager.isBuilding)
end
end
end
function BuildManager.SwitchBuild(ActionName, InputState, InputObject)
if(ActionName == "SwitchBuild") then
if(InputState == Enum.UserInputState.Begin) then
BuildManager.isBuilding = true
if(BuildManager.isBuilding and BuildingKeybinds[InputObject.KeyCode]) then
BuildManager.SelectedBuild = BuildingKeybinds[InputObject.KeyCode]
end
end
end
end
local function GetTouchingParts(Part)
local Connection = Part.Touched:Connect(function() end)
local Results = Part:GetTouchingParts()
Connection:Disconnect()
return Results
end
function BuildManager.PlaceBuild(BuildMesh, BuildName)
if(BuildManager.isBuilding) then
local Results = GetTouchingParts(BuildMesh)
local Placeable = true
for _, Build in pairs(Results) do
if Build.Name == BuildMesh.Name then
if Build.Position == BuildMesh.Position then
Placeable = false
end
end
end
if(Placeable) then
PlaceBuildEvent:FireServer(BuildName, BuildMesh.Position, BuildMesh.Orientation)
end
end
end
return BuildManager
Local Script:
-- // SERVICES // --
local ContextActionService = game:GetService("ContextActionService")
local RunService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
-- // MODULES // --
local BuildManager = require(script:WaitForChild("BuildManager"))
-- // FOLDERS // --
local MeshesFolder = script.BuildMeshes
local PreviewFolder = MeshesFolder.Preview
-- // PLAYER // --
local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local HumanoidRootPart = char:WaitForChild("HumanoidRootPart")
local Mouse = plr:GetMouse()
-- // TABLES // --
local BuildingMeshes = {
["Wall"] = PreviewFolder:WaitForChild("Wall");
["Floor"] = PreviewFolder:WaitForChild("Floor");
["Ramp"] = PreviewFolder:WaitForChild("Ramp")
}
local CFrameAddOns = {
["Wall"] = CFrame.new(0,0,(BuildManager.GridSize/2));
["Floor"] = CFrame.new(Vector3.new(0,-BuildManager.GridSize/2,0));
["Ramp"] = CFrame.new(0,0,0);
}
local function ResetPreviewParents(Mesh)
for _,BuildMesh in pairs(BuildingMeshes) do
if BuildMesh ~= Mesh and BuildMesh.Parent ~= PreviewFolder then
BuildMesh.Parent = PreviewFolder
end
end
end
--|| ACTIONS ||--
ContextActionService:BindAction("SwitchBuild", BuildManager.SwitchBuild, true, Enum.KeyCode.Z, Enum.KeyCode.X, Enum.KeyCode.C) -- The KeyCodes for the keybinds
ContextActionService:BindAction("ToggleBuild", BuildManager.ToggleBuildMode, true, Enum.KeyCode.H)
--|| EVENTS ||--
UIS.InputBegan:Connect(function(InputObject, GameProcessed)
if GameProcessed then return end
if(InputObject.UserInputType == Enum.UserInputType.MouseButton1) then
BuildManager.PlaceBuild(BuildingMeshes[BuildManager.SelectedBuild], BuildManager.SelectedBuild)
end
end)
RunService.RenderStepped:Connect(function()
if(BuildManager.isBuilding) then
local BuildComponentPosition = BuildManager.GetNextBuildPosition(HumanoidRootPart.Position, Mouse.Hit.LookVector)
local BuildComponentRotation = BuildManager.GetNextBuildRotation(Mouse.Hit.LookVector)
local BuildComponent = BuildingMeshes[BuildManager.SelectedBuild]
ResetPreviewParents(BuildComponent)
BuildComponent.Parent = workspace:FindFirstChild("Builds") or workspace
BuildComponent.CFrame = CFrame.new(BuildComponentPosition) * CFrame.Angles(BuildComponentRotation.X,BuildComponentRotation.Y,BuildComponentRotation.Z) * CFrameAddOns[BuildManager.SelectedBuild]
else
ResetPreviewParents()
end
end)
Please help me I have been trying to do this for like 3 days.
(And yes before anyone asks I have tried learning from roblox’s battle royale game)