Hey all!
I am trying to create a grid building system for my game, and I thought I was being smart here.
The idea is to check if the mouse has moved 4 studs before moving the “temporary” object, which does work, however it’s not like the snap-to-grid type system that I was hoping for and only realized after I started placing objects down.
Here is what it currently looks like
As you can see they are not exactly on the “grid” per se and are all over the place.
Here is my code
(p.s please do not do a code review on it, I know the code isn’t clean, doesn’t look good and probably doesn’t use best practices. I am cleaning it up as I go, I am just trying to make a simple system as of right now to get a working prototype out.)
local ContextAction = game:GetService("ContextActionService")
local Run = game:GetService("RunService")
if Run:IsClient() == false then error("This module should only be run on the client!") end
local Workspace = game:GetService("Workspace")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
--/ Settings
local SETTINGS = {
Interpolation = true,
MoveByGrid = true,
BuildModePlacement = true,
RotationStep = 90,
MaxHeight = 90,
LerpSpeed = 0.7
}
local Placement = {}
Placement.__index = Placement
-- / Constructor
function Placement.init()
local self = {
GRID_SIZE = 4,
ITEM_LOCATION = nil,
ROTATE_KEY = nil,
TERMINATE_KEY = nil,
BUILDING_ACTIVE = false,
SELECTED_BUILDING = nil,
MousePos = Vector3.new(0,0,0),
LastMousePos = Vector3.new(0,0,0)
}
self.StartBuildAction = ContextAction:BindAction("BuildToggle", function(action, userinputstate, inputobject)
if action == "BuildToggle" and userinputstate == Enum.UserInputState.End then
self.BUILDING_ACTIVE = not self.BUILDING_ACTIVE
print("Building Active: ", self.BUILDING_ACTIVE)
end
end, false, Enum.KeyCode.B)
self.RunService = Run.PreRender:Connect(function()
if self.BUILDING_ACTIVE == false then
if self.SELECTED_BUILDING ~= nil then
self.SELECTED_BUILDING:Destroy()
self.SELECTED_BUILDING = nil
end
return
end
if self.SELECTED_BUILDING == nil then
self.SELECTED_BUILDING = self:GetPlacementObject("BasicConveyer")
self.SELECTED_BUILDING.Parent = game.Workspace
self:CreateHighlight(self.SELECTED_BUILDING)
self.LastMousePos = self.MousePos
self.SELECTED_BUILDING:PivotTo(CFrame.new(self.MousePos))
end
if (self.MousePos - self.LastMousePos).Magnitude >= 4 then
self.LastMousePos = self.MousePos
self.SELECTED_BUILDING:PivotTo(CFrame.new(self.MousePos))
end
end)
self.MouseMoveConnect = Mouse.Move:Connect(function()
Mouse.TargetFilter = self.SELECTED_BUILDING
self.MousePos = Mouse.Hit.Position --+ Vector3.new(0,0.5,0)
end)
self.MouseClick = Mouse.Button1Down:Connect(function()
local obj = self:GetPlacementObject(self.SELECTED_BUILDING.Name)
obj.Parent = game.Workspace
obj:PivotTo(self.SELECTED_BUILDING.PrimaryPart.CFrame)
end)
return setmetatable(self, Placement)
end
function Placement:GetPlacementObject(id: string)
local Builds = ReplicatedStorage:FindFirstChild("Builds")
local SelectedObject = Builds:FindFirstChild(id, true)
return SelectedObject:Clone()
end
function Placement:CreateHighlight(model: Model)
if self.BuildingHighlight then
self:DeleteHighlight()
end
self.BuildingHighlight = Instance.new("Highlight") :: Highlight
self.BuildingHighlight.Adornee = model
self.BuildingHighlight.FillColor = Color3.new(0.152941, 0.505882, 0.0470588)
self.BuildingHighlight.OutlineColor = Color3.new(1,1,1)
self.BuildingHighlight.FillTransparency = 0.5
self.BuildingHighlight.Enabled = true
self.BuildingHighlight.DepthMode = Enum.HighlightDepthMode.Occluded
self.BuildingHighlight.OutlineTransparency = 0
self.BuildingHighlight.Parent = model
end
function Placement:DeleteHighlight()
self.BuildingHighlight:Destroy()
self.BuildingHighlight = nil
end
return Placement
AGAIN FOR CLARIFICATION, THIS IS NOT A CODE REVIEW REQUEST, I JUST NEED MY SYSTEM FIXED RIGHT NOW