}

유니티 XR Plug-in Management #Initialize XR on Startup

VR개발을 하다 보면 에디터를 실행할 때 에어링크로 연결된 기기가 재생이 되지 않고 PC를 이용한 에디터 디버깅이 필요할 때가 종종 생깁니다.

etc-image-0
Initialize XR on Startup

 

에어링크가 연결된 상태임에도 불구하고 PC로 에디터를 컨트롤 하기 위해서는 프로젝트 세팅에 있는 XR 플러그인 매니지먼트의 Initialize XR on Startup부분을 비활성화해주면 됩니다.

 

하지만, 매번 저 윈도우창에 들어가서 껐다 켰다 하기란 매우 불편한 과정입니다.


모습

xr.gif
토글

 

그래서 에디터 상단에 토글을 이용하여 저 부분을 껐다 켰다 할 수 있는 기능을 만들어 보았습니다.

큰 문제는 되지 않으나 윈도우 창에서 토글을 건드려도 에디터 상단 토글은 업데이트 되지 않습니다.

 

따라서, 에디터 상단 토글을 이용하시길 추천드립니다.

 


코드

using System.Reflection;
using UnityEditor;
using UnityEngine;
using UnityEngine.XR.Management;
using UnityToolbarExtender;

[InitializeOnLoad]
public class InitializeXREditorToggle : EditorWindow
{
    private const string InitManagerPrefKey = "InitXRManagerOnStart";
    private static bool InitManagerOnStart;

    static InitializeXREditorToggle()
    {
        // EditorPrefs에서 초기값 불러오기
        InitManagerOnStart = EditorPrefs.GetBool(InitManagerPrefKey, false);
        // XRGeneralSettings.asset과 동기화
        SyncWithXRGeneralSettings();
        // 툴바에 토글 추가
        ToolbarExtender.RightToolbarGUI.Add(ShowToggle);
    }

    private static void ShowToggle()
    {
        XRGeneralSettings generalSettings = XRGeneralSettings.Instance;
        if (generalSettings != null)
        {
            InitManagerOnStart = generalSettings.InitManagerOnStart;
        }
        else
        {
            InitManagerOnStart = EditorPrefs.GetBool(InitManagerPrefKey, false);
        }

        EditorGUI.BeginChangeCheck();
        bool newValue = GUILayout.Toggle(InitManagerOnStart, "Initialize XR[Standalone]");
        if (EditorGUI.EndChangeCheck())
        {
            UpdateInitManagerState(newValue);
        }
        // 강제 재갱신 – 에디터와 PC Play 모드에서 실시간 반영
        EditorApplication.QueuePlayerLoopUpdate();
        UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
    }

    private static void UpdateInitManagerState(bool newState)
    {
        InitManagerOnStart = newState;

        EditorPrefs.SetBool(InitManagerPrefKey, InitManagerOnStart);
        PlayerPrefs.SetInt(InitManagerPrefKey, InitManagerOnStart ? 1 : 0);
        PlayerPrefs.Save();

        // XRGeneralSettings.asset 직접 수정 (AssetDatabase를 통해)
        string[] guids = AssetDatabase.FindAssets("t:XRGeneralSettings");
        if (guids.Length > 0)
        {
            string assetPath = AssetDatabase.GUIDToAssetPath(guids[0]);
            XRGeneralSettings settingsAsset = AssetDatabase.LoadAssetAtPath<XRGeneralSettings>(assetPath);
            if (settingsAsset != null)
            {
                SerializedObject serializedSettings = new SerializedObject(settingsAsset);
                SerializedProperty prop = serializedSettings.FindProperty("m_InitManagerOnStart");
                if (prop != null)
                {
                    prop.boolValue = InitManagerOnStart;
                    serializedSettings.ApplyModifiedProperties();
                }
                EditorUtility.SetDirty(settingsAsset);
                AssetDatabase.SaveAssets();
            }
        }

        // 에디터 내에서 로드된 모든 XRGeneralSettings 인스턴스를 찾아 reflection으로 업데이트
        XRGeneralSettings[] instances = Resources.FindObjectsOfTypeAll<XRGeneralSettings>();
        foreach (var instance in instances)
        {
            FieldInfo field = typeof(XRGeneralSettings).GetField("m_InitManagerOnStart", BindingFlags.NonPublic | BindingFlags.Instance);
            if (field != null)
            {
                field.SetValue(instance, InitManagerOnStart);
            }
            EditorUtility.SetDirty(instance);
        }
    }

    private static void SyncWithXRGeneralSettings()
    {
        XRGeneralSettings generalSettings = XRGeneralSettings.Instance;
        if (generalSettings != null)
        {
            if (generalSettings.InitManagerOnStart != InitManagerOnStart)
            {
                InitManagerOnStart = generalSettings.InitManagerOnStart;
                EditorPrefs.SetBool(InitManagerPrefKey, InitManagerOnStart);
                PlayerPrefs.SetInt(InitManagerPrefKey, InitManagerOnStart ? 1 : 0);
                PlayerPrefs.Save();
            }
        }
    }
}

 

에디터 폴더에서 작성하셔야 합니다.