Overview
com.111percent.utilities.percent-toolbar-visualizer
이게 뭔가요?
Unity 2021.3 버전 이후 Unity Technology에서 개발한 VisualElement 라이브러리가 Unity Editor IMGUI 를 대처하고 있습니다.
이 패키지는 하드코딩된 IMGUI 코드를 유니티에서 접근 및 제어 가능하도록 변경된 부분을 모두 접근 및 수정할 수 있도록 지원하는 패키지입니다.
왜 필요한가요?
유니티에서는 개인 또는 회사를 위한 기능들 (Plastic SCM, Code Coverage, Version Control, Cloud Service etc..)을 제공하고 있습니다만,
실제 이 기능들을 사용하기엔 비용이 들거나 관리가 어렵거나 하는 등 사용하기 어려운 경우가 있어 사용하지 않고 있습니다.
하지만 사용하지 않아 해당 패키지를 삭제해도, 유니티 에디터 내부 아이콘은 삭제되지 않습니다.
로그인, 유니티 서비스 버튼, 버전 컨트롤 등등..
이 패키지는 이런 불필요한 버튼을 제거하거나 기존 유니티 내장 버튼을 삭제하고 새로운 기능을 추가할 수 있도록 합니다.
만약 VisualElement 형식을 사용하지 않고 제작한다면,
- 기존 ImGUI 코드를 대처하려면 오픈소스인 Harmony 또는 리플렉션, Unity InternalAssembly 0 ~ 45번대 등 직접적으로 가리켜야 합니다.
- 패치되면 모두 막혀버리는 대참사 ..
- 초기화 시점을 알 수 없음.
- IMGUI Style 값을 조정하려면 GUIStyle 코드만 몇백줄 작성해야 하는 문제가 ..
- 눈으로 보면서 작업할 수 없음.
2023 버전 이상부터는 유니티 테크놀로지에서 인지하여 많은 부분을 VisualElement 으로 대처하고 있습니다.
어떻게 사용하나요?
Caution
기존 오픈소스 (Toolbar Extension, Unity Toolbar Editor 등등..)는 호환되지 않습니다.
- 정확하게 말하면, VisualElement 요소로 작성된 확장이 아닌 경우 호환되지 않습니다.
상단에 있는 콘텐츠 기능에 대해 설명합니다. (좌측부터)
Version → Application 버전을 변경할 수 있습니다.
Build Mode → 빌드 환경을 자동으로 변경합니다.
- Percent Firebase Environment 패키지가 있는 경우 호환됩니다.
Active Scene → 현재 SceneView 에서 표시되는 씬을 보여주며, 다른 씬으로 편리하게 전환할 수 있습니다.
Button
- L → 해당 장면을 불러옵니다. (Load)
- P → 해당 장면이 Project 위치에 어디있는지 확인합니다. (Ping)
- 해당 장면에 커서를 올리면 해당 장면에 대한 위치를 툴팁으로 표시합니다.
Scale Time → 게임의 플레이 속도를 변경할 수 있습니다.
- Scale Time 라벨을 클릭할 시 아래 이미지와 같이 Draw GUI 형식을 변경할 수 있습니다.
Toggle Button
Slider
Frame Rate → 게임의 FPS를 제어할 수 있습니다. (1.1.0 버전 이후 버튼으로 변경할 예정)
- -1 인 경우 OS의 기본 FPS를 사용합니다.
특정 콘텐츠에 대한 값이 변경되는 이벤트를 구독하는 방법
Top Toolbar Content
해당 콘텐츠에 대한 콜백 기능을 제공합니다 (After Callback)
- Version → (event)
GameVersionChanger.OnChangedGameVersion
- Build Mode → (event)
EnvironmentSynbolController.OnChangedDefineSymbol
- Active Scene → 유니티에서 제공하는 기능을 사용한 것과 같습니다.
- (event)
UnityEditor.SceneManagement.EditorSceneManager.activeSceneChangedInEditMode
- (event)
- Scale Time → (event)
GameTimeScaleChanger.OnChangedTimeScale
- Frame Rate → (event)
ApplicationFrameRateChanger.OnChangedFrameRate
직접 콘텐츠를 제작하여 삽입하는 방법
Note
현재는 상단 툴바에서만 콘텐츠를 주입하는 방법을 지원합니다.
OnInitializedContainer
아래 이벤트는 상단의 VisualElement 객체들이 초기화될 때 호출되는 초기화 이벤트 입니다.
public static class ToolbarContentVisualizer
{
// ...
public static event Action<VisualElement> OnInitializedContainerLeft;
public static event Action<VisualElement> OnInitializedContainerPlayMode;
public static event Action<VisualElement> OnInitializedContainerRight;
// ...
}
// 아래 코드는 플레이모드 버튼이 초기화될 때 MyCustomContainer 객체를 할당하고 생성자를 호출하는 예시입니다.
public class MyCustomContainer
{
[InitializeToolbarOnLoadMethod(0)]
static void OnInitialize()
=> ToolbarContentVisualizer.OnInitializedContainerPlayMode += (root) => _ = new MyCustomContainer(root);
internal MyCustomContainer(VisualElement root)
{
// 코드 작성 ..
}
}
InitializeToolbarOnLoadMethod
아래 속성을 사용하여 객체 초기화 시 초기화 순서를 변경할 수 있습니다.
// 적재될 객체의 초기화 순서를 정하는 속성입니다.
// OnInitialize() 함수는 두 번째(0, 1, 2, 3, ...) 부터 실행합니다.
[InitializeToolbarOnLoadMethod(1)]
static void OnInitialize()
=> ToolbarContentVisualizer.OnInitializedContainerLeft += (root) => _ = new GameSceneController(root);
예시
아래 예시에서는 이미지와 같이 플레이 버튼 오른쪽에 버튼을 추가하는 스크립트를 예시로 합니다.
- 오른쪽에 버튼 생성
- 왼쪽에 버튼 생성
// 아래 예시에서는 게임 플레이 버튼의 왼쪽 또는 오른쪽에 버튼을 삽입하고 클릭하는 예시입니다.
public class MyCustomButotnActionController
{
// 툴바가 생성될 때 호출되도록 하는 속성값 입니다. 순서를 지정할 수 있습니다.
[InitializeToolbarOnLoadMethod(0)]
// ToolbarContentVisualizer.OnInitializedContainerPlayMode <- 플레이 버튼을 자식으로 가진 VisualElement 요소를 반환하는 이벤트입니다.
static void OnInitialize()
=> ToolbarContentVisualizer.OnInitializedContainerPlayMode += (root) => _ = new MyCustomButotnActionController(root);
internal MyCustomButotnActionController(VisualElement root)
{
// 왼쪽에 버튼을 생성하고 싶은 경우
// root.contentContainer.Insert(0, new IMGUIContainer(OnGUIContainer));
// 오른쪽에 버튼을 생성하고 싶은 경우
root.contentContainer.Add(new IMGUIContainer(OnGUIContainer));
}
private void OnGUIContainer()
{
if (GUILayout.Button("My Button"))
{
Debug.Log("Click!");
}
}
}