VR Multiplayer Game - 1. HandPresence

Ericjang·2023년 6월 5일
0

Unity VR MultiPlayer

목록 보기
1/1

영상 목록

  • 필요한 plugin
    - XR Interaction Toolkit
    - XR Plugin Management
    - OpenXR Plugin
  • HMD
    Oculous quest 2
  • Unity version
    21.3.25f1

튜토리얼은 다 따라했고 동기화도 다 되었다.
짧게 요약하자면 네트워크를 하면 Player는 두 명이 있다.

  • XROrigin(로컬)
  • NetworkPlayer(네트워크)

XROrigin은 로컬 상에서 움직이고 NetworkPlayer는 XROrigin의 위치와 동기화되어 로컬에선 보이지 않고 네트워크 서버에선 상대방에게 보이는 player이다. 그리고 이 동기화는 Photonview를 통해 이루어진다.

  • Photonview
    동기화할 물건의 최상단 부모오브젝트에 있어야 할 컴포넌트
  • PhotonTransformView
    위치 변화
  • PhotonAnimatorView
    손이나 동작이 필요한 경우
  • PhotonRigidbodyView
    물리적 상호작용이 있는 물건

그런데 VR MultiPlayer Tutorial을 따라해봤는데 궁금증이 생겼다.

〽️ 기능은 어디에 구현하고 동기화는 어디서 하는 거지??

그렇게 시작된 분석 끝에 HandPresence 가 뭐하는 놈이지? 라는 생각에 도달했다.

아무래도 영상이 2년전 영상이다 보니 패키지가 업데이트되어 컴포넌트 이름이 다르거나 없거나 하는 등 튜토리얼 따라하면서 다사다난했지만 HandPresence는 뭐하는 놈인지 몰랐다.

HandPresence코드 분석 결과, NetworkPlayer에 있는 handModelPrefab을 받아와서

spawnedHandModel = Instantiate(handModelPrefab, transform);
handAnimator = spawnedHandModel.GetComponent<Animator>();

이렇게 해서 handModelPrefab의 Animator에 접근하여 HandAnimation을 update하는 것이다.

그러니까 이 스크립트는 손모델링 prefab을 받아서 prefab에 있는 Animator를 통해 애니메이션을 일으키는 것이다. 그리고 이 손모델링prefab은 NetworkPlayer에 있다.

그런데 1편의 27:26를 보면 NetworkPlayer의 손 동작은 UpdateHandAnimation가 추가되면서 움직이기 시작했다. 즉, NetworkPlayer 손의 애니메이션을 XROrigin이 받아오는 게 아니다. 독자적으로 UpdateHandAnimation 함수를 이용해 손동작이 이루어진다. 즉, 하나의 입력에 XROrigin의 손과 NetworkPlayer의 손이 똑같이 동작하는 것이다. 다만, 애니메이션이 똑같아서 똑같아 보이는 것이다.

💡 HandPresence → 애니메이션 읽어오기(동기화 아님)

해서 HandPresence 없이 NetworkPlayer의 손과 똑같은 모델링에 애니메이션이 동작하는 스크립트만 있다면 가능하다. 이는 이 영상에 있는 거 그대로 따라한거 써도 된다는 뜻이다. 굳이 prefab에 접근해서 할 필요가 없다. 다만 Animator는 동일해야 한다.

HandPresence가 필요없는 또다른 이유는 NetworkPlayer에서 XROrigin의 양손, 머리의 Transform 정보를 가져와 위치를 동기화시키기 때문이다.

void Start()
{
    photonView = GetComponent<PhotonView>();
    // 로컬상에 있는 XROrigin과 연결시킨다. 
    XROrigin origin = FindObjectOfType<XROrigin>();
    headRig = origin.transform.Find("Camera Offset/Main Camera");
    leftHandRig = origin.transform.Find("Camera Offset/LeftHand Controller");
    rightHandRig = origin.transform.Find("Camera Offset/RightHand Controller");
    
    //  네트워크 자기꺼 비활성화(대신 로컬상 XROrigin)
    if (photonView.IsMine)
    {
        foreach (var item in GetComponentsInChildren<Renderer>())
        {
            item.enabled = false;
        }
    }
}

해서 XROrigin은 기존의 것을 써서 자체적으로 Animtor를 작동하는 방식으로 했다.

결론

  • 버튼 입력시 애니메이션은 XROrigin, NetworkPlayer에서 각자 자체적으로 재생한다.
    따라서 기능은 XROrigin에서 구현하고 NetworkPlayer에선 PhotonView로 동기화한다.
  • NetworkPlayer는 NetworkSpawner에 의해 생성되므로 Lobby에서는 NetworkPlayer가 없다. 방에 참가하여야만 생성된다. 그리고 방에서 시작되어도 NetworkPlayer는 생성되지 않는다.
  • 기능 구현은 XROrigin에서 하고 Network는 Photonview를 이용해서 동기화시켜줘야 한다.

0개의 댓글