Unity 툴을 이용해 VR 콘텐츠를 구현하는 데 있어서 3D 객체를 줍고 던지고 하는 행위는 빈번하게 나타나고 있습니다.
하지만 그런 행위 때문에 사용자에게 필요한 객체를 잃어버리게 되거나 위치를 잊게된다면 개발자나 사용자한테 혼란을 심어줄 수 있습니다.
SteamVR Plugin에서 제공되는 메소드를 사용해 손쉽게 객체를 아무리 던지고 물리적 힘을 가해도 원래 위치로 돌아오는 기능을 손쉽게 구현해 보겠습니다.
필요 에셋
SteamVR Plugin
오브젝트 준비
1. Collider, Rigidbody 컴포넌트 추가
물체를 원위치로 돌아가는 스크립트를 적용시키기위해서는 외부의 힘을 받을지 여부를 결정하기 위해 IsKinematic을 접근해야 합니다.
2. SteamVR에서 제공하는 Interactable.cs, Throwable.cs 추가
Interactable.cs : 객체를 잡고 상호작용을 하기 위한 메소드
Throwable.cs : 객체를 잡고 물리적 힘을 가해 던질 수 있는 메서드
Attachment Flags는 DetachFromOtherHand, VelocityMovement, TurnOffGravity 활성화시켜준다.
(Throwable.cs에 대해서는 해당 블로그 설명을 확인)
3. LockToPoint.cs 추가
SnapTo : 빈오브젝트(Transform)를 추가해 위치를 지정해 주면 해당 위치로 시간 내에 돌아가게 됩니다.
SnapTime : 객체가 위치로 돌아가는 시간
주의! 스크립트가 활성화되어있는 상태에는 객체는 항상 위치로 돌아가게 됩니다. 그러므로 객체의 시작위치와 SnapTo에 할당된 빈객체(Transform)의 위치는 동일하게 시작해야 됩니다.
코드 작성
사용방법은 다양하게 사용가능하지만 보통 Interactable.cs이 적용된 객체인 경우 OnAttachedToHand(), OnDetachedFromHand() 메서드를 사용해서 잡혔을 때 유무를 파악해 LockToPoint.cs를 활성화 비활성화를 통해 물체를 원위치로 돌릴 수 있습니다.
public GameObject attachObject;
//객체를 잡았을 때 LockToPoint.cs 비활성화, isKinematic 활성화
private void OnAttachedToHand(Hand hand)
{
attachObject.GetComponent<LockToPoint>().enable = false;
attachObject.GetComponent<Rigidbody>().isKinematic = true;
}
//객체를 놨을 때 LockToPoint.cs를 활성화시키고 외부의 물리적 영향을 받지 않기 위해 isKinematic 비활성화
private void OnDetachedFromHand(Hand hand)
{
attachObject.GetComponent<LockToPoint>().enable = true;
attachObject.GetComponent<Rigidbody>().isKinematic = false;
}
> 실행시키면 물체를 집고 던졌을 때 SnapTo에 할당된 Transform 위치에 돌아오는 것을 확인하실 수 있습니다.
이렇게 SteamVR에서 제공하는 메서드를 사용해 손쉽게 물체를 던지고 원위치로 돌아오는 기능을 구현했습니다.