[OpenXR] XR Interaction Toolkit 2.4.3 (Two Hand Grab)

VR/XR Interaction Toolkit 2023. 12. 28. 11:25
반응형

 

https://youtube.com/playlist?list=PLTFRwWXfOIYBIPKhWi-ZO_ITXqtNuqj6j&si=9t2YSxJcsw7fRNMR

 

XR Interaction Toolkit 2.4.3

XR Interaction Toolkit 2.4.3 OpenXR Oculus

www.youtube.com


https://youtu.be/LZFjfT_2TaQ?list=PLTFRwWXfOIYBIPKhWi-ZO_ITXqtNuqj6j

리소스 

https://assetstore.unity.com/packages/3d/props/guns/stylized-m4-assault-rifle-with-scope-complete-kit-with-gunshot-v-178197

 
 
컨트롤러를 사용한 한손잡기를 만들어 준다 
 
새 씬을 만들고 
메인 카메라를 제거 후 XR Origin을 생성 한다 

 
XR Origin오브젝트를 선택후 Tracking Origin Mode를 Floor로 변경 

 
Left/Right Controller를 선택하고 

 
XR Controller를 제외한 나머지 컴포넌트는 제거 한다 

 
다음과 같은 구조를 만들어주고 

 
Left Controller를 선택후 Model Prefab과 Model Parent를 각각 넣어준다 

 
왼손 Offset의 위치와 회전을 설정한다 

왼손 설정된 모습

 
오른손도 동일하게 작업 한다 
 
Right Controller를 선택하고 

 
Model Prefab/Parent를 넣어주고 

 
 
Offset의 위치와 회전을 맞춰준다 

 
 

완성된 왼손 컨트롤러 핸드

 
 

 
 


 
리소스를 다운 받고 

 
프리팹을 선택한다 

 
다음과 같이 핑크색으로 보이면 

 
 
 
핑크색 메터리얼들을 선택 하고 

 

 
Edit > Rendering > Materials > Convert Selected Bulit-In Materials to URP를 선택한다 

 

 
 
이제 프리팹을 씬으로 가져온후 위치를 맞추고 실행후 정면에 잘 보이는지 확인 한다 

 
 
실행후 확인 
 

 
 
 
이제 씬에서 총을 선택하고 언팩 하고 다음과 같은 구조로 만들어 준다 

 
기존에 붙어 있던 스크립트는 제거 한다 

 
 
Rifle오브젝트를 선택하고 위치와 크기를 조절 한다 

 
 
손의 크기에 맞게 크기를 조절하고 위치도 잡을수 있게 수정 한다 

 
다시 실행후 크기와 위치가 맞는지 확인한다 
 

 
 


 
Left Controller를 선택하고 
 

 
XR Direct Interactor컴포넌트를 부착하고 

 
후 Interaction Manager 프로퍼티에 XR Interaction Manager오브젝트를 넣어준다 

 
이어서 Sphere Collider를 추가 하고 Radius를 0.1로 설정한다 

 
 
이제 Rifle오브젝트를 선택하고 Rigidbody, XR Grab Interactable 컴포넌트를 부착한뒤 
다음과 같이 설정 한다 

 
Rifle을 선택하고 자식으로 빈오브젝트 (Collider)를 만들어 주고 
 

 
 
Box Collider컴포넌트를 부착 하고 Is Trigger를 체크 한다  

 
크기와 위치 회전을 조절해 핸들 부붙에 가져다 놓는다 

 
 
Rifle 오브젝트를 선택하고 Colliders에 넣어준다 

 
 
Assault_Rifle오브젝트를 선택하고 

Mesh Collider를 제거 한다 

 
 
 
위치와 크기가 맞지 않는다면Assault_Rifle_M4를 선택해 

위치와 회전을 다음과 같이 설정하고 

 
Rifle을 선택해 정면을 바라보게 만들어 준다 

 
실행후 결과를 확인 한다 

 
 
손의 위치가 맞지 않으면 

 
 
Offset의 위치를 설정 한다 

 
 
 

왼손 오프셋

 

오른손 오프셋

 

라이플 위치와 회전 크기

 
실행후 결과를 확인 하자 

 


 
Rifle을 선택한뒤 XR Grab Interactable 컴포넌트의 Select Mode를 Multiple로 변경 한다 

 
다음과 같이 간단히 두손 잡기를 구현 할수 있다 
 

 
 
콜라이더를 하나 더 만들어 핸드가드 (총열덮개) 부분에 위치 시킨다 

 
Rifle 오브젝트를 선택하고 XR Grab Interactable 컴포넌트의 Colliders에 추가 한다 

 

 


라이플을 선택후 

 
 
XR Grab Interactable컴포넌트의 Use Dynamic Attack 프로퍼티를 체크 해본다 

 
다음과 같이 잡은 위치와 회전을 기반으로 잡기가 동작 한다 
 

https://docs.unity3d.com/Packages/com.unity.xr.interaction.toolkit@2.4/api/UnityEngine.XR.Interaction.Toolkit.XRGrabInteractable.html

 
 
완성된 결과물 


 
도전 
이전시간에 했던 Hand Grab Pose 를 이용해 손동작을 적용해보자

 

 

 

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;

public class Hand : MonoBehaviour
{
    public InputDeviceCharacteristics inputDeviceCharacteristics;

    private InputDevice _targetDevice;
    [SerializeField] private Animator _handAnimator;

    private void Start()
    {
        InitializeHand();
    }

    private void InitializeHand()
    {
        List<InputDevice> devices = new List<InputDevice>();
        InputDevices.GetDevicesWithCharacteristics(inputDeviceCharacteristics, devices);

        if (devices.Count > 0)
        {
            _targetDevice = devices[0];
        }
    }

    private void Update()
    {
        if (!_targetDevice.isValid)
        {
            InitializeHand();
        }
        else
        {
            UpdateHand();
        }
    }

    private void UpdateHand()
    {
        SetAnimatorParameterValue(CommonUsages.grip, "Grip");
        
        // Animator 컴포넌트에 해당 트리거 파라미터가 존재하는지 확인
        if (HasParameterOfType(this._handAnimator, "Trigger", AnimatorControllerParameterType.Trigger))
        {
            // 트리거 파라미터가 존재하면 실행
            SetAnimatorParameterValue(CommonUsages.trigger, "Trigger");
        }
        else
        {
            // 트리거 파라미터가 존재하지 않으면 실행하지 않음
            Debug.LogWarning("Trigger parameter does not exist");
        }
        
    }
    
    public bool HasParameterOfType(Animator animator, string paramName, AnimatorControllerParameterType paramType)
    {
        AnimatorControllerParameter[] parameters = animator.parameters;
        foreach (AnimatorControllerParameter parameter in parameters)
        {
            if (parameter.name == paramName && parameter.type == paramType)
            {
                return true;
            }
        }
        return false;
    }

    private void SetAnimatorParameterValue(InputFeatureUsage<float> feature, string parameterName)
    {
        if (_targetDevice.TryGetFeatureValue(feature, out float value))
        {
            _handAnimator.SetFloat(parameterName, value);
        }
        else
        {
            _handAnimator.SetFloat(parameterName, 0);
        }
    }
}

 
 
Use Dynamic Attach 를 사용하지 않았을 경우 
 

 
 
Use Dynamic Attach를 사용했을 경우 
 

 

반응형
: