Unity XR - Rotate a grabbed object with XRGrabInteractable around its pivot

791 views Asked by At

I'm pretty new to VR development with Unity, what I need to do is to grab a clockwork object and rotate it around its pivot by moving the right hand controller, like if I had to do that in real life

Here's the scenario:

enter image description here

Here's the code I'm using in Update:

public class Box1: MonoBehaviour { 
    public Transform rightHandTransf;
    Vector3 handPosition; 

   
  void Update(){ 
     Vector3 rhPos = rightHandTransf.position; 
     Quaternion rhRot = rightHandTransf.rotation; 

     // clockworkM Rotation 
     rhPos.z = clockworkM.transform.position.z - Camera.main.transform.position.z; 
     handPosition = Camera.main.WorldToScreenPoint(rhPos); 
     clockworkM.transform.rotation = Quaternion.LookRotation(Vector3.back, handPosition - clockworkM.transform.position);
  }

}

What I get is that wherever I move the hand, the clockwork rotates just a little bit, and if I rotate the headset, the clockwork rotates based on my X axis rotation with my headset

Weird behavior, I have no idea what I'm doing wrong :(

1

There are 1 answers

0
Dmnk On BEST ANSWER

you probably solved it by now but in case someone else stumbles on this. My solution is just for rotating object around Y axis but can be easily edited for any other direction:

public Transform interactorTransform;
float lastFrameAngle;
public float multiplier = 1;

private void Start() {
    XRGrabInteractable interactble = GetComponent<XRGrabInteractable>();
    interactble.selectEntered.AddListener(Selected);
    interactble.selectExited.AddListener(Deselected);
}

private void FixedUpdate() {
    if (interactorTransform != null) {
        float angle = Vector3.SignedAngle(interactorTransform.position - transform.position, interactorTransform.forward, Vector3.up);
        float delta = angle - lastFrameAngle;
        transform.Rotate(transform.up, delta*multiplier);           
        lastFrameAngle = angle;
    }
}

public void Selected(SelectEnterEventArgs arguments) {        
    interactorTransform = arguments.interactorObject.transform;
    lastFrameAngle = Vector3.SignedAngle(interactorTransform.position - transform.position, interactorTransform.forward, Vector3.up);        
}

public void Deselected(SelectExitEventArgs arguments) {        
    interactorTransform = null;        
}