본문 바로가기

Unity/Articles

Unity: 플러그인에 사용하기엔 계륵같은 존재, UI Toolkit

작년 3,4분기에 열심히 개발하던 AssetLens라는 이름의 종속성 탐지 기능이 중점인 플러그인이 있습니다. 지금도 작게나마 관리중이지만, 플러그인의 특성상 다양한 버전의 유니티 에디터를 지원해야하는 어려움에 부딪혀 점차 개발속도가 느려지다 끝내 소소한 버그픽스만 진행하고 있습니다. 가장 큰 문제는 한 번만 작업하고도 여러 버전의 에디터를 동시에 지원하고 싶은 욕심이 불러온 복잡한 개발 파이프라인입니다. 

 

 

GitHub - seonghwan-dev/AssetLens: Asset Lens : Unity asset reference management utility working in background. 에디터 백그

Asset Lens : Unity asset reference management utility working in background. 에디터 백그라운드에서 관리되는 유니티 에셋 파일 레퍼런스 데이터 도구. - GitHub - seonghwan-dev/AssetLens: Asset Lens : Unity asset reference manageme

github.com

 

최신 버전이 거듭 공개됨에 따라 UI Elements라는 이름의 Editor/Runtime 공용 UI Framework는 UI Toolkit이라는 새로운 이름을 가지게 되고, 뿐만 아니라 작업 방식과 문법, 인식용 키워드들의 변화가 있었습니다. 이전버전에 구현되지 않았던 기본 컨트롤러(HelpBox 등)들이 추가되고, 리소스 에셋을 바인딩하는 방식도 수 차례 변경되었습니다. 항상 최신버전에서 작업을 이어가던 저로서는 알게 모르게 최신 버전의 기능을 사용하게 되고, 곧이어 이전 버전에서의 컴파일 에러 또는 추적하기 어려운 버그를 발생시켰습니다. 필연적으로 새로운 작업을 하고나면 수작업으로 여러 버전에서 구동을 확인하고 테스트하는 과정이 동반되어야 하고, 이는 과도한 작업 스트레스로 다가왔습니다. 

 

 

그래서 이를 자동화하고자 선택한 방법은 GitHub Action과 Unit Test의 힘을 빌리는 것입니다. 각 테스트를 위한 버전으로 Code Coverage 프로필을 세팅해두고, 메인 브랜치를 대상으로 한 PR이 생성되면 커버리지 CI 가 돌면서 컴파일 에러 및 유닛 테스트를 진행하는 것입니다. 

 

총 4가지의 커버리지 액션이 등록되어있고, 순차적으로 플러그인을 사용한 유닛 테스트를 수행합니다. 유닛테스트라 하니 거창한 무언가 존재할 것 같지만, 개발에 치여 아직 그럴듯한 테스트를 수행하지는 못하고 있습니다. 우선적으로 컴파일에러만이라도 막기 위한 수단으로 활용되고 있는 실정입니다. 

 

어느 정도의 컴파일 에러와 버전대응은 이것으로 마무리되는가 싶었지만, 의외로 꽤 성가신 타입의 문제도 존재했습니다. UI Toolkit은 기본적으로 uxml + uss 조합으로 이루어지는데, 웹 개발에서의 html + css 정도 역할로 간편하게 생각할 수 있습니다. html 만큼의 자유도를 가지지는 못하지만, uxml은 레이아웃과 초기값을 담당하며 uss는 스타일시트입니다. 그런데, 상위 버전의 uss 선택자를 사용하면 하위 버전의 에디터에서는 그 검증단계에서 에셋 데이터베이스가 새로고침되어 에셋이 임포트 될 때 마다 에러를 뱉습니다.

 

상위 버전에 새로 생긴 선택자를 파싱하는데 실패해 생기는 오류인데요, 이 검증을 해제하는 옵션이 존재하지만 의도하는 대로 동작하지 않습니다. 

하위버전에서는 이 옵션을 끄더라도, Validation을 하지만 않을 뿐 Warning을 계속해서 콘솔에 출력하여 사용자를 성가시게 합니다. 개인 개발이라면 참고 넘길 수도 있겠지만, 불특정 다수가 사용해야 할 플러그인이라면 이는 사용자를 매우 불쾌하게 만들 수 있는 요소입니다. 

 

css에서는 해당 뷰를 렌더링하는 브라우저에서 선택자가 구현되어있는지 여부에 따라 선택자가 실행되도록 하는 @supports 같은 키워드가 존재합니다. 혹시나 uss에서도 그와 유사한 기능이 있을까 하여 기대했지만, 그런 일은 일어나지 않았습니다. 포럼에 묻고 건의했으나, 언제나 그랬듯 릴리즈 매니저의 시큰둥한 반응을 들어줘야 했습니다.

 

 

어쩔 수 없이 마지막으로 선택한 방법은 유니티 에디터가 인식하지 못하는 폴더에 리소스를 담아둔 뒤, 에디터 콜백에서 직접 파일을 복사해주어 사용하는 것입니다. 이 방식은 아래 코드에서 확인할 수 있습니다.

 

https://github.com/seonghwan-dev/AssetLens/blob/main/Packages/com.calci.assetlens/Editor/Reference/Callback/ReferenceEntrypoint.cs#L26

 

GitHub - seonghwan-dev/AssetLens: Asset Lens : Unity asset reference management utility working in background. 에디터 백그

Asset Lens : Unity asset reference management utility working in background. 에디터 백그라운드에서 관리되는 유니티 에셋 파일 레퍼런스 데이터 도구. - GitHub - seonghwan-dev/AssetLens: Asset Lens : Unity asset reference manageme

github.com

 

 

이렇게 원하지 않는 리소스를 유니티 에디터가 자동으로 임포트 하지 않도록 우회했지만, 이 방식에는 두 가지 치명적인 단점이 존재합니다. 

 

첫 번째로는, UI Builder와 같은 기능을 사용하면서 개발하기가 어렵습니다.

버전별로 uss를 분리하였으므로, uxml에 적용시킨 모습을 UI Builder에서 보기 번거롭고 실제 렌더링 모습과 디버거 뷰를 통해 작업을 진행하는쪽이 빠릅니다. 추가로, uxml에서 uss를 직접 등록하면, 리소스 추가 방식 문법의 변경점으로 인해 불필요한 에러와 경고메시지를 열람해야만 합니다. 이는 전혀 우회하여 작업할 방법이 없어서 마지막 수단인 C# 스크립트에서 uss를 임의로 추가해주는 식으로 변경했습니다.

 

두 번째로는, 컴파일 때 마다 에셋 데이터베이스가 리프레쉬된다는 점입니다.

원래 필수적인 1회 리프레쉬가 있지만, 에셋이 변경되었을지도 모르므로 리소스를 우선적으로 덮어쓰기 하는 방식으로 구현되었습니다. 이 작업은 소규모 프로젝트에서는 큰 부하가 아니지만, 많은 수의 에셋이 포함된 프로젝트에서는 에디터 반응성에 영향을 줄 수 있습니다. 

 

사실, 위에서 언급된 문제들은 근본적으로 첫 번째 버전의 UI Elements가 등장할 때 부터 예상했던 이슈들이 아니라면 해결할 수 없는 문제들입니다. 하지만, @supports와 같이, 향후 많은 수정이 있을 것에 대비한 최소한의 안전장치도 없다는 점은 다소 실망스러운 부분입니다. 

단일 프로젝트에서 개발용으로 사용한다면 팀원이 모두 같은 버전을 사용할 테니 생기지 않을 문제이지만, 불특정 다수를 대상으로 지원을 제공해야하는 플러그인의 경우에는 UI Toolkit을 사용하는 것이 생산성 향상에 있어 꽤 치명적으로 작용할 수 있습니다.