Why is my part changing rotation when placed with my placing script?

  1. I want my script to place down the object / model on the server side when the client clicks.

  2. The issue is that when placed the model is turned 90 degrees the other way from what the Rot or Rotation value is. I know all the models are orientated to (0,0,0)

Client 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 UIS = game:GetService("UserInputService")
local Grid = 2
local Rot = 0

local PosX
local PosY
local PosZ
local Plot
local plotName
local PlotO
local PlotX
local PlotY
local PlotZ
local Object

local GivenPlot = game.ReplicatedStorage.BuildEvents.GivenPlot
local PlaceObject = game.ReplicatedStorage.BuildEvents.PlaceObject
GivenPlot.OnClientEvent:Connect(function(plt)
	Plot = plt
	plotName = plt.Name
	PlotO = plt.Orientation
	PlotX = PlotO.X
	PlotY = PlotO.Y
	PlotZ = PlotO.Z
end)

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, PlotY, 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))
	end
end
--TAKE THIS PART OUT FOR RELEASE
BuildMode = true

local function rotation(input, GPE)
	if Placing and CanPlace and not CanStart and input.KeyCode == Enum.KeyCode.R 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)

Server Script

local PlaceObject = game.ReplicatedStorage.BuildEvents.PlaceObject

local function PlaceObjectServer(player, Obj, PX, PY, PZ, Rot, Plt)
	local Object = game.ReplicatedStorage.BuildObjects:FindFirstChild(Obj):Clone()
	Object:SetPrimaryPartCFrame(CFrame.new(PX, PY, PZ) * CFrame.Angles(0, math.rad(Rot), 0))
	Object.Parent = Plt
end

PlaceObject.OnServerEvent:Connect(PlaceObjectServer)

Hey TestUser4646!

I’m not too sure what’s causing this specifically, although I see a few inconsistencies that might be altering how the client and server perceive your variable “Rot”.

However none of that matters because this can be quickly fixed with a simple bodge!

Change this line of code in your server script:

Object:SetPrimaryPartCFrame(CFrame.new(PX, PY, PZ) * CFrame.Angles(0, math.rad(Rot), 0))

to instead be:

Object:SetPrimaryPartCFrame(CFrame.new(PX, PY, PZ) * CFrame.Angles(0, math.rad(Rot - 90), 0))

This will set it back 90 degrees so that the offset that appears in the difference between client to server communication is corrected!

Hope this helped!

Thanks… I actually just fixed it myself right now but I really appreciate that you tried to help and sorry if that wasted your time. But thanks