기타/해커톤

[기술스택 설명] 메타버스 수도 경북 해커톤, 유니티-리액트&iOS-스프링

kyxxn 2024. 1. 4. 14:07
728x90

본 게시물은 메타버스 수도 경북 해커톤에 참가하여 어떤 기술스택을 사용하여
프로젝트에 녹아냈는 지에 대해 기술해보겠다.

전체적 흐름도


확장형 하이브리드 메타버스 플랫폼으로써 메타버스 요소를 유니티로 구현한 다음
해당 내용을 웹, 앱과 같이 접근성이 뛰어난 다양한 플랫폼에서 유니티를 동작하게 하고 싶었다.
그래서 웹/앱에서 로그인을 하면 유니티 게임 속으로 진입하여 멀티플레이 및 안전 시나리오를 할 수 있다.

멀티 흐름도


웹 페이지에서는 리액트, 앱에서는 iOS라 생각하고 봐주면 이해가 쉽다.
리액트와 iOS는 연결 매개체로 유니티와 서버의 상호작용을 전달받고 전달해주는 역할이다.
서버 측에서는 stateless가 없는 웹소켓을 활용하여 데이터들을 양방향으로 멀티플레이를 구현했다.
유니티 측에서는 오브젝트의 transform 정보를 비롯한 게임 점수 등을
전처리 조건문에 의해 빌드가 되어도 해당 조건문이 웹에서 동작하도록 한다.

주요 코드

유니티 -> 리액트


WebGL로 빌드 시 디렉토리가 생성이 되는데, 그 중 'build'라는 디렉토리 내부에
4개의 파일을 리액트에서 useUnityContext 훅을 사용하여 연결해준 다음 Unity 태그에 unityProvider로 넣어준다.
이러면 웹에서 유니티를 띄울 준비는 끝이다.

 


유니티에서 리액트로 보내는 클래스의 중 일부이다.
[DllImport("__Internal")]와 static extern을 포함한 메소드를 선언하고,
메소드 내에서는 #if UNITY_WEBGL == true && UNITY_EDITOR == false을 통해 WebGL로 빌드된 환경에서만 동작하는 이벤트를 생성한다.

리액트가 유니티로부터 메세지를 받으면


유니티의 전처리 조건문에 의해 BuildComplete 함수가 호출되면,
리액트에서 이 함수를 요청받으면 useUnityContext 훅에 있는 addEventListener를 통해 UnityFirstSetting라는 메소드가 실행된다.


UnityFirstSetting 메소드는 로그인 하였던 아이디에 대한 게임 정보 (닉네임, 점수)를 서버로부터 받아와서
해당 내용의 문자열을 JSON으로 변환하여 useUnityContext 훅에 있는 sendMessage를 통해 다시 유니티로 넘겨준다.

리액트 -> 유니티


유니티 내부에 GameMode라는 오브젝트를 찾고, 그 안에 StatfromReact라는 메소드를 JSON 타입인 jsonUserData를 파라미터로 넘겨주며 호출한다.

서버 -> 리액트 -> 유니티


웹소켓으로 구독되어 있는 채널로부터 데이터를 받으면 해당 JSON 내용을 parse하여 문자열이 변환된 JavaScript 객체를
위와 같이 SendMessage로 유니티에게 보내준다.

정리

위처럼 웹소켓, 유니티에서의 전처리 조건문을 어떻게 이용하는 지 간단하게 설명했다.
위 로직은 빌드되었을 때만 동작하는 주 내용들을 담았고, 실제로는 채팅 기능과 다른 캐릭터 혹은 내 캐릭터가 움직이면
모두 웹소켓으로 다른 클라이언트에게 영향을 주게 된다.

본 해커톤을 준비하기 위해 자료를 찾아보았으니 유니티를 웹에 빌드하는 과정만 보여주는 블로그밖에 없었다.


https://react-unity-webgl.dev/docs/8.x.x/concepts/unity-context
그래서 위 사진의 useUnityContext에 대한 훅을 정리한 공식문서를 보며 번역해가며 이해했다.
처음에는 웹소켓 연결이 잘 되는지, 전처리 조건문이 제대로 동작할지 등 이론에 대한 확신은 있었으나

실제로 구현된 것을 한 번도 본 적이 없어서 불안해 했다.


그러다 실제로 밤을 새워가며 팀원들과 프로젝트 한 결과

처음 멀티플레이, 다중 사용자 시스템을 구현해냈을 때 쾌감이 엄청났다.
성취감에 밤을 새고도 기분이 좋았던 하루였다.