[Tistory] 코드리뷰

원글 페이지 : 바로가기

목차 유니티 WebGL과 Task AOT, JIT – System.Reflection.Emit Addressable Asset System 기타 내용(람다, event 최적화, 게임 서버 접속) 코드리뷰 ● 유니티 WebGL과 Task 유니티 WebGL은 C#의 Task를 못씁니다. 그 이유는 유니티 WebGL은 싱글스레드만 제공하기 때문입니다. 그래서 개발중에는 별 문제를 못 느낄 수 있지만 실제로 WebGL에서 실행하면 실행이 안되는 것을 알 수 있습니다. 해당 문제를 해결하기 위해서는 코루틴을 통해 비동기를 구현하거나 UniTask라는 패키지를 사용해야 합니다. (https://github.com/Cysharp/UniTask) 유니티는 PlayerLoop 시스템은 초기화와 프레임별 업데이트를 처리하는 다양한 시스템을 포함하며 모든 스크립트가 이 PlayerLoop를 활용하여 게임 플레이를 생성한다고 합니다. 유니티의 스크립트 수명주기가 이 안에서 돌아갑니다. 이 PlayerLoop는 싱글 스레드로 돌아가는데 간단히 생각하면 유니티가 모든 환경을 세팅해주고 사용자에게 일부의 자유(싱글 스레드)를 줬다고 생각합니다. 여기서 UniTask는 C#의 Task를 유니티에 PlayerLoop에 최적화 시킨 패키지입니다. UniTask 메서드는 단일 스레드(PlayerLoop)에서 실행되며, 스레드 풀 기능이 있으나 스레드 풀을 사용하는 경우 WebGL 등 싱글스레드에서 작동하지 않는다고 합니다. UniTask는 PlayerLoop에 최적화 했기에 UniTask메서드는 싱글 스레드라고 봐도 될 것 같습니다. ● AOT, JIT – System.Reflection.Emit Reflection은 메타 데이터를 다루는 기법으로 객체의 타입 정보를 들여다 볼 수 있습니다. *메타 데이터 : 데이터의 데이터가 뜻으로 코드의 데이터(크기, 타입, 정보 등) 등도 가능합니다. Emit은 동적으로 새로운 타입을 만드는 작업을 할 수 있는 네임스페이스입니다. 여기서 문제는 컴파일은 AOT(Ahead Of Time) 방식과 JIT(Just In Time) 2가지 방식이 있고 유니티는 2가지 모두 제공하는데, 유니티에서 ios, WebGL 등(IL2CPP) 특정 플랫폼이 AOT가 강제되며, AOT 방식에서는 Emit으로 동적으로 만든 타입을 확인할 수 없어 문제가 생긴다고 합니다. AOT(Ahead Of Time) : 소스 코드를 미리 컴파일하여 설치 시점에 기계어로 번역합니다. 컴파일을 미리 하기 때문에 실행속도가 상대적으로 빠르지만 대신 설치 속도와 용량은 큰편입니다. 또 이미 컴파일 되어 있으니 효율적입니다. JIT (Just In TIme, 즉시) : 동적번역이라고도 하며, 바이트 코드 수준으로 설치해서, 실행 시점에 바이트 코드를 기계어로 번역(VM)합니다. 앱을 실행하면 그때 컴파일하며 AOT와 장단점이 반대입니다. 실행속도가 느리지만 설치 속도가 빠르고 용량이 적습니다. 또 Hot Reload 기능이 가능합니다. *Hot Reload : 소스코드 재 컴파일 과정 없이 내가 현재 작성하고 있는 수정사항을 바로 확인 가능 기능 *JIT != Interpreter? : 설명만 보면 JIT는 인터프리터와 크게 달라보이지 않고 많은 사람들도 같은 생각이었는데, 다음 글에서 재밌는 예시로 소개합니다. ( https://stackoverflow.com/questions/2426091/what-are-the-differences-between-a-just-in-time-compiler-and-an-interpreter ) 더보기 영국으로 여행을 갔을 때 네이티브, AOT컴파일러, JIT컴파일러, 인터프리터 4명이 있다면 다음과 같이 됩니다. 영어에 능통한 네이티브 언어/어셈블러는 그냥 대화를 하면 됩니다. AOT컴파일러는 여행을 가기 전 영어 사전을 사서 미리 공부합니다. 그 과정에서 Hello, Hi 등 동의어 중 음절이 짧은 것을 알고 대신 사용할 수도 있습니다(최적화). 위 글에서는 미리 정보를 모국어로 바꿔놓는다고 설명합니다. JIT컴파일러는 여행을 가서 대화를 하면서 사전을 보고 그걸 기억(캐싱)합니다. 나중에 다시 대화를 할 때는 기억하고 있는 부분이라면 바로 대화할 수 있습니다.(컴파일하며 캐싱한 기계어 사용)여기서 장점은 다른 국가(플랫폼)에 여행을 간다면 한 단어를 한국어/일본어/영어/독일어 등으로 같이 기억할 필요는 없고 다른 사전을 들고 여행을 가면 됩니다. 인터프리터는 통역가로 여행을 바로 가서 대화하며 그 국가에 맞게 개별적으로 해석합니다. 장점은 미국 여행중 갑자기 한국인, 네덜란드인, 미국인 누구를 만나도 바로바로 대화가 가능합니다.(어떤 코드를 실행할 때마다 기계어로 바꿉니다.) * 신기한 요소 : 안드로이드는 JIT로 실행하게 해 설치 시간을 줄이고 앱을 사용하지 않을 때 AOT로 조금씩 컴파일 한다고 합니다. ● Addressable Asset System 유니티의 어드레서블(Addressables)은 복잡한 라이브 콘텐츠 지원을 위한 Unity 에디터 및 런타임 에셋 관리 시스템입니다. Unity 2019.03부터 공식적으로 지원됩니다. 어드레서블의 주된 기능은 로드할 에셋과 에셋이 로드되는 위치/방식을 분리합니다. 씬, 프리팹, 텍스트 등 모든 에셋을 어드레서블(위치 지정 가능)로 표시하고 고유명을 부여할 수 있습니다. 어드레서블 에셋은 참조 및 로드가 가능하고, 이를 그룹화하여 동적으로 로드하기 위한 번들로 통합할 수 있습니다. 조금 더 간단하게 보면 Addressable(주소 지정 가능) = 주소로 대상(에셋)을 지정(로드) 가능한 에셋 관리 시스템입니다. 실제 위치에 상관없이 에셋에 부여한 address를 기반으로 로드하며 에셋을 효율적으로 관리하거나 서버에서 추가 다운로드 등에 쓰인다고 합니다. 일반적으로 어드레서블을 사용하면 에셋간의 중복을 제거해 메모리 사용량을 줄일 수 있지만, 어드레서블 패키지 자체가 3mb? 정도 크기를 가져서 프로젝트에서는 오히려 메모리가 증가해서 사용하지 않게 되었습니다. *내용을 아직 잘 모르기에 자세한 참고 자료 (유니티 docu, Hammer Impact님의 번역) 더보기 https://docs.unity3d.com/Packages/com.unity.addressables@2.0/manual/AddressableAssetsGettingStarted.html Get started | Addressables | 2.0.6 Get started Contains getting started information to set up and use Addressables for the first time. docs.unity3d.com https://velog.io/@hammerimpact/%EC%9C%A0%EB%8B%88%ED%8B%B0-Addressables-%EB%AC%B8%EC%84%9C-%EB%B2%88%EC%97%AD-4%EC%9E%A5-%EC%96%B4%EB%93%9C%EB%A0%88%EC%84%9C%EB%B8%94%EC%9D%98-%EC%82%AC%EC%9A%A9#%EC%9B%90%EA%B2%A9-%EC%BD%98%ED%85%90%EC%B8%A0-%EB%B0%B0%ED%8F%AC 유니티 Addressables 문서 번역 4장 어드레서블의 사용 유니티 Addressables 문서 번역 4장 어드레서블의 사용유니티/Addressables/유니티 문서/번역/ velog.io 블로그에서 번역을 너무 세심히 해준거 같습니다 ● 기타 내용 람다함수는 내부적으로 클래스를 새로 new로 생성하는 느낌이라 가비지가 쌓이는데, static을 넣어서 하면 내부적으로 static함수가 싱글톤처럼 생성/유지/작동되서 LINQ에서 가능하면 static을 사용하는게 좋습니다. 외부 필드가 필요하면 어떻게든 길을 뚫어주던지 static을 빼던지 하는 방식으로… 유니티는 ui설정에 1, 2프레임 단위가 걸려서 이상작동을 한다면 몇 프레임 대기도 괜찮은 방법일 수 있습니다. event를 사용할 때 미리 빈 delegate{}를 넣어서 null 방지로 속도를 올릴 수 있습니다. 링크드 리스트에서 공간을 더 써서 속도 올린것과 같은.. 로그인에서 JWT 방식을 줬고 Refresh토큰도 넣었는데 로그인, 로비서버, 게임서버가 따로 있고 로비서버에서 매칭이 완료된다면 게임서버에 대한 티켓을 얻고 로비서버 티켓을 잃고, 게임이 끝나면 게임 서버에서 로비서버로의 티켓을 얻고 나가는 방식으로 구현되어있습니다… 로그인 방식 : 로그인 완료시 입장권을 유저에게 주고, 사이트에서 무엇을 할 때 입장권을 체크하는 방식. 세션과 JWT 2가지 방식으로 구분. ■ 세션 방식 : 입장권은 id만 있고 서버가 입장권 id에 유효기간 체크 ■ JWT 방식 : 회원 정보, 유효기간 등 여러 데이터를 가진 입장권이 있고 서버는 입장권이 진짜인지만 체크 장점 : stateless 저장 정보가 없으니 처리도 빠르고 서버가 가질 데이터도 적다. 단점 : 보안이 상대적 부족 * 간략이해 추천영상 ( https://www.youtube.com/watch?v=XXseiON9CV0 )

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다