So my goal was and still is to make a plot building system. I have finished the movement feature of this system but my problem is the player is supposed to be only able to place things on their plot but they are still able to place objects off there plot slightly just because I used a mouse.Target which is very inaccurate. So someone (a lot of people on the forum told me to use math.Clamp but I can’t figure how to use it and how to find the plot’s CFrame to do this. So here’s my script so you could maybe help find out how to incorporate a mouse.Clamp. I already know it needs to be in the SnapToGrid Function but I still don’t know what the forum members wanted me to try so I hope you can help:
local Player = game.Players.LocalPlayer
local Mouse = Player:GetMouse()
local Camera = game.Workspace.CurrentCamera
local BuildPro = false
local OnPlot = false
local BuildUi = script.Parent.FHOS.Frame.BuildFrame
local MarketPlaceService = game:GetService("MarketplaceService")
local RunService = game:GetService("RunService")
game.Players.PlayerAdded:Connect(function()
local hasPass = false
local success, message = pcall(function()
hasPass = MarketPlaceService:UserOwnsGamePassAsync(Player.UserId, 11321181)
end)
if not success then
warn("Error while checking if player has pass: " .. tostring(message))
return
end
if hasPass == true then
BuildPro = true
end
end)
local Grid = 2
local PosX
local PosY
local PosZ
local Plot
local plotName
local Object
local GivenPlot = game.ReplicatedStorage.BuildEvents.GivenPlot
local PlaceObject = game.ReplicatedStorage.BuildEvents.PlaceObject
GivenPlot.OnClientEvent:Connect(function(plt)
Plot = plt
plotName = plt.Name
end)
local Rot = Plot.Orientation.Y
Plot.Touched:Connect(function(hit)
local plr = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
if plr then
OnPlot = true
end
end)
Plot.TouchEnded:Connect(function(hit)
local plr = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
end)
local CanStart = true
local Placing = nil
local CanPlace = nil
local MoveObject = false
local CanPlace
local BuildMode = Instance.new("BoolValue")
BuildMode.Parent = Player
BuildMode = false
BuildSelection = BuildUi.ScrollingFrame
Soil = BuildSelection.SoilSelect.ImageButton
StartBarn = BuildSelection.StartBarnSelect.ImageButton
Tent = BuildSelection.TentSelect.ImageButton
HayBale = BuildSelection.HayBaleSelect.ImageButton
Log = BuildSelection.LogSelect.ImageButton
GreenScreen = BuildSelection.GreenScreenSelect.ImageButton
Flag = BuildSelection.FlagSelect.ImageButton
SmallDeck = BuildSelection.SmallDeck.ImageButton
DeckStairs = BuildSelection.DeckStairs.ImageButton
LargeDeck = BuildSelection.LargeDeck.ImageButton
Chair = BuildSelection.Chair.ImageButton
Bed = BuildSelection.Bed.ImageButton
TallBillboard = BuildSelection.TallBillboard.ImageButton
ShortBillboard = BuildSelection.ShortBillboard.ImageButton
Table = BuildSelection.Table.ImageButton
CampFire = BuildSelection.CampFire.ImageButton
script.Parent.FHOS.Frame.Frame.BuildModeApp.TextButton.MouseButton1Click:Connect(function()
script.Parent.FHOS.Frame.Frame.Visible = false
script.Parent.FHOS.Frame.FhBrand.Visible = false
script.Parent.FHOS.Frame.Power.Visible = false
script.Parent.FHOS.Frame.Time.Visible = false
script.Parent.FHOS.Frame.Network.Visible = false
script.Parent.FHOS.Frame.Battery.Visible = false
script.Parent.FHOS:TweenPosition(UDim2.new(0.105, 0,0.485, 0), "Out", "Linear", 1, false, nil)
while script.Parent.FHOS.Rotation > -90 do
script.Parent.FHOS.Rotation = script.Parent.FHOS.Rotation - 1
wait()
end
BuildMode = true
if BuildMode == true and OnPlot == true or BuildPro == true then
Camera.CameraSubject = Plot
end
end)
local function Round(n, to)
local to = to or 1
if to == 0 then return n end
return math.floor(n/to + 0.5) * to
end
local function SnapToGrid(vector3)
return Vector3.new(
Round(vector3.X, Grid),
Round(vector3.Y, 0),
Round(vector3.Z, Grid)
)
end
local function CloneService(Obj)
if CanStart == true and not CanPlace and not Placing then
Object = game.ReplicatedStorage.BuildObjects:FindFirstChild(Obj):Clone()
Object.Parent = game.Workspace
Mouse.TargetFilter = Object
Object.PrimaryPart.Orientation = Vector3.new(0, Object.PrimaryPart.Orientation.Y, 0)
CanStart = false
CanPlace = true
Placing = true
end
end
Soil.MouseButton1Click:Connect(function()
CloneService("Soil")
MoveObject = true
end)
StartBarn.MouseButton1Click:Connect(function()
CloneService("StarterBarn")
MoveObject = true
end)
Tent.MouseButton1Click:Connect(function()
CloneService("Tent")
MoveObject = true
end)
HayBale.MouseButton1Click:Connect(function()
CloneService("Haybale")
MoveObject = true
end)
Log.MouseButton1Click:Connect(function()
CloneService("Log")
MoveObject = true
end)
GreenScreen.MouseButton1Click:Connect(function()
CloneService("GreenScreen")
MoveObject = true
end)
Flag.MouseButton1Click:Connect(function()
CloneService("Flag")
MoveObject = true
end)
SmallDeck.MouseButton1Click:Connect(function()
CloneService("SmallDeck")
MoveObject = true
end)
DeckStairs.MouseButton1Click:Connect(function()
CloneService("DeckStairs")
MoveObject = true
end)
LargeDeck.MouseButton1Click:Connect(function()
CloneService("LargeDeck")
MoveObject = true
end)
Chair.MouseButton1Click:Connect(function()
CloneService("Chair")
MoveObject = true
end)
Bed.MouseButton1Click:Connect(function()
CloneService("Bed")
MoveObject = true
end)
TallBillboard.MouseButton1Click:Connect(function()
CloneService("TallBillboard")
MoveObject = true
end)
ShortBillboard.MouseButton1Click:Connect(function()
CloneService("ShortBillboard")
MoveObject = true
end)
Table.MouseButton1Click:Connect(function()
CloneService("Table")
MoveObject = true
end)
CampFire.MouseButton1Click:Connect(function()
CloneService("Campfire")
MoveObject = true
end)
local function Place()
if Placing and CanPlace then
PosX = Object.PrimaryPart.Position.X
PosY = Object.PrimaryPart.Position.Y
PosZ = Object.PrimaryPart.Position.Z
PlaceObject:FireServer(Object.Name, PosX, PosY, PosZ, Rot, Plot)
Placing = false
CanPlace = false
CanStart = true
Object:Destroy()
end
end
local function GetMousePlacementCFrame(Plot, Object)
local objectOffset = Vector3.new(0, Object.PrimaryPart.Size.Y/2, 0)
local mouseHit = Mouse.Hit
local mouseHitRelative = Plot.CFrame:ToObjectSpace(mouseHit) + objectOffset
local mouseHitRelativeSnapped = CFrame.new( SnapToGrid(mouseHitRelative.p))
local mouseHitWorldSnapped = Plot.CFrame * mouseHitRelativeSnapped
return mouseHitWorldSnapped
end
local function updateModelPlacement()
if Plot and (not Plot:IsDescendantOf(Object)) and Mouse.Target.Name == plotName then
Object:SetPrimaryPartCFrame(GetMousePlacementCFrame(Plot, Object)*CFrame.Angles(0,math.rad(Rot),0))
Object.PrimaryPart.Orientation = Vector3.new(0, Rot, 0)
end
end
--TAKE THIS PART OUT FOR RELEASE
BuildMode = true
game:GetService("UserInputService").InputBegan:Connect(function(input, GPE)
if input.KeyCode == Enum.KeyCode.R and Placing == true and CanPlace == true then
Rot = Rot + 45
Object:SetPrimaryPartCFrame(Object.PrimaryPart.CFrame * CFrame.Angles(0, math.rad(Rot), 0))
end
end)
RunService.RenderStepped:Connect(function()
Mouse.TargetFilter = Object
if Placing == true and CanPlace == true and not CanStart then
Plot.Texture.Transparency = 0
updateModelPlacement()
end
end)
Mouse.Button1Down:Connect(Place)