How to make an anchored part face the direction it's moving with CFrame

I have a part that’s moving in circles, and it’s working, but it isn’t facing the direction it’s going, the rotation is the same, and is always facing one way.
I tried replacing math.rad(rate) + math.rad(rate) with math.rad(number) or just simply number but it doesn’t work, it either spins really fast or really slow. I’m not that experienced with CFrame so I can’t really think of anything else that would make it work.

local number = 0 
	local rate = 2
	local PositionY = script.Parent.Position + Vector3.new(0, 50, 0)
	local info = TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)
	script.Parent.CFrame = CFrame.new(script.Parent.Position, PositionY)
	local goals = {
		CFrame = CFrame.new(PositionY)
	}
	local animation = game:GetService("TweenService"):Create(script.Parent, info, goals)
	animation:Play()
	animation.Completed:Wait()
	local connection = nil
	connection = RunService.Heartbeat:Connect(function() 
		-- Increment the angle over time
		number = number + math.rad(rate)

		-- Calculate the new position the part will move to
		local direction = Vector3.new(math.cos(number), PositionY, math.sin(number))
		print(PositionY)

		-- Make the part face the new direction while moving to it
		script.Parent:PivotTo(script.Parent.CFrame * CFrame.new(direction) * CFrame.Angles(0, math.rad(rate) + math.rad(rate), 0))
	end)

The problem:

You can get the direction it’s moving using AssemblyLinearVelocity

You can move it using CFrame.lookAt()

You can use the last position of it and CFrame.lookAt:

local connection = nil
connection = RunService.Heartbeat:Connect(function() 
		-- Increment the angle over time
		number = number + math.rad(rate)

		-- Calculate the new position the part will move to
		local direction = Vector3.new(math.cos(number), PositionY, math.sin(number))
		print(PositionY)

		-- Calculate the desired position of the part
		local newPosition = (script.Parent.CFrame * CFrame.new(direction)).Position
		-- Store the current position 
		local oldPosition = script.Parent.CFrame.Position
		-- Calculate a vector in the direction of movement
		local movementVector = newPosition - oldPosition
		-- Make a new CFrame at the newPosition facing the direction of movement
		local newCFrame = CFrame.lookAt(newPosition, newPosition + movementVector)

		-- Set the script.Parent's CFrame
		script.Parent:PivotTo(newCFrame)
	end)

This code calculates the direction of movement and makes a CFrame that faces that direction. You might want to add a case that handles when the newPosition and oldPosition are equal (in this case it probably should just not change the orientation of the CFrame).

What’s the purpose of the spinning brick, because you have some options. If it’s a platform a player’s supposed to interact with then you need to use physics, otherwise the player will slide off the CFramed Part.

Anchor a pivot Part at the circle center. Weld an unanchored Part to the center Part at the radius you want it from the center. Tween the center Part’s rotation.

Do the same thing with a HingeConstraint and have the Attachment for the spinning Part at the Position of the Hinge Attachment at center.

1 Like

The part is anchored, so this actually doesn’t work. Anchored assemblies can have velocity, but the velocity doesn’t correspond to the movement (this is how conveyors work: anchored parts that still have velocity).

This is what happens when I do that:

Thanks, this worked.
It was supposed to be a sort of tiny plane that goes around in circles.