# Rotate and move a GameObject towards a point around a center point (rotating a Rubik's cube's pieces)

I’m creating an nnn Rubiks cube solver in unity.

I am rotating and moving each piece(cubie) individually instead of grouping and ungrouping (I think it should be more efficient).

I can’t get the rotation and movement of the cubies to line up when a side is turned:

Here is the function used to produce the result above. It is called for every cubie on the rotating layer per frame:

void RotateAndMove(GameObject obj, Vector3 targetPos, Quaternion targetRot, Vector3 rotationPoint, float speed)
{
var pos = obj.transform.localPosition;
var rot = obj.transform.localRotation;

//if the rotation is almost equal to the target rotation set both the rotatation and position to the target
if (EqualAprox(rot.x, targetRot.x) && EqualAprox(rot.y, targetRot.y) && EqualAprox(rot.z, targetRot.z) && EqualAprox(rot.w, targetRot.w))
{
obj.transform.SetLocalPositionAndRotation(targetPos, targetRot);
return;
}

var Amount = Time.deltaTime * speed;
var dist = Vector3.Distance(pos, rotationPoint);

//a point on the straight line between pos and targetpos
var newPoint = Vector3.MoveTowards(pos, targetPos, Amount * dist * 0.0195f);

//the new calculated position
pos = (newPoint - rotationPoint).normalized * dist + rotationPoint;
//the new calculated rotation
rot = Quaternion.RotateTowards(rot, targetRot, Amount);

obj.transform.SetLocalPositionAndRotation(pos, rot);
}

The MoveTowards function speed is slowed down by a number found through trial and error to try and keep the rotation and movement speed the same relative to each other but it seems like no number used here will align them precisely.

I think there is an issue with the formula and something else should be used instead but I have no clue how to fix it. I’m new to vector math.

Please suggest an algorithm or piece of code to rotate and move an object around a central point by a specified distance towards another point.

The unity rotate around function does almost what I need but it overshoots the target position.

Here is a similar question using lerp that almost works for me but it follows a straight line instead of rotating around:

Here one complicated way of doing what you are trying, you might be able to tweak it:

private void ComplicatedWay()
{
Matrix4x4 pivotMatrix = Matrix4x4.TRS(pivot.position, pivot.rotation, Vector3.one);
Matrix4x4 inverse = pivotMatrix.inverse;

//Rotate the pivot
Quaternion rotation = Quaternion.AngleAxis(Time.deltaTime * speed, Vector3.forward);
pivot.rotation *= rotation;

foreach (Transform objectToRotate in objectsToRotate)
{
//Transform the object to rotate position in to the system of coordinate of the pivot
Vector3 positionInRelationOfThePivot = inverse * new Vector4(objectToRotate.position.x, objectToRotate.position.y, objectToRotate.position.z, 1);
//Rotate the object to rotate
Vector3 newPositionInRelationOfThePivot = rotation * positionInRelationOfThePivot;
//Transform back the object to rotate position in to the world system of coordinate
Vector3 newPosition = pivotMatrix * new Vector4(newPositionInRelationOfThePivot.x, newPositionInRelationOfThePivot.y, newPositionInRelationOfThePivot.z, 1);

objectToRotate.position = newPosition;
objectToRotate.rotation = pivot.rotation;
}
}