Unity-Technologies / XR-Interaction-Toolkit-Examples

This repository contains various examples to use with the XR Interaction Toolkit

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Feature request: grabbing object example but keeping hand-object relative initial position and rotation

francopenizzotto opened this issue · comments

It would be great to add an example of interaction where the object is not rotated to the attached position in order to be used in training simulators that demand hands-objects specific movements. All examples in this awesome project are gun-like grab interactions.
I would appreciate it if some can guide me to the code of the mentioned interaction. Thanks a lot.

This tutorial/script shows how to grab objects without snapping to the controller (if I understand your request correct?):

https://www.youtube.com/watch?v=-a36GpPkW-Q

This appears to be related to #21.

I was able to get the code from the tutorial working in 1.0-pre.2:

using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;

public class XRCustomGrabInteractable : XRGrabInteractable
{
    private Vector3 interactorPosition = Vector3.zero;
    private Quaternion interactorRotation = Quaternion.identity;
    
    protected override void OnSelectEntering(SelectEnterEventArgs args)
    {
        base.OnSelectEntering(args);
        Storelnteractor(args.interactor);
        MatchAttachmentPoints(args.interactor); 
    }
    
    private void Storelnteractor(XRBaseInteractor interactor)
    {
        interactorPosition = interactor.attachTransform.localPosition;
        interactorRotation = interactor.attachTransform.localRotation; 
    }
    
    private void MatchAttachmentPoints(XRBaseInteractor interactor)
    {
        bool hasAttach = attachTransform != null; 
        interactor.attachTransform.position = hasAttach ? attachTransform.position : transform.position; 
        interactor.attachTransform.rotation = hasAttach ? attachTransform.rotation : transform.rotation; 
    }
    
    protected override void OnSelectExiting(SelectExitEventArgs args)
    {
        base.OnSelectExiting(args); 
        ResetAttachmentPoint(args.interactor); 
        Clearinteractor(args.interactor); 
    }
    
    private void ResetAttachmentPoint(XRBaseInteractor interactor) 
    {
        interactor.attachTransform.localPosition = interactorPosition;
        interactor.attachTransform.localRotation = interactorRotation; 
    }
    
    private void Clearinteractor(XRBaseInteractor interactor) 
    {
        interactorPosition = Vector3.zero;
        interactorRotation = Quaternion.identity;
    }
}

Note I ended up not using the above code because I was using an XRRayInteractor which bugged out with the above code, the ray would jump to the position of the interactable and it wouldn't work with sockets. So I ended up using this:

using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;

public class XRCustomGrabInteractable : XRGrabInteractable
{
    private Vector3 interactorPosition = Vector3.zero;
    private Quaternion interactorRotation = Quaternion.identity;
    
    protected override void OnSelectEntering(SelectEnterEventArgs args)
    {
        base.OnSelectEntering(args);
        
        if (args.interactor is XRRayInteractor) 
        {
            interactorPosition = args.interactor.attachTransform.localPosition;
            interactorRotation = args.interactor.attachTransform.localRotation;

            bool hasAttach = attachTransform != null;
            args.interactor.attachTransform.position = hasAttach ? attachTransform.position : transform.position;
            args.interactor.attachTransform.rotation = hasAttach ? attachTransform.rotation : transform.rotation;
        }
    }
    
    protected override void OnSelectExiting(SelectExitEventArgs args)
    {
        base.OnSelectExiting(args);
        
        if(args.interactor is XRRayInteractor)
        {
            interactorPosition = Vector3.zero;
            interactorRotation = Quaternion.identity;
        }
    } 
}

Hello,
It's great, thank you !

I also used the above code, but it does not work with version 2.3.0 anymore, does anyone know why or how to get it to work again? I tried using various functions from args.interactorObject but it keeps snapping to the controller/hand. I have a feeling that it has something to do with transformers, but I can't figure it out.

ouch - I just noticed that the "Force Grab" option on the Ray Interactor toggles this exact feature. Is there a need to keep this issue open then? :D

@jagru20 sorry I haven't had a chance to test on the latest version as I'm on my phone but force grab used to move the intractable to a specific point on the interactor which effectively moves the object when you first grab it. This is fine for a gun which needs to snap to a certain position on the hand. But this was about keeping the interactable in its initial position when you trigger a grab.