using UnityEngine; using System.Collections.Generic; /// /// StreamDeck 단일 기능 버튼들을 통합 관리하는 시스템 컨트롤러 /// 각 기능은 서브매니저로 분리되어 있으며, 명령어 디스패치 파사드 역할 /// public class SystemController : MonoBehaviour { [Header("OptiTrack")] public OptiTrackManager optiTrack = new OptiTrackManager(); [Header("Facial Motion Capture")] public FacialMotionManager facialMotion = new FacialMotionManager(); [Header("Motion Recording")] public MotionRecordingManager motionRecording = new MotionRecordingManager(); [Header("Screenshot")] public ScreenshotManager screenshot = new ScreenshotManager(); [Header("Cloth Simulation")] public ClothSimulationManager clothSimulation = new ClothSimulationManager(); [Header("Avatar Head")] public AvatarHeadManager avatarHead = new AvatarHeadManager(); [Header("Retargeting Remote")] public RetargetingRemoteManager retargetingRemote = new RetargetingRemoteManager(); [Header("Runtime Control Panel")] public RuntimeControlPanelManager runtimeControlPanel = new RuntimeControlPanelManager(); [Header("Debug")] public bool enableDebugLog = true; // 싱글톤 패턴 public static SystemController Instance { get; private set; } private void Awake() { if (Instance == null) { Instance = this; } else { Destroy(gameObject); } } private void Start() { optiTrack.Initialize(Log, LogError); facialMotion.Initialize(Log, LogError); motionRecording.Initialize(optiTrack, Log, LogError); screenshot.Initialize(Log, LogError); clothSimulation.Initialize(Log, LogError); avatarHead.Initialize(Log, LogError); retargetingRemote.Initialize(Log, LogError); runtimeControlPanel.Initialize(transform, Log, LogError); Log("SystemController 초기화 완료"); Log($"OptiTrack 클라이언트: {(optiTrack.optitrackClient != null ? "설정됨" : "없음")}"); Log($"Motion Recorder 개수: {motionRecording.motionRecorders.Count}"); Log($"Facial Motion 클라이언트 개수: {facialMotion.facialMotionClients.Count}"); Log($"Screenshot 카메라: {(screenshot.screenshotCamera != null ? "설정됨" : "없음")}"); } /// /// 명령어 실행 - WebSocket에서 받은 명령을 적절한 매니저로 디스패치 /// public void ExecuteCommand(string command, Dictionary parameters) { Log($"명령어 실행: {command}"); switch (command) { // OptiTrack 마커 case "toggle_optitrack_markers": optiTrack.ToggleOptitrackMarkers(); break; case "show_optitrack_markers": optiTrack.ShowOptitrackMarkers(); break; case "hide_optitrack_markers": optiTrack.HideOptitrackMarkers(); break; case "reconnect_optitrack": optiTrack.ReconnectOptitrack(); break; case "spawn_optitrack_client": optiTrack.SpawnOptitrackClientFromPrefab(); break; // Facial Motion case "reconnect_facial_motion": facialMotion.ReconnectFacialMotion(); break; case "refresh_facial_motion_clients": facialMotion.RefreshFacialMotionClients(); break; // Motion Recording case "start_motion_recording": motionRecording.StartMotionRecording(); break; case "stop_motion_recording": motionRecording.StopMotionRecording(); break; case "toggle_motion_recording": motionRecording.ToggleMotionRecording(); break; case "refresh_motion_recorders": motionRecording.RefreshMotionRecorders(); break; // Screenshot case "capture_screenshot": screenshot.CaptureScreenshot(); break; case "capture_alpha_screenshot": screenshot.CaptureAlphaScreenshot(); break; case "open_screenshot_folder": screenshot.OpenScreenshotFolder(); break; // Avatar Head case "refresh_avatar_head_colliders": avatarHead.RefreshAvatarHeadColliders(); break; // MagicaCloth case "refresh_magica_cloth": case "reset_magica_cloth": clothSimulation.ResetAllMagicaCloth(); break; case "reset_magica_cloth_keep_pose": clothSimulation.ResetAllMagicaClothKeepPose(); break; // Retargeting Remote case "start_retargeting_remote": retargetingRemote.StartRetargetingRemote(); break; case "stop_retargeting_remote": retargetingRemote.StopRetargetingRemote(); break; case "toggle_retargeting_remote": retargetingRemote.ToggleRetargetingRemote(); break; case "refresh_retargeting_characters": retargetingRemote.AutoRegisterRetargetingCharacters(); break; default: LogError($"알 수 없는 명령어: {command}"); break; } } private void Update() { runtimeControlPanel.Tick(); } private void OnDestroy() { screenshot.Cleanup(); runtimeControlPanel.Cleanup(); } // --- 하위 호환 프로퍼티 (StreamDeckServerManager 등 외부 참조용) --- public OptitrackStreamingClient optitrackClient => optiTrack.optitrackClient; public bool IsRecording() => motionRecording.IsRecording(); public List GetAvatarHeadTargets() => avatarHead.GetAvatarHeadTargets(); public void RefreshAvatarHeadColliders() => avatarHead.RefreshAvatarHeadColliders(); public bool IsRetargetingRemoteRunning() => retargetingRemote.IsRetargetingRemoteRunning(); public string GetRetargetingRemoteUrl() => retargetingRemote.GetRetargetingRemoteUrl(); private void Log(string message) { if (enableDebugLog) { Debug.Log($"[SystemController] {message}"); } } private void LogError(string message) { Debug.LogError($"[SystemController] {message}"); } }