Why isn't my Object showing up because of Math.Clamp

  1. What I originally and still is to make it so you can only place your object on the plot to ensure they can’t cheat and get more room to place objects. I am trying math.clamp but then my object doesn’t see to show up and when I place it, it is not on the plot its somewhere else in my game.

  2. The issue is that I don’t know how to make it so the Object is on the plot there. I added a print and it seemed to make a cframe of the plot and I think that’s the problem or could help find a solution. I think now I need to make the Object move to my mouse.hit but relative to the plot’s frame but I don’t know how to do that as I’m not familiar with CFrame.

My Script:

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(
		math.clamp( Round( vector3.X, Grid ), Plot.Position.X - 20, Plot.Position.X + 20),
		Round(vector3.Y, 0),
		math.clamp( Round( vector3.Z, Grid ), Plot.Position.Z - 20, Plot.Position.Z + 20),
		print(vector3)
	)
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)

Help is needed since I want to release my game so if you know a solution or have an idea let me know!

I want to help you, but the code is quite long, try shortening it to some parts that may be vital points to the problem. This might be why no one has replied yet.

If anyone asks for more code later, don’t hesitate to show them :slight_smile: (If you decide to shorten it.)

1 Like

This won’t help you with your placement system, but I strongly encourage you to clean up your code.

Having code that looks like this is not the best especially in the long run.