title: Look rotation with offset
body: <p>I’m working on a mechanism to control the position and rotation of an object around an anchorPoint relative to a controlPoint in 3D space. The object can have any initial rotation, necessitating the use of a rotational offset in order to maintain a relative alignment when the controlPoint is moved. Neither the control nor anchor points exist within the unity scene hierarchy as they’re stored as Vector3’s. The object however, utilizes unity’s Transform and may have one or more parent objects each with their own rotation.</p>
  <p>The expected behavior is much like that of a local rotation gizmo where you click on the ring of the gizmo to set the rotation of the object.</p>
  <p>I've tried without success to implement this using FromToRotation, LookRotation as rotations from identity as well as incremental rotations from the previous rotation state.</p>
  <p>The below was the closest i got, however if the object or it's parent have a Z rotation upon calculating the offset, the object then rotates as expected but also includes an undesired roll around the look axis.</p>
  <pre class="lang-cs prettyprint-override"><code>public Vector3 anchorPoint = Vector3.zero;
  public Vector3 controlPoint = Vector3.left;
  
  Quaternion rotationOffset = Quaternion.identity;
  
  //Called when the object is &quot;attached&quot; to the anchor to store the difference between it's rotation and the directional vector from the control to the anchor
  public void StoreOffset() {
      //The unit vector pointing from the controlPoint to it's anchorPoint
      Vector3 controlFwd = (anchorPoint - controlPoint).normalized;
  
      //Generate a rotation using the direction vector while respecting the objects local up.
      Quaternion lookRot = Quaternion.LookRotation(controlFwd, transform.up);
  
      //Subtract the object's rotation from the lookRotation to determine the rotational offset between the two.
              //Invert the offset rotation to save on calculations during update
              rotationOffset = Quaternion.Inverse(Quaternion.Inverse(transform.rotation) * lookRot);
  }
  
  //Called any time the control point is moved to update the objects rotation
  public void UpdateRotation() {
      //The unit vector pointing from the controlPoint to it's anchorPoint
      Vector3 controlFwd = (anchorPoint - controlPoint).normalized;
  
      //Generate a rotation using the above direction vector while respecting the objects local up.
      Quaternion lookRot = Quaternion.LookRotation(controlFwd, transform.up);
  
      //Assign the new look rotation to the object then apply the offset rotation.
      //ToLocalRotation is a Quaternion extension that converts rotations from world to local space
              transform.localRotation = (lookRot * rotationOffset).ToLocalRotation(transform);
  }
  </code></pre>
  <p><strong>Example Animations</strong></p>
  <p>The first .gif shows the correct functionality so long as the parent object has no rotation.</p>
  <p>The second .gif shows errant rotation if the parent has a Z rotation of 10°</p>
  <p><a href="https://i.stack.imgur.com/VxR0J.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/VxR0J.gif" alt="Expected Rotation" /></a>
  <a href="https://i.stack.imgur.com/dXczV.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/dXczV.gif" alt="Errant Rotation" /></a></p>