using UnityEngine; using UnityEditor; using KindRetargeting.Remote; namespace KindRetargeting.Editor { [CustomEditor(typeof(RetargetingRemoteController))] public class RetargetingRemoteControllerEditor : UnityEditor.Editor { private SerializedProperty httpPortProp; private SerializedProperty wsPortProp; private SerializedProperty autoStartProp; private SerializedProperty registeredCharactersProp; private void OnEnable() { httpPortProp = serializedObject.FindProperty("httpPort"); wsPortProp = serializedObject.FindProperty("wsPort"); autoStartProp = serializedObject.FindProperty("autoStart"); registeredCharactersProp = serializedObject.FindProperty("registeredCharacters"); } public override void OnInspectorGUI() { serializedObject.Update(); RetargetingRemoteController controller = (RetargetingRemoteController)target; // 헤더 EditorGUILayout.Space(5); EditorGUILayout.LabelField("리타게팅 웹 리모컨", EditorStyles.boldLabel); EditorGUILayout.Space(5); // 상태 표시 EditorGUILayout.BeginVertical(EditorStyles.helpBox); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("상태:", GUILayout.Width(40)); if (Application.isPlaying) { if (controller.IsRunning) { GUI.color = Color.green; EditorGUILayout.LabelField("실행 중", EditorStyles.boldLabel); GUI.color = Color.white; } else { GUI.color = Color.yellow; EditorGUILayout.LabelField("중지됨", EditorStyles.boldLabel); GUI.color = Color.white; } } else { GUI.color = Color.gray; EditorGUILayout.LabelField("대기 중 (플레이 모드 필요)", EditorStyles.boldLabel); GUI.color = Color.white; } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); EditorGUILayout.Space(10); // 서버 설정 EditorGUILayout.LabelField("서버 설정", EditorStyles.boldLabel); EditorGUILayout.BeginVertical(EditorStyles.helpBox); EditorGUILayout.PropertyField(httpPortProp, new GUIContent("HTTP 포트")); EditorGUILayout.PropertyField(wsPortProp, new GUIContent("WebSocket 포트")); EditorGUILayout.PropertyField(autoStartProp, new GUIContent("자동 시작")); EditorGUILayout.EndVertical(); EditorGUILayout.Space(10); // 접속 URL if (Application.isPlaying && controller.IsRunning) { EditorGUILayout.LabelField("접속 URL", EditorStyles.boldLabel); EditorGUILayout.BeginVertical(EditorStyles.helpBox); string localUrl = $"http://localhost:{httpPortProp.intValue}"; EditorGUILayout.BeginHorizontal(); EditorGUILayout.TextField("로컬", localUrl); if (GUILayout.Button("복사", GUILayout.Width(40))) { EditorGUIUtility.systemCopyBuffer = localUrl; } EditorGUILayout.EndHorizontal(); string localIP = GetLocalIPAddress(); if (!string.IsNullOrEmpty(localIP)) { string networkUrl = $"http://{localIP}:{httpPortProp.intValue}"; EditorGUILayout.BeginHorizontal(); EditorGUILayout.TextField("네트워크", networkUrl); if (GUILayout.Button("복사", GUILayout.Width(40))) { EditorGUIUtility.systemCopyBuffer = networkUrl; } EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndVertical(); } EditorGUILayout.Space(10); // 캐릭터 등록 EditorGUILayout.LabelField("등록된 캐릭터", EditorStyles.boldLabel); EditorGUILayout.PropertyField(registeredCharactersProp, GUIContent.none); // 자동 등록 버튼 EditorGUILayout.Space(5); if (GUILayout.Button("씬에서 캐릭터 자동 찾기")) { AutoFindCharacters(); } EditorGUILayout.Space(10); // 서버 제어 버튼 (플레이 모드에서만) if (Application.isPlaying) { EditorGUILayout.LabelField("서버 제어", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); if (controller.IsRunning) { if (GUILayout.Button("서버 중지", GUILayout.Height(30))) { controller.StopServer(); } } else { if (GUILayout.Button("서버 시작", GUILayout.Height(30))) { controller.StartServer(); } } EditorGUILayout.EndHorizontal(); } serializedObject.ApplyModifiedProperties(); } private void AutoFindCharacters() { var characters = FindObjectsByType(FindObjectsSortMode.None); registeredCharactersProp.ClearArray(); foreach (var character in characters) { int index = registeredCharactersProp.arraySize; registeredCharactersProp.InsertArrayElementAtIndex(index); registeredCharactersProp.GetArrayElementAtIndex(index).objectReferenceValue = character; } serializedObject.ApplyModifiedProperties(); Debug.Log($"[RetargetingRemote] {characters.Length}개의 캐릭터를 찾았습니다."); } private string GetLocalIPAddress() { try { var host = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()); foreach (var ip in host.AddressList) { if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { return ip.ToString(); } } } catch { } return ""; } } }