How to rotate around an object's pivot with scripts

  1. What do you want to achieve?
    I’m making a plugin that creates tracks with some geometry calculations in the background. In other for this math to check out, I need to rotate parts around their pivots via scripts.

  2. What is the issue?
    The parts do rotate, the pivot point is set… it however doesn’t rotate around the pivot point like parts usually do with Studio build tools.

  3. What solutions have you tried so far?
    I looked on the DevForum but all I could find I either didn’t understand because the people trying to help went really off-topic, couldn’t really apply to my use-case or was just full of errors and in the end didn’t even work.

This is my current code, the one that doesn’t rotate around the pivot point but the part origin.

-- trackPiece is the current track piece
-- previousTrackPiece is the one that was calculated just before our current one.
trackPiece.CFrame = previousTrackPiece.CFrame + previousTrackPiece.CFrame.LookVector*previousTrackPiece.Size.Z
local PivotOffset = CFrame.new(Vector3.new(0,0,trackPiece.Size.Z/2)) -- Does some math for said pivot point
trackPiece.PivotOffset = PivotOffset -- Successfully sets new pivot point
trackPiece.Orientation = Vector3.new(0,trackPiece.Orientation.Y + increment, 0) -- ORIENTATION BY SCRIPT DOESN'T ROTATE AROUND PIVOT

Any help is greatly appreciated!

1 Like

I somewhat found a solution but it feels very hacky. I’ll not mark this as resolved; maybe someone will find a cleaner option

For short, I first move the new track piece half of the usual length, rotate it and then move it the half-length relative to the new part instead of the old one.

trackPiece.CFrame = previousTrackPiece.CFrame + previousTrackPiece.CFrame.LookVector*previousTrackPiece.Size.Z / 2
local PivotOffset = CFrame.new(Vector3.new(0,0,trackPiece.Size.Z/2))
trackPiece.PivotOffset = PivotOffset
trackPiece.Orientation = Vector3.new(0,trackPiece.Orientation.Y + increment, 0) -- ORIENTATION BY SCRIPT DOESN'T ROTATE AROUND PIVOT
trackPiece.CFrame = trackPiece.CFrame + trackPiece.CFrame.LookVector*trackPiece.Size.Z / 2 -- Hacky, but can be called as working

There’s a method called :PivotTo which will work.

You could also use CFrame directly without a pivot. Move it forward, rotate it, move it forward again:

trackPiece.CFrame = previousTrackPiece.CFrame
  * CFrame.new(0, 0, -previousTrackPiece.Size.Z / 2)
  * CFrame.Angles(0, increment, 0)
  * CFrame.new(0, 0, -trackPiece.Size.Z / 2)
3 Likes

You can just change the pivot offset inside the part and hook that variable and set it to the orientation.

I found the solution (my solution):

  1. Adjust the PivotOffset position.
  2. On script, we use PivotTo() as a changing orientation.
  3. Here’s my script example (Full Script):
local ClickDetector = script.Parent

ClickDetector.MouseClick:Connect(function(playerWhoClicked)
	local OpenClose = script.Parent.Parent.Parent.OpenClose
	
	local Door = script.Parent.Parent.Parent
	
	if OpenClose.Value == true then
-----------------------// THE SCRIPT \\--------------------------------------
		repeat
			wait(0.01)
			--[[ Over Here ->]] Door:PivotTo(Door:GetPivot() * CFrame.Angles(0, math.rad(0+1), 0))
		until Door.Orientation.Y == 90
----------------------------------------------------------------------
		
		if Door.Orientation.Y == 90 then
			OpenClose.Value = false
		end
	elseif OpenClose.Value == false then
		OpenClose.Value = true
		
		repeat
			wait(0.01)
			Door.Orientation += Vector3.new(0, -1, 0)
		until Door.Orientation.Y == 0

		if Door.Orientation.Y == 0 then
			OpenClose.Value = true
		end
	end
end)

Note - I set the value to 0+1 because i just want to add some animation when interacting with the doorknob.
4. You’re good to try this trick!

1 Like