SW 중심대학 OSS GIT 서버
새로운 리포
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.XR.Interaction.Toolkit;
public class TwoHandGrabInteractable : XRGrabInteractable{ public List<XRSimpleInteractable> secondHandGrabPoints = new List<XRSimpleInteractable>(); //두번째 손 잡이용 XRSimpleInteractable들
private XRBaseInteractor secondInteractor; //두 번째 손의 Interactor
private Quaternion attachInitialRotation; //첫 번째 손의 원래 회전값
public enum TwoHandRotationType { None, First, Second } //어느 손의 기준으로 총을 회전할 것인가?
public TwoHandRotationType twoHandRotationType;
private Quaternion initialRotationOffset; //두번째 손으로 잡을 때, 회전각의 차이값을 저장
void Start() { //두 번째 손을 잡았을 때 / 손았을 때 실행할 리스너 함수 등록
foreach (var item in secondHandGrabPoints) { item.onSelectEntered.AddListener(OnSecondHandGrab); item.onSelectExited.AddListener(OnSecondHandRelease); } }
//사물을 잡고 있는 동안 계쏙 실행
public override void ProcessInteractable(XRInteractionUpdateOrder.UpdatePhase updatePhase) { //양 손으로 잡고 있을 때만 회전값을 계산하도록
if(selectingInteractor && secondInteractor) { //회전값을 계산
//오브젝트의 Pivot중심점이 아닌, 첫 번째 손을 잡은 AttachTransform을 기준으로 회전하기 위해 잡은 손의 attachTransform의 회전각을 변경해줌
selectingInteractor.attachTransform.rotation = GetTwoHandRotation() * initialRotationOffset; }
base.ProcessInteractable(updatePhase); }
private Quaternion GetTwoHandRotation() { Quaternion targetRotation;
switch (twoHandRotationType) { default: case TwoHandRotationType.None: //회전하지 않음
targetRotation = Quaternion.LookRotation(secondInteractor.transform.position - selectingInteractor.transform.position); break; case TwoHandRotationType.First: targetRotation = Quaternion.LookRotation(secondInteractor.transform.position - selectingInteractor.transform.position, selectingInteractor.attachTransform.up); break; case TwoHandRotationType.Second: targetRotation = Quaternion.LookRotation(secondInteractor.transform.position - selectingInteractor.transform.position, secondInteractor.attachTransform.up); break; }
return targetRotation; }
public override bool IsSelectableBy(XRBaseInteractor interactor) { //이미 다른 Interactor가 잡고 있는가?
//현재 잡고 있는 Interactor가 있고, 그게 지금 새로 잡으려는 interactor가 아닌 경우에만 true
bool isAlreadyGrabbed = selectingInteractor && !interactor.Equals(selectingInteractor);
//'다른 Interactor'가 잡고 있지 않을 때'라는 조건 추가
return base.IsSelectableBy(interactor) && !isAlreadyGrabbed; }
public void OnSecondHandGrab(XRBaseInteractor interactor) { print("Second Hand Grab"); secondInteractor = interactor; //두번째 Interactor 설정
//Quaternion의 회전값의 차이를 구하기 위해, 한 Quaternion의 Inverse값에 다른 Quaternion을 곱해줌
initialRotationOffset = Quaternion.Inverse(GetTwoHandRotation()) * selectingInteractor.attachTransform.rotation; }
public void OnSecondHandRelease(XRBaseInteractor interactor) { print("Second Hand Release"); secondInteractor = null; //두번쨰 Interactor 비워줌
}
protected override void OnSelectEntered(XRBaseInteractor interactor) { base.OnSelectEntered(interactor);
print("First Hand Enter");
attachInitialRotation = interactor.attachTransform.localRotation; //첫 번째 손의 원래 회전값 저장
}
protected override void OnSelectExited(XRBaseInteractor interactor) { base.OnSelectExited(interactor);
print("First Hand Exit");
secondInteractor = null; //첫번째 손을 놓으면, 두번째 손도 놓게
interactor.attachTransform.localRotation = attachInitialRotation; //첫 번째 손의 회전값 리셋
}}
|