Is there a way to tween a CFrame's orientation without changing the position?

Just to make it clear what I mean: I do NOT mean CFrame = part.CFrame * CFrame.Angles

Imagine a part is already moving/being tweened, is there a way to make a 2nd tween that changes purely the part’s orientation through cframes without changing the position or am I forced to tween purely the orientation without cframes? Because if you try to tween with CFrame =part.CFrame * CFrame.Angles while the part is moving then it’ll constantly try to stick to one position and it starts glitching out

maybe?



local position = part.Position
local targetRotation = CFrame.Angles(math.rad(x), math.rad(y), math.rad(z))
local goalCFrame = CFrame.new(position) * targetRotation

Already tried that solution from a different forum, doesnt work (basically for the same reason as ive said in the message)

what about this:

local part = workspace.Part
part.CFrame *= CFrame.Angles(math.rad(90), 0, 0)

That’s literally what I wrote in my post :sob:

2 Likes

ok sorry i didn’t read past the title. but you can’t really do what you’re describing with tweens. you’re going to have to use a heartbeat loop or a while loop to update the cframe

1 Like

Just combine your goal CFrame with your orientation CFrame.

local TweenService = game:GetService("TweenService")
local part = [yourPart]
local goalPart = [yourGoalPart]

local goalPosition = goalPart.Position
local xRot, yRot, zRot = part.CFrame:ToOrientation()

local moveAndRotate = TweenService:Create(
part,
TweenInfo.new(5),
{CFrame = CFrame.new(goalPosition) * CFrame.Angles(xRot, math.rad(90), zRot)}
)

moveAndRotate:Play()
1 Like

The point is that the part is already moving by the time you’re doing the second tween, that’s why Im asking the question in the first place

So you don’t want to rotate the part in the initial moving tween, you want to rotate the part during the moving tween?

Yup

CharacterlimitCharacterlimitCharacterlimitCharacterlimit

Sorry for the long wait!! I had to do some testing with this. Here’s how you can pull it off:

local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")

local part = [yourPart]
local tweenConnection : RBXScriptConnection = nil

-- create the values --
local rotationValue = Instance.new("CFrameValue"); rotationValue.Parent = script
local x, y, z = part.CFrame:ToOrientation(); rotationValue.Value = CFrame.Angles(x, y, z)
-- pretty self explanatory, set the value to the current orientation

local positionValue = Instance.new("Vector3Value"); positionValue.Parent = script
positionValue.Value = part.Position
-- also pretty self explanatory, set the value to the current position

-- our goals --
local goalPosition = [yourGoalPosition]
local goalRotation = CFrame.Angles(0, math.rad(90), 0)

-- tweens --
local positionTween = TweenService:Create(
	positionValue,
	TweenInfo.new(10),
	{Value = goalPosition}
)

local rotationTween = TweenService:Create(
	rotationValue,
	TweenInfo.new(5),
	{Value = goalRotation}
)

positionTween:Play()

tweenConnection = RunService.Heartbeat:Connect(function()
	part.CFrame = CFrame.new(positionValue.Value) * rotationValue.Value
end)
-- here we set up a connection that will constantly calculate our orientation & position 
-- each heartbeat, preventing tween overlap which was your issue.
-- because [rotationValue.Value] is the part's current rotation at the time
-- of setting this up there's no jarring changes to the part's orientation.

task.wait(5)

rotationTween:Play()

positionTween.Completed:Once(function()
	if tweenConnection.Connected then
		tweenConnection:Disconnect()
	end
	tweenConnection = nil
end)
-- we stop listening for RunService.HeartBeat because the tween has ended.

This method supports EasingStyle and EasingDirection as well! Hope this works for you.

4 Likes

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