You are on the right track that’s how you will find the parts zAxis relative to the part.
However, to do the actual rotation you might want to use CFrame.fromAxisAngle to create the rotations you need as you can specify which axis you want the CFrame to rotate on.
I believe your scenario is similar to my experiences of trying to rotate a limb using the direction of the previous limb as a reference axis, however, if not then you can probably use the following as a guide on how CFrame.fromAxisAngle works and how you can use it for CFrame’s in the future.
Here is an example script is taken from my open-source inverse kinematics module detailing the usage of CFrame.fromAxisAngle and it’s advantages of easily finding an axis to rotate around.
This is what the script does in action:
And here is the diagram I drew of the CFrame.fromAxisAngle Manipulation.
It rotates the limb based on where the previous limb was relative to the previous limb’s CFrame using vector to world space like so below. This is illustrated by the pink arrow going from the pink brick to the black brick.
local limbVectorRelativeToOriginal = previousLimbCF:VectorToWorldSpace(originalVectorLimb)
The red arrow going from the pink brick to the red brick is the goal, where I want the limb to be which I generated using the FABRIK algorithm.
To achieve the rotation from the pink arrow to the red arrow I will first find the angle rotation needed to be represented by the green theta symbol from the pink arrow to the red arrow.
This is done by this piece of code, using the dot product formula with a clamp in order to avoid floating point errors for some reason.
local dotProductAngle = limbVectorRelativeToOriginal.Unit:Dot(currentVectorLimb.Unit)
local safetyClamp = math.clamp(dotProductAngle, -1, 1)
local limbRotationAngle = math.acos(safetyClamp)
Then in order to define where the rotation will happen, I obtained the blue dotted arrow through the cross product as to rotate around this axis like so:
local limbRotationAxis = limbVectorRelativeToOriginal:Cross(currentVectorLimb) -- obtain the rotation axis
Once the angle and the axis are found we have found the additional rotation CFrame we need to add on to the initial CFrame in order to apply the rotation.
local addRotationCframe = CFrame.fromAxisAngle(limbRotationAxis,limbRotationAngle)
However, due to the CFrame order of operations and how it’s not commutative especially with how the rotation I got only applied relative to the world and not relative to the motor joint C0 things got complex and I ended up with this for some reason.
--Obtain the CFrame operations needed to rotate the limb to the goal
local undoPreviousLimbCF = previousLimbCF:Inverse()*CFrame.new(motorPosition)
local rotateLimbCF =CFrame.fromAxisAngle(limbRotationAxis,limbRotationAngle)*CFrame.fromMatrix(Vector3.new(),previousLimbCF.RightVector,previousLimbCF.UpVector)
local goalCF = undoPreviousLimbCF*rotateLimbCF
The overall code of the CFrame orientation system for my project:
Overall meat of the code
--Obtains the CFrame of the part0 limb of the motor6d
local previousLimbPart = self.Motor6DTable[i].Part0
local previousLimbCF = previousLimbPart.CFrame
-- Obtains the CFrame rotation calculation for CFrame.fromAxis
local limbVectorRelativeToOriginal = previousLimbCF:VectorToWorldSpace(originalVectorLimb)
local dotProductAngle = limbVectorRelativeToOriginal.Unit:Dot(currentVectorLimb.Unit)
local safetyClamp = math.clamp(dotProductAngle, -1, 1)
local limbRotationAngle = math.acos(safetyClamp)
local limbRotationAxis = limbVectorRelativeToOriginal:Cross(currentVectorLimb) -- obtain the rotation axis
--Obtain the CFrame operations needed to rotate the limb to the goal
local undoPreviousLimbCF = previousLimbCF:Inverse()*CFrame.new(motorPosition)
local rotateLimbCF =CFrame.fromAxisAngle(limbRotationAxis,limbRotationAngle)*CFrame.fromMatrix(Vector3.new(),previousLimbCF.RightVector,previousLimbCF.UpVector)
local goalCF = undoPreviousLimbCF*rotateLimbCF
Hope this helps for obtaining a new useful tool that is CFrame.fromAxisAngle you can use to do CFrame math with hopefully for your goals with the camera.
My personal advice is to use Roblox Studio to the diagrams for you like the part debugging I did in my idea since I can’t draw well.
I’m pretty sure @CJ_Oyer will agree with the usefulness of CFrame.fromAxisAngle as he has used it in his own Inverse Kinematics project.