저번글 https://gall.dcinside.com/mgallery/board/view/?id=vr&no=3391658 에서는 월드 마스터를 중심으로 한 동기화변수와 전반적인 이벤트 트리거에 대해 다뤘다면
이번엔 오브젝트의 동기화에 대해 다룰 예정
저번글에서도 썼듯이 유저 모두 각자의 씬을 가지고 있고 모든 게임 오브젝트는 기본적으로 로컬이며 동기화 시키기 위해선 끊임없이 정보를 주고받게 만들어야됨
브챗에선 오브젝트들의 동기화를 위해 VRC Object Sync라는 스크립트를 제공해서 제작자가 오브젝트 동기화를 직접 구현할 필요가 없게 만들어놨음

글로벌로 만들고 싶은 오브젝트에 이 스크립트를 추가해주면 알아서 동기화 시켜줌
얘가 맘에 안들어서 동기화를 직접 구현한 스크립트들도 있지만 아주 특별한 상황이 아니라면 얘로도 충분함
Udonsharp에선 VRC.SDK3.Components.VRCObjectSync 클래스로 사용가능하고 메소드가 5개가 있는데 사실상 써먹는건 FlagDiscontinuity()랑 Respawn() 이렇게 2가지임
Respawn()은 오브젝트를 초기 위치 상태로 돌려놓는 메소드임
월드에서 자주 보이는 리스폰 버튼 누르면 글로벌 오브젝트들이 싹 정리되는데 이걸 이용한것
FlagDiscontinuity()는 오브젝트를 순간이동 시키고 싶을때 사용함 이 함수를 호출하면 해당 프레임에서 일어난 오브젝트 이동은 smoothing하는 과정 없이 말그대로 순간이동처럼 보임
사실 TeleportTo()라는 메소드가 따로 있는데 기억상 구데기라서 밑에처럼 따로 라이브러리 만들어서 쓰고있음

대충 Rigidbody 물리량들을 초기화하고 위치 옮긴 뒤에 FlagDiscontinuity()를 트리거하는 식
몸통 젤 첫줄에 보면 오브젝트의 오너를 설정해주는 부분이 있는데 사실 VRCObjectSync를 통한 동기화는 오브젝트의 오너를 중심으로 이뤄짐
저번 글의 월드 마스터 중심으로 이뤄지던 변수나 이벤트 동기화랑 다른 부분이라 알아두고 있어야됨
오너쉽 이동은 플레이어가 물체를 잡았을때 자동으로 해당 오브젝트의 오너가 되고 직접 제어하고 싶다면 저렇게 Networking.SetOwner()로 요청할 수도 있음
이벤트 등을 통해 직접 오브젝트를 움직이고 싶다면 월드 마스터에 오너를 넘긴뒤에 하는게 디버깅에도 간편하고 좋음
오우나쉽 이동에 관한건 이렇게 한짤 요약이 돼있으니 참조

마지막으로 VRCObjectSync는 Transform이랑 Rigidbody는 동기화 시켜주지만 해당 오브젝트의 active상태는 동기화요소가 아니라는걸 알아둬야됨
그래서 오브젝트의 글로벌 온오프는 따로 이벤트로 구현하거나 VRC.SDK3.Components.VRCObjectPool를 사용할 수도 있음
VRCObjectPool은 많은 수의 글로벌 오브젝트를 관리할 때 편함 얘의 장점은 pool에 들어있는 오브젝트들의 활성화 상태를 자동으로 동기화 시켜준다는 점임
뒤늦게 조인한 플레이어를 위해 따로 온오프 상태 업데이트 구현을 안해줘도 된다는것

클래스 프로퍼티인 GameObject[] Pool로 각각 오브젝트들에 접근할 수있고
VRCObjectPool에 할당된 오브젝트들은 런타임시에 전부 비활성 상태로 로드됨
오브젝는 TryToSpawn()을 통해 활성화, Return()을 통해 비활성화 할 수 있고 얘네를 써야만 제대로 활성화 상태가 동기화됨
근데 참으로 찐빠스럽게도 TryToSpawn()에는 오브젝트 인수를 넘길 수 없고 Pool 인덱스 순서대로 활성화됨 (좆병신같음)
웃긴건 Return()에는 오브젝트를 넘겨줄 수 있다는 점임 (개좆병신임?)
암튼 그래서 원하는 오브젝트만 활성화 시키려면 Pool루프를 돌리면서 TryToSpawn()으로 전부 활성화 시키고 원하지 않는건 Return()해서 원하는거만 남겨두는 병신같은 똥꼬쇼를 해야됨

그래서 그냥 게임오브젝트 기본 SetActive()를 사용하고 동기화는 이벤트로 따로 구현하는게 편할때도 있으니 취향대로 하면됨
보너스로 VRCObjectPool엔 Shuffle()이라는 메소드도 있는데 말그대로 Pool을 섞어줌 TryToSpawn()호출 전에 Shuffle()하면 카드 랜덤 뽑기 같은걸 구현할 수 있음

인겜에서 오브젝트 동기화 현황은 6번 디버깅 창으로 볼 수 있고

이렇게 오너가 누군지 깨있는지 잠들어있는지 (잠들어있는 상태면 동기화를 멈춤) 오너랑 다른 플레이어들 사이의 딜레이가 얼마나 되는지 보내는 바이트 사이즈랑 초당 얼마나 보내는지 마지막으로 동기화 되고 얼마나 지났는지 동기화 빈도등을 hz단위로 볼 수 있음

8번 메뉴로는 이렇게 각각 오브젝트 별로도 볼 수 있으니 참조
오브젝트 동기화에 대한건 이걸로 거의 다 쓴듯