# Offset Rotation 3D space 2D Plane

I’m having trouble creating a crank like mechanism in a 3D space. Below is the code that works, but since I’m using `transform.RotateAround();` for a specified angle, that angle will always jump to the new direction. e.g. if EnumToDir() is set to transform.right, the right vector will jump to _snapDir.
RotTowardsTarget

``````    void RotToTarget()
{
// Determine which direction to rotate towards
_targetDirection = target - transform.position;

//Snap the direction to a plane with the specified normal.
_snapDir = Vector3.ProjectOnPlane(_targetDirection, axisToNormal[_snapPlaneNormal]).normalized;

// The step size is equal to speed times frame time.
_singleStep = _speed * Time.deltaTime;

//Calculate the angle from face to snapDir indicating axis to prevent rotation flips.
_angle = Vector3.SignedAngle(EnumToDir(), _snapDir, axisToNormal[_snapPlaneNormal]);

transform.RotateAround(_rotatePivotPoint.position, axisToNormal[_snapPlaneNormal], _angle * _singleStep);
}
``````

What I want to achieve is like the below. I need to use _angle to calculate the initial direction, and the new direction. Then using this angle, to rotate the object. Problem is, the object might not use transform.forward.

How to I lerp between two angles in 3D space like the below using any specified direction?

_angle

``````_angle = Vector3.SignedAngle(cachedDir, _snapDir, axisToNormal[_snapPlaneNormal]);
``````

edited: Player input drags to create new direction (black). Blue is the angle to apply to object.

Solve this by making a hierarchy and only rotating the .localRotation of a sub-object.

Something like this:

``````FixedPartsOfItLikeTheWallUnit <- don't rotate this
VisibleFixedPart1
VisibleFixedPart2
RotatableParts <- ONLY rotate this using .localRotation
RotatingPart1
RotatingHandlePart1
etc```

And you want to track your own notion of its angle, then generate the local rotation:

``````

// example rotating around local .z (angle is a float)
RotatablePartTransform.localRotation = Quaternion.Euler( 0, 0, angle);

``````
Or else just make an animation and be done, or use a free tweener like ITween or DOTween``````

Thanks! I had to cached the initial eulerangles as well to create the offset angle.

So is using if/else the only way? I feel like it could be condensed somehow…

``````    void RotAngleToNewAngle(Vector3 cachedDir, Vector3 cachedLocalEulers)
{
_targetDirection = target - transform.position;

//Snap the direction to a plane with the specified normal.
_snapDir = Vector3.ProjectOnPlane(_targetDirection, axisToNormal[_snapPlaneNormal]).normalized;

//The step size is equal to speed times frame time.
//_singleStep = _speed * Time.deltaTime;

//calculate the angle between first vector and new vector
Vector3 offsetAngle;

//Calculate the angle from face to snapDir indicating axis to prevent rotation flips.
_angle = Vector3.SignedAngle(cachedDir, _snapDir, axisToNormal[_snapPlaneNormal]);

if (_snapPlaneNormal.Equals(CustomExtensions.CustomAxis.X) || _snapPlaneNormal.Equals(CustomExtensions.CustomAxis.X_Flip))
{
offsetAngle = new Vector3(cachedLocalEulers.z + _angle, 0f);
}
else if (_snapPlaneNormal.Equals(CustomExtensions.CustomAxis.Y) || _snapPlaneNormal.Equals(CustomExtensions.CustomAxis.Y_Flip))
{
offsetAngle = new Vector3(0f, cachedLocalEulers.y + _angle);
}
else
{
offsetAngle = new Vector3(0f, 0f, cachedLocalEulers.z + _angle);
}

//Use the offset angle as localEulerAngle
transform.localEulerAngles = -offsetAngle;
}
``````