Tween works fine in studio, but moves to the wrong position in game

Hello! I created two big doors that tween open server sided. It works fine in studio, but once it’s published to Roblox, it breaks in game.

In studio: https://gyazo.com/c139a782bdc9ef09c3c0f702030eed84

In game: https://gyazo.com/d40b70b719311a4f5a4b80899fb994e2

they seem to fly to the world origin (0,0,0) so maybe there’s something wrong with the positions?

Here’s the code if there’s anything wrong with it

local clickdetector = script.Parent
local Players = game:GetService("Players")
local G = workspace.GateImportant
local N = workspace.GateNonImportant
local TweenService = game:GetService("TweenService")
local open = false
local Position1 = N.GatePosition1
local Position2 = N.GatePosition2

--Object variables
local Lock1 = G.Lock1
local Lock2 = G.Lock2
local Lock3 = G.Lock3
local Lock4 = G.Lock4
local Lock5 = G.Lock5
local Lock6 = G.Lock6

local Key = script.Parent.Parent.Key

local P1 = G.Particle1.ParticleEmitter
local P2 = G.Particle2.ParticleEmitter
local P3 = G.Particle3.ParticleEmitter
local P4 = G.Particle4.ParticleEmitter
local P5 = G.Particle5.ParticleEmitter
local P6 = G.Particle6.ParticleEmitter
local P7 = G.Particle7.ParticleEmitter
local P8 = G.Particle8.ParticleEmitter

local Gate1 = N.Gate1.Union
local Gate2 = N.Gate2

local BigGear1 = G.BigGear1
local BigGear2 = G.BigGear2
local SmallGear1 = G.SmallGear1
local SmallGear2 = G.SmallGear2

local RemoteEvent = game.ReplicatedStorage:WaitForChild("RemoteEvent")

--Audio
local A1 = script.Parent.Parent["Avalanche Deep Crumbling 9 (SFX)"]
local A2 = script.Parent.Parent["Pump Cycle Machine Mechanical Clunks Air Bur (SFX)"]
local A3 = script.Parent.Parent["Large Stone Door"]

--TweenStuff
local tweeninfo = TweenInfo.new(5, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0)
local Gatetweeninfo = TweenInfo.new(14, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0)

local goal1 = {}
goal1.Position = Vector3.new(-196.615, 193.703, 147.332)

local goal2 = {}
goal2.Position = Vector3.new(-347.474, 192.902, 147.332)

local goal3 = {}
goal3.Position = Vector3.new(-347.629, 114.302, 147.332)

local goal4 = {}
goal4.Position = Vector3.new(-196.17, 114.504, 147.332)

local goal5 = {}
goal5.Position = Vector3.new(-196.369, 46.783, 147.332)

local goal6 = {}
goal6.Position = Vector3.new(-347.249, 46.582, 147.332)

local GateGoal1 = {}
GateGoal1.Position = Position2.Position
GateGoal1.CFrame = CFrame.Angles(0, 89.253, 0)

local GateGoal2 = {}
GateGoal2.Position = Position1.Position
GateGoal2.CFrame = CFrame.Angles(0, -89.253, 0)

--0, -120.012, 0

local LockTween1 = TweenService:Create(Lock1, tweeninfo, goal1)
local LockTween2 = TweenService:Create(Lock2, tweeninfo, goal2)
local LockTween3 = TweenService:Create(Lock3, tweeninfo, goal3)
local LockTween4 = TweenService:Create(Lock4, tweeninfo, goal4)
local LockTween5 = TweenService:Create(Lock5, tweeninfo, goal5)
local LockTween6 = TweenService:Create(Lock6, tweeninfo, goal6)

local GateTween1 = TweenService:Create(Gate1, Gatetweeninfo, GateGoal1)
local GateTween2 = TweenService:Create(Gate2, Gatetweeninfo, GateGoal2)

local function OnClicked(player)
	A2:Play()
	Key.Transparency = 0
	for i = 1, 106 do
		task.wait(0.02)
		BigGear1.Part.CFrame *= CFrame.Angles(0, 0, 0.02)
		BigGear1.Hexagon1.CFrame *= CFrame.Angles(0, -0.02, 0)
		BigGear1.Hexagon.CFrame *= CFrame.Angles(0, -0.02, 0)
		BigGear2.Part.CFrame *= CFrame.Angles(0,0, -0.02)
		BigGear2.Hexagon1.CFrame *= CFrame.Angles(0, 0.02, 0)
		BigGear2.Hexagon.CFrame *= CFrame.Angles(0, 0.02, 0)
		SmallGear1.CFrame *= CFrame.Angles(0,0,-0.02)
		SmallGear2.CFrame *= CFrame.Angles(0,0,0.02)
	end
	
	A1:Play()
	wait(2)
	RemoteEvent:FireAllClients(player)
	LockTween1:Play()
	LockTween2:Play()
	LockTween3:Play()
	LockTween4:Play()
	LockTween5:Play()
	LockTween6:Play()
	P1.Enabled = true
	P2.Enabled = true
	P3.Enabled = true
	P4.Enabled = true
	P5.Enabled = true
	P6.Enabled = true
	wait(5)
	P1.Enabled = false
	P2.Enabled = false
	P3.Enabled = false
	P4.Enabled = false
	P5.Enabled = false
	P6.Enabled = false
	wait(2)
	A3:Play()
	P7.Enabled = true
	P8.Enabled = true
	GateTween1:Play()
	GateTween2:Play()
	wait(14)
	P7.Enabled = false
	P8.Enabled = false
end

clickdetector.MouseClick:Connect(function()
	for _, player in Players:GetPlayers() do
		if open == false then
			open = true
			OnClicked()
		end
	end
	
end)

Can you please provide the code you are using?

Are you 100% sure that it was published?

It looks like the tween is working, but the final position is set to something other than what it should be

Just posted the code, 100% sure it was published

I do realize the code is a bit messy

Okay so I was able to reproduce the problem in studio by changing the position to CFrame instead, so MAYBE a similar thing is happening in game, though that’s my only lead thus far.

Please, someone smarter than me help me out here

Unrelated but you should probably check it

Not related but you can clean your code up using tables and for loops. For example, you can change this

local Lock1 = G.Lock1
local Lock2 = G.Lock2
local Lock3 = G.Lock3
local Lock4 = G.Lock4
local Lock5 = G.Lock5
local Lock6 = G.Lock6

into this

local LockTable = {
	[1] = G.Lock1,
	[2] = G.Lock2,
	[3] = G.Lock3,
	[4] = G.Lock4,
	[5] = G.Lock5,
	[6] = G.Lock6
}

You can also change this

local LockTween1 = TweenService:Create(Lock1, tweeninfo, goal1)
local LockTween2 = TweenService:Create(Lock2, tweeninfo, goal2)
local LockTween3 = TweenService:Create(Lock3, tweeninfo, goal3)
local LockTween4 = TweenService:Create(Lock4, tweeninfo, goal4)
local LockTween5 = TweenService:Create(Lock5, tweeninfo, goal5)
local LockTween6 = TweenService:Create(Lock6, tweeninfo, goal6)

into this

local LockTweens = {
	[1] = TweenService:Create(LockTable[1], tweeninfo, goal1),
	[2] = TweenService:Create(LockTable[2], tweeninfo, goal2),
	[3] = TweenService:Create(LockTable[3], tweeninfo, goal3),
	[4] = TweenService:Create(LockTable[4], tweeninfo, goal4),
	[5] = TweenService:Create(LockTable[5], tweeninfo, goal5),
	[6] = TweenService:Create(LockTable[6], tweeninfo, goal6),
}

which would allow you to replace this

	LockTween1:Play()
	LockTween2:Play()
	LockTween3:Play()
	LockTween4:Play()
	LockTween5:Play()
	LockTween6:Play()

with a for loop

for _,tween in LockTweens do
	tween:Play()
end

Makes your code easier to look at.

I would advise you not to do this

	for i = 1, 106 do
		task.wait(0.02)
		BigGear1.Part.CFrame *= CFrame.Angles(0, 0, 0.02)
		BigGear1.Hexagon1.CFrame *= CFrame.Angles(0, -0.02, 0)
		BigGear1.Hexagon.CFrame *= CFrame.Angles(0, -0.02, 0)
		BigGear2.Part.CFrame *= CFrame.Angles(0,0, -0.02)
		BigGear2.Hexagon1.CFrame *= CFrame.Angles(0, 0.02, 0)
		BigGear2.Hexagon.CFrame *= CFrame.Angles(0, 0.02, 0)
		SmallGear1.CFrame *= CFrame.Angles(0,0,-0.02)
		SmallGear2.CFrame *= CFrame.Angles(0,0,0.02)
	end

Calculating CFrame can be a bit taxing on the server which could cause lag, though it seems you’re only doing this once so its fine I guess. Nonetheless, there are easier ways of doing, one would just be welding all the parts to one part and tweening the angle of that part. Or just use Model:PivotTo(CFrame.Angles(your angle)) just make sure to set a primarypart

Well it seems to me that you’re tweening the position, I’m not too sure why its tweening the position since you have it tweening the angles first, though it could be code that you updated which causes the video to technically be wrong.

Do the gates spawn in a different position during the game, or are they there all the time?

How about this?

local GateGoal1 = {}
GateGoal1.Position = Position2.Position      -- shouldn't this be Position1?
GateGoal1.CFrame = CFrame.Angles(0, 89.253, 0)

local GateGoal2 = {}
GateGoal2.Position = Position1.Position      -- and this be Position2?
GateGoal2.CFrame = CFrame.Angles(0, -89.253, 0)

-- try this to see if it throws you weird numbers for the positions in the Output window:
print("GateGoal1.Position = ", GateGoal1.Position, "     GateGoal2.Position = ", GateGoal2.Position)

After lots of testing, it seems the CFrame goal is causing the weirdness. If it’s removed, it goes to the correct position in game.

I’ll try to find some alternative to get the tween to do what I want.

When you used my print suggestion were you getting different values in the Positions?

What are the references:

local Position1 = N.GatePosition1
local Position2 = N.GatePosition2

N.GatePosition1 isn’t a valid reference to a Roblox item and you haven’t set a variable up that way.

“N” refers to a folder

the print returned the correct position

the reason for the position1 and position2 being in reversed positions was just incorrect naming and me choosing the lazy option instead of renaming

I was able to fix it through changing the rotation with vector3 instead of CFrame

1 Like