I can't tween a part's position while it is rotating

Server Script: Responsible for moving water up

local function MoveWater(part, info, translation) -- fe2 ripoff but u can spin the lava
	if part:IsA("BasePart") then
		TS:Create(part, info, {Position = part.Position + Vector3.new(0, translation, 0)}):Play()
	end
end

MoveWater(Lava2, TweenInfo.new(14.7), 20)

Local Script: Responsible for spinning

spawn(function()
	while task.wait() do
		if Lava2.Texture.Transparency == 1 then
			break
		end
		Lava2.CFrame = Lava2.CFrame * CFrame.Angles(0, -0.002, 0)
	end
end)

When the MoveWater() function is called, the water starts moving up but stops spinning. Is there a way to make it so that the water moves up but still spins while moving up?

2 Likes

I see that the server script is only editing the Position property, so maybe the client script could edit just the Orientation property? Editing the CFrame (which would affect position AND orientation) might be causing the different changes to be fighting each other. I have not been able to test this myself, so here’s another post with some other solutions you might be able to try in case mine fails: Make Parts Keep Rotating While Moving Up and Down - #2 by 7z99

1 Like

Changing the orientation instead doesn’t seem to work. As for the post you provided, I don’t understand a single thing in it and can’t figure out how to change the speed of the rotation or the part’s position ;-;

you can use linear interpolation for this, it’s the same as tween but more mathematical, you can use math to make effects ect. Here is better explanation: What is the :lerp function?

Can you use this in a local script?

1 Like

For the solution post of this link, how would you move the part up, and how would I implement it into the MoveWater function?

1 Like

Well, I actually figured out something less complicated than the solutions in that link.

On the server, instead of tweening the part, I tween the value of a CFrameValue instance. I then just have the client script read that value to determine the part’s Y position then add the rotation. The part’s CFrame never changes on the server, but .Touched connections in server scripts can still work because those events are managed by clients.

--// SERVER SCRIPT
local ts = game:GetService("TweenService")

ts:Create(
	workspace.SpinPart.CFrameValue,
	TweenInfo.new(4,Enum.EasingStyle.Sine,Enum.EasingDirection.InOut,-1,true,0),
	{Value = CFrame.new(0,10,0)}
):Play()

--// CLIENT SCRIPT (cannot be in StarterGui or else the script will reset when the player respawns)
local rs = game:GetService("RunService")
local Part = workspace:WaitForChild("SpinPart")

local StartCFrame = Part.CFrame
local Rotation = CFrame.Angles(0,0,0)

rs.RenderStepped:Connect(function(dt)
	Rotation *= CFrame.Angles(0,math.rad(90 * dt),0) --// Update rotation; x in x * dt equals the number of degrees to rotate in a second
	Part.CFrame = StartCFrame * Part.CFrameValue.Value * Rotation
end)

Here’s a video of the outcome:

1 Like

It spins while moving up! However, the part seems to go down at some point even though there isn’t anything in the script that should make it go down.

local function MoveWater(part, info, translation)
	if part:IsA("BasePart") then
		TS:Create(part.CFrameValue, info ,{Value = CFrame.new(0, translation, 0)}):Play()
	end
end

task.wait(0.9)
MoveWater(Lava2, TweenInfo.new(14.7), 20) -- works fine i think?
MovePart(game.Workspace._FirstDoor, TweenInfo.new(15), Vector3.new(0, 130, 0))
task.wait(12.7)
TS:Create(Lava2.Texture, TweenInfo.new(2), {Transparency = 0.9}):Play()
task.wait(2)
TS:Create(Lava2.Texture, TweenInfo.new(0.7), {Transparency = 0}):Play()
MoveWater(Lava2, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out), 30) -- it goes up but not the full 30 studs
task.wait(1)
MoveWater(Lava2, TweenInfo.new(26.3), 70) -- it goes up but doesn't even come close to 70 studs
task.wait(24.3)
TS:Create(Lava2.Texture, TweenInfo.new(2), {Transparency = 1}):Play()
task.wait(2)
-- 113s
Lava2.Texture.Transparency = 1
Lava2.Orientation = Vector3.new(0, -120, 0)
Lava2.Size = Vector3.new(264.49, 94.1, 350)
TS:Create(Lava2.Texture, TweenInfo.new(0.7), {Transparency = 0}):Play()
MoveWater(Lava2, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out), 50) -- it goes down here instead of up
game.Workspace.FinalPart.Value = true

Ooh I know what’s happening. So, the Y value of CFrameValue.Value starts at 0, then becomes 20 with the first MoveWater(). The later calls don’t work because the functions sets Y to translation instead of adding/subtracting translation from Y like you want. That said, the second MoveWater() changes the Y value to 30 instead of 50 like you want. Fortunately, the fix should be as simple as this:

local TargetY = 0 --// Don't change this
local function MoveWater(part, info, translation)
	TargetY += translation
	if part:IsA("BasePart") then
		TS:Create(part.CFrameValue, info ,{Value = CFrame.new(0, TargetY, 0)}):Play()
	end
end
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.