This document is about: FUSION 1
SWITCH TO

수정중인 페이지 입니다.

Expo

Level 4
Available in the Industries Circle
Circle

개요

ExpoFusion 샘플은 Fusion으로 최대 100명의 플레이어까지 게임을 할 수 있는 소셜 앱 개발 방법을 설명하는 샘플 앱입니다.

각 플레이어는 아바타로 표현되며 Photon Voice SDK 덕분에 플레이어들이 동일한 채팅 버블 내에 위치해 있으면 다른 플레이어와 대화를 할 수 있습니다.

이 샘플의 주요 내용은 다음과 같습니다 :

  • 첫 번째로, 플레이어는 아바타 선택 화면에서 아바타를 사용자 정의 할 수 있습니다
  • 그러고 나서, Expo 씬에 참여할 수 있습니다. 플레이어가 PC 또는 MAC에서 샘플을 실행하면 데스크톱 모드(키보드 및 마우스 사용) 또는 VR 모드(Meta Quest 헤드셋) 중 하나를 선택할 수 있습니다.
  • 플레이어는 동일한 정적 채팅 버블에 있는 경우 서로 대화할 수 있습니다. 각 정적 채팅 버블에서 락 버튼을 사용하여 새로운 플레이어가 입장하지 못하도록 할 수 있습니다.
  • 또한 두 플레이어가 가까이 있으면 속도가 더 느린 플레이어 주위에 동적 채팅 버블이 생성됩니다.
  • 일부 3D 펜은 3D 드로잉을 만드는 데 사용할 수 있습니다. 앵커를 사용하여 각 3D 드로잉을 이동할 수 있습니다.
  • 또한 클래식 화이트보드를 사용할 수 있습니다. 앵커를 사용하여 각 드로잉을 이동할 수 있습니다.

더 상세한 기술 정보는 코드의 주석에서 제공됩니다.

fusion expo

기술 정보

  • 이 샘플은 공유 모드 토폴로지를 사용하지만 코어는 공유 및 호스트 모드 토폴로지와 호환됩니다.
  • 빌드는 PC, Mac 및 Meta Quest에서 사용할 수 있습니다.
  • 이 프로젝트는 유니티 2021.3.3f1으로 개발되었습니다.
  • 유니티 XR 상호작용 툴킷 2.0.2과 호환됩니다.

시작하기 전에

샘플 실행을 위해 :

  • PhotonEngine 관리 화면에서 Fustion AppId를 생성하고 Real Time 설정(Fusion 메뉴에서 접근 가능)의 App Id Fusion 필드에 붙여 넣으십시오.

  • PhotonEngine 관리 화면에서 Voice AppId를 생성하고 Real Time 설정 내의 App Id Voice 필드에 붙여 넣으십시오.

  • 그러고 나서 AvatarSelection 씬을 로드하고 Play를 누릅니다.

입력 처리

데스크톱

키보드

  • 이동 : 걷기는 WASD 또는 ZQSD 이용
  • 회전 : 회전하기는 QE 또는 AE 이용
  • Bot 스폰: “B”를 눌러 봇을 스폰 합니다. 1초 이상 길게 눌러 떼면 한 번에 50개의 봇을 생성합니다.

마우스

  • 이동 : 마우스로 왼쪽을 클릭하여 포인터를 표시합니다. 마우스를 떼었을 때 이동 가능한 경우 텔레포트합니다.
  • 회전 : 마우스 오른쪽을 누르고 마우스를 이동하여 뷰 포인트를 회전합니다.
  • 이동 & 회전 : 왼쪽과 오른쪽 모두 누르고 앞으로 이동합니다. 마우스를 이동하여 회전할 수 있습니다.
  • 잡기 & 사용 (3D 펜) : 마우스를 물체 위에 놓고 왼쪽 마우스 버튼을 사용하여 잡습니다. 그러면 키보드 스페이스 키를 사용하여 사용할 수 있습니다.

Meta Quest

  • 텔레포트 : A, B, X, Y, 또는 스틱으로 포인터를 표시합니다. 떼면 가능한 지역으로 텔레포트합니다.
  • 터치 (예를 들어 채팅 버블 잠금 버튼) : 간단히 버튼 위에 손을 올려서 토글 합니다.
  • 잡기 : 먼저 손을 물체 위에 놓고 컨트롤러 그랩 버튼을 사용하여 잡습니다.
  • 봇 스폰 : 왼쪽 컨트롤러의 메뉴 버튼을 눌러 하나의 봇을 생성합니다. 떼어서 50개의 봇을 만들려면 1초 이상 누르고 있어야 합니다.

폴더 구조

메인 폴더인 /Expo 에는 이 샘플의 모든 요소가 들어 있습니다.

메인 폴더 /FusionXR 에는 다른 프로젝트와 공유할 수 있는 요소들이 포함되어 있습니다. Integrations라고 하는 하위 폴더가 존재하는데, ReadyPlayerMe 및 유니티 XR 상호작용 툴킷과 같은 타사 솔루션과의 호환성을 관리합니다.
FusionXR 컴포넌트는 공유 토폴로지 및 호스트 토폴로지와 모두 호환되며 expo 샘플만 공유되므로 FusionXR의 일부는 여기에서 필요하지 않습니다.

/Photon 폴더에는 Fusion 및 Photon Voice SDK가 들어있습니다.

/Plugins 폴더에는 Ready Player Me SDK가 들어있습니다.

/StreamingAssets 폴더에는 사전 구축된ReadyPlayerMe 아바타가 들어있습니다. 미리 만들어진 아바타가 필요 없으면 자유롭게 제거할 수 있습니다.

/XRI/XR 폴더에는 가상 현실용 환경 구성 파일이 들어있습니다.

네트워크 연결 및 앱 라이프 사이클

ConnexionManager는 공유 모드 토폴로지에서 Fusion 세션을 시작하고 연결된 각 사용자에 대해 사용자 프리팹을 스폰 합니다.

SessionEventsManager는 Fusion 및 PhotonVoice 연결 상태를 경고하기 위해 관심 있는 컴포넌트, 특히 다양한 음향 효과를 처리하는 SoundManager를 관찰합니다.

오디오

VoiceConnectionFusionVoiceBridge 컴포넌트는 Fusion 세션을 따라 오디오 Photon Voice 연결을 시작하는데, Recorder 컴포넌트는 마이크 입력을 포착합니다.

Oculus Quest 빌드의 경우 추가 사용자 권한이 필요하며, 이 요청은 MicrophoneAuthorization 스크립트에서 관리합니다.

사용자 프리탭은 SpeakerVoiceNetworkObject를 머리 위에 올려놓아 음성을 수신할 때 공간화된 소리를 투사합니다.

Fusion과 Photon Voice의 통합에 대한 자세한 내용은 다음 페이지를 참조하십시오: https://doc.photonengine.com/en-us/voice/current/getting-started/voice-for-fusion

리그

몰입형 앱에서, 리그는 일반적으로 양손, 머리 및 플레이 영역(예를 들어, 사용자가 텔레포트를 할 때 이동할 수 있는 개인 공간)을 나타내는 데 필요한 모든 모바일 부품을 나타냅니다.

네트워크 세션에서 모든 사용자는 네트워크를 통해 다양한 부품 위치가 동기화되는 네트워크 리그로 표시됩니다.

우리는 각 리그 부품마다 하나씩 여러 개의 중첩된 NetworkTransforms과 함께 하나의 NetworkObject로 사용자를 나타내도록 선택합니다.

로컬 사용자를 대표하는 네트워크 리그의 특정 사례에 대해, 이 리그는 하드웨어 입력에 의해 구동되어야 합니다. 이 프로세스를 단순화하기 위해 “하드웨어 리그”라고 하는 별도의 비네트워크 리그가 만들어졌습니다. 하드웨어 입력을 수집하기 위해 고전적인 유니티 컴포넌트를 사용합니다(예: TrackedPoseDriver). 그런 다음 로컬 사용자와 연결된 네트워크 연결 장치의 경우, 모든 네트워크 연결 장치 부품은 단순히 일치하는 하드웨어 연결 장치 부품을 따릅니다.

사용자 프리팹에 있는 XRNetworkedRig 컴포넌트는 중첩된 모든 리그 부품에 대한 추적을 관리합니다.

로컬 사용자에 대한 리그 로직

FixedUpdateNetwork()에서 다른 플레이어와 리그 부품 위치를 공유하는 것 외에도 XRNetworkRig 컴포넌트는 외삽을 처리합니다. Render() 동안에 다양한 리그 부분의 그래픽적인 표현을 처리하는 보간 대상이 움직이고 네트워크 틱 사이에서도 사용자가 가장 최근의 위치의 손을 항상 보기 위해 외삽을 처리합니다.

로컬 사용자와 관련된 XRHardwareRig와 일치하는 XRNetworkRig 를 쉽게 찾을 수 있도록 컴포넌트 "RigInfo"는 추가 사용을 위해XRHardwareRig 와 모든 XRNetworkedRig를 등록합니다.

riginfo content

상호작용 스택

이 샘플은 플레이어가 움직이고, 물체를 잡고, 표면을 만질 수 있게 해줍니다.

이러한 모든 조작은 네트워크와는 무관하게 로컬(하드웨어 리그)에서 수행된 후 Fusion 입력을 통해 네트워크 리그로 전송됩니다.

유니티 XR 상호작용 툴킷(XRIT) 호환성을 보장하기 위해 이 방법을 사용했습니다. XRIT를 반대로 사용하는 것이 더 복잡하기 때문입니다.

XR 상호작용 툴킷

Fusion에서 XR Interaction Toolkit(XRIT)을 사용하려면 몇 가지 조정이 필요합니다.

Fusion에 대해 선택한 토폴로지 및 물리 설정에 따라 XR Interaction Toolkit과 Fusion은 동일한 요소를 처리하려고 할 수 있으므로 두 요소가 원활하게 함께 작동하도록 다음과 같이 변경되었습니다.

  • 일부 XRIT 구성 요소는 유니티 물리학 단계의 시작, 진행 중, 종료 시 처리를 분할합니다. Photon은 물리 시뮬레이션을 관리할 수 있기 때문에 XRIT의 경우 순서가 예기치 않을 수 있습니다. 그래서 XRIT 클래스의 하위 클래스는 Fusion 실행 순서를 인식하도록 만들어졌습니다. 참고: 이러한 수정 사항 중 일부가 모든 토폴로지에 필요한 것은 아니지만, 현재 버전은 모든 경우에 작동하도록 토폴로지와 함께 생활하는 방법을 보여줍니다.

  • 공유 모드에서 객체를 잡을 때 Fusion과 XRIT 모두 강체의 isKinematic 특성을 편집할 수 있습니다. 이 구성 요소는 XRIT가 Fusion 속성에서 사용할 수 있는 실제 값을 인식하도록 보장합니다.

이동

가상 현실에서 이동은 레이-기반 텔레포트를 통해 제공되며, 조이스틱에서 추가 스냅턴을 사용할 수 있습니다. 이동은 XR 상호작용 툴킷에 의해 관리되며, 요청이 있을 때만 텔레포트 레이가 활성화되도록 일부 수정되었습니다.

데스크톱 버전에서는 사용자가 키보드를 사용하여 이동하거나 마우스 왼쪽 버튼을 클릭하여 이동할 수 있습니다. 이동은 DesktopControllerMouseTeleport 컴포넌트가, 카메라 이동은 MouseCamera 컴포넌트가 오른쪽 클릭을 사용하여 관리합니다.

원격 사용자의 경우 플레이 영역 이동이 부드러워져 대상 위치로 점차 이동함으로써 텔레포트가 대체됩니다(instantPlayareaTeleport 옵션이 true로 설정되어 있는 경우 제외).

이동 제한

이 예제 애플리케이션은 사용자가 특정 위치로 이동하지 못하도록 하는 경우가 있습니다(예: 최대 용량에 도달하면 채팅 버블에 들어갈 수 없음).

이렇게 하려면 사용자를 이동하려는 모든 컴포넌트가 일반 이동 검증 시스템과 특정 이동 모드와 관련된 제약 조건에 모두 의존적이어야 합니다.

이동 유효성 검증 시스템

사용자가 금지 지역으로 이동하려는 것이 아닌지 판단하기 위해 모든 이동 시스템은 먼저 CanMove() 메소드를 사용하여 XRHardwareRig에 이 위치로 이동할 수 있는지 묻습니다. 답변하기 위해 XRHardwareRig는 먼저 이동이 모든 ILocomotionValidator 하위 항목과 네트워크의 로컬 사용자를 나타내는 XRNetworkedRig 인스턴스의 모든 ILocomotionValidator 하위 항목에 대해 유효한지 확인합니다.

locomotion system

또한 사용자가 금지 구역에 머리를 배치하면 보기가 희미해져 “부정행위”를 방지할 수 있습니다. \

기타 제한

또한, 이동은 사용되는 이동 시스템에 따라 다른 요인에 의해 제한됩니다.

  • XRIT 이동: 사용자는 TeleportArea 컴포넌트가 있는 객체에서만 순간이동할 수 있습니다.
  • DesktopController 이동: 컨트롤러는 콜라이더 내부에 있지 않은지 확인하고 이동 후 올바른 보행형 내비게이션 메시 지점이 콜라이더 아래에 있는지 확인하여 이동 후 헤드 위치가 올바른지 확인합니다.
  • 봇: 봇이 이동 가능한 내비게이션 메시에 머무르도록 합니다.

터치 가능

손가락 터치 시 이벤트를 트리거 하기 위해 손에는 Toucher 컴포넌트가 있는 반면 일부 객체는 Touchable 컴포넌트가 있습니다. 이벤트는 하드웨어 리그 내에서 완전히 처리되며 네트워크에 대한 자동 링크가 없으므로 Touchable.OnTouch로 불리는 컴포넌트에서 처리해야 합니다.

데스크톱 컨트롤에서는 마우스 포인터로 Touchable을 터치할 수 있습니다.

잡기

잡기는 이 샘플에서만 펜 및 드로잉 조작을 처리하는 데 사용됩니다.

잡기 시스템은 Tracker 클래스를 기반으로 합니다. 네트워크 객체가 다양한 추적 논리(순간 이동, 힘 기반 이동 등)를 사용하여 다른 객체(손과 같은)를 추적할 수 있습니다. 또한 필요한 경우 추정을 처리하며, 권한 변경 시 자연스러운 움직임, 사용된 추적 로직이 이를 지원할 때 물체와의 충돌 등을 처리합니다.

추적 시스템은 공유 토폴로지 및 호스트 토폴로지를 모두 지원하도록 구축되었으며, 여기에서는 그 기능의 극히 일부가 사용됩니다. 특히 여기서는 순간 추적에만 사용되며 강제 추적에는 사용되지 않습니다.

여기서 실제 잡기는 XR 상호 작용 툴킷을 사용하여 로컬에서 수행됩니다. 그런 다음 움켜쥔 개체가 움켜쥔 손을 추적(“팔로우”)한다는 사실은 Tracker 컴포넌트의 네트워크를 통해 공유됩니다.

입력 시스템은 잡는 하드웨어 손에서 네트워크 손까지 이 정보를 전달하고 네트워크 손은 최종적으로 Tracker에 경고합니다.

아바타

사용자는 아바타라고 불리는 그래픽 표현으로 표현됩니다. 이 샘플은 Ready Player Me의 아바타와 사용자가 정의하는 단순 아바타의 두 가지 종류를 지원합니다.

Gazer

보다 자연스러운 아바타를 표현하기 위해, 전용 시스템은 자동 시선 추적을 처리합니다: 관심 있는 객체가 아바타 앞에 제시되면, 눈은 이 대상을 찾고 그것을 따라갑니다. 더 가까운 목표물이 제시되면 눈의 초점이 변경됩니다.

사용할 수 있는 대상이 없는 경우 눈은 무작위로 때때로 움직입니다.

마지막으로, 이 샘플에서 사용할 수 있는 모든 아바타 시스템은 눈 깜빡임을 처리하며, 또한 더 자연스럽게 보입니다.

잠재적인 눈 대상이 되려면 게임 오브젝트에 GazeTarget 컴포넌트가 있어야 합니다. 모든 아바타의 눈과 머리에는 기본적으로 사전 구축된 프리팹에 이러한 컴포넌트가 있습니다. GazeTargetGazeInfo manager에 등록됩니다.

Gazer 컴포넌트는 GazeInfo에게 GazeTarge의 잠재적인 정렬된 목록(거리별)을 질문함으로써 눈을 조정합니다.

사용 가능한 대상이 많이 가까울 때 정렬 프로세스는 상당히 무거우며 백그라운드 스레드에서 수행됩니다.

gaze system

핸드

여기에 사용된 핸드 모델은 Oculus 샘플 프레임워크(Facebook Technologies, LLC 및 해당 계열사에서 BSD-3 라이선스로 배포됨)에서 가져온 것입니다.

손의 움직임을 주도하는 입력 동작은 로컬로 수집되고 Fusion을 통해 공유되어 모든 클라이언트에 손의 움직임을 표시합니다.

손의 움직임은 변화의 빈도를 줄이기 위해 원격으로 약간 분산됩니다.

손 색깔은 사용된 아바타 표현의 피부색과 일치합니다.

AvatarRepresentaiton

각 아바타는 avatarURL을 저장하며 XRNetworkedRig 컴포넌트 내의 Fusion [Networked] 변수를 통해 공유됩니다.

변경 시 이 URL은 AvatarRepresentation 컴포넌트에 의해 분석되어 다음을 나타내는지 확인합니다:

간단한 아바타

간단한 아바타 시스템은 간단하고 저렴한 아바타 모델을 제공합니다.

입 애니메이션은 볼륨 감지를 기반으로 하며, 정확한 입술의 동기화는 없습니다.

Ready Player Me

Ready Player Me 아바타 시스템은 https://readyplayer.me에서 제공되는 모든 아바타를 표시할 수 있습니다.

입 애니메이션은 Oculus Audio SDK 라이선스로 출시된 Oculus Lip Sync 라이브러리를 기반으로 립 동기화를 제공합니다(https://developer.oculus.com/licenses/audio-3.3/).

지정된 아바타 URL에 대해 아바타 다운로드 및 로딩을 최적화하기 위해 아바타 객체를 여러 가지 방법으로 로드할 수 있습니다:

  • 이 URL이 활성 아바타에 이미 사용된 경우 기존 아바타가 복제됩니다.
  • 이 URL이 프리팹에 연결되어 있으면 glb 파일을 다운로드하고 파싱 하는 대신 프리팹이 생성됩니다.
  • 이러한 옵션이 관련되지 않으면 glb 파일이 다운로드되고 파싱 됩니다. URL은 URL에 %StreamingAssets%/Woman1.glb 구문을 사용하여 다운로드를 건너뛰려면 StreamingAssets 폴더에 있는 glb 파일을 만들 수 있습니다. 만약 그렇게 한다면 Ready Player Me에서 제공하는 Woman1.json 메타데이터에 관련된 Woman1.glb 파일 옆에 배치해야 합니다(다운로드하려면 Ready Player Me에서 제공하는 원시 URL 내에 있는 단순히 .glb 확장자를 .json으로 바꾸면 됩니다).

LOD

사용자(또는 봇)가 많은 세션에서 아바타는 성능에 큰 영향을 미칠 수 있습니다.

이를 방지하기 위해 아바타 표현은 다음과 같은 여러 LOD를 관리합니다:

  • 일반 아바타(단순 아바타 또는 Ready Player Me)
  • 일반 아바타의 머리/피부/옷 색상과 일치하는 심플한 아바타의 낮은 폴리 버전입니다.
  • 빌보드가 항상 사용자 카메라를 향하고 있습니다.

채팅 버블

이 샘플은 채팅 버블을 보여줍니다. 이 씬에는 4개의 정적 채팅 버블이 포함됩니다. 프로그램은 또한 두 명의 사용자가 서로 가까워질 때 동적 채팅 버블을 만들 수 있습니다.

정적 채팅 버블

정적 채팅 버블

기본적으로 엑스포 씬에서 사용자는 서로의 소리를 들을 수 없습니다.

그러나 그들이 같은 정적 채팅 버블에 들어가면, Photon Voice를 통해 공간화된 소리로 함께 대화할 수 있을 것입니다.

zone system

이 샘플에서 영역 시스템은 XRNetworkedRigZone에 가까운 ZoneUser 컴포넌트를 추적합니다. 이 경우 ZoneUser가 영역에 진입하여 다양한 ZoneZoneUser 리스너를 트리거 합니다.

Zone은 PhotonVoice 관심 그룹을 연결할 수 있으므로, ZoneAudioInterestChanger컴포넌트는 로컬 사용자가 영역을 출입할 경우 해당 사용자의 오디오 청취 및 녹음 그룹을 변경할 수 있습니다.

정적 채팅 버블은 최대 사용자 수에 도달하면 자동으로 잠기지만, 모든 정적 채팅 버블에서 사용 가능한 잠금 버튼을 눌러 그전에 잠글 수도 있습니다.

동적 채팅 버블

사용자를 나타내는 프리팹은 DynamicZoneSource 컴포넌트가 포함되어 있습니다.

동적 zone 시스템

이 컴포넌트는 DynamicZonePool 컴포넌트에 등록하여 DynamicZonePool.size에 정의된 대로 기존의 다른 DynamicZoneSource가 근접해 있는지 확인할 수 있습니다. 이 경우 DynamicZonepool은 두 사용자 모두에 사용할 스폰(또는 재사용)되는 영역을 제공할 수 있습니다.

다른 사용자가 영역의 최대 용량에 도달할 때까지 나중에 가입할 수 있습니다.

동적 zone 스폰

사람으로 가득 찬 엑스포를 샘플이 어떻게 지원하는지 보여주기 위해 일반 사용자 외에도 봇을 만들 수 있습니다.

봇은 음성이 비활성화되고 사용자 입력 대신 탐색 메시에 의해 구동되는 일반 네트워크 프리팹입니다.

Bot 클래스도 이동 검증 시스템을 사용하여 채팅 버블을 인식합니다. 게다가, 그들은 말을 할 수 없기 때문에, 잠겨 있든 없든 어떤 구역에도 들어가는 것이 금지되어 있습니다.

드로잉

3D 드로잉

엑스포 씬에는 3D 드로잉을 만들 수 있는 3D 펜이 포함되어 있습니다. 즉, 잡고 이동할 수 있는 공통 핸들이 있는 라인 렌더러 그룹입니다.

3D 펜에는 Drawer 컴포넌트가 들어 있어 Draw 컴포넌트를 고정하는 드로잉 프리팹이 생성됩니다. Draw 컴포넌트는 그려진 모든 점이 Fusion을 통해 동기화되도록 합니다. 이 작업은 [Networked] 변수를 통해 수행됩니다. 무한정 많은 점을 담을 수 없기 때문에 필요할 때 여러 부분으로 분할하면 사용자가 이동할 때 첫 번째 Draw 에 이은 2차 Draw 가 하나의 드로잉으로 나타납니다.

2D 드로잉

엑스포 씬의 보드는 펜으로 작성할 수 있으며, 결과 드로잉을 3D 펜 드로잉의 핸들과 유사한 핸들로 보드에서 이동할 수 있습니다.

이것은 사실 레이어 카메라에는 보이지 않지만 보드와 관련된 카메라에는 보이는 레이어를 사용하는 특별한 3D 도면입니다. 그런 다음 카메라는 보드에 표시되는 렌더 텍스처에 드로잉 이미지를 렌더링 합니다.

성능 향상을 위해 이 카메라는 보드 근처의 펜을 사용하거나 펜으로 만든 드로잉을 이동할 때만 활성화됩니다.

다운로드

버전 릴리즈 일자 다운로드
0.0.19 May 12, 2023 Fusion Expo XRShared 0.0.19 Build 192

타사 컴포넌트

Oculus Lipsync

https://developer.oculus.com/licenses/oculussdk/

Oculus 샘플 프레임워크 핸드

Oculus 샘플 프레임워크 라이선스 (BSD3)

Ready player me

GLTF 유틸리티

https://github.com/Siccity/GLTFUtility

NewtonSoft.Json

http://docs.unity3d.com/Packages/com.unity.nuget.newtonsoft-json@2.0/license/Third%20Party%20Notices.html

음향

nathangibson-Universal UI 사운드팩

obsydianx-interface-sfx-pack-1

TextMesh Pro

알려진 이슈

  • 가끔 어떤 봇들은 땅으로 스폰 되어 움직이지 않습니다.
  • Oculus Quest : 헤드셋이 대기 모드일 때는 오랜 시간 동안 애플리케이션을 종료할 수 없습니다. 그런 다음 헤드셋을 재부팅해야 합니다.
  • 드로잉의 권한 연결이 끊기는 동안 사용자가 연결하면 새 사용자가 드로잉 데이터를 수신하지 않습니다.
Back to top