Files
XRLib/Assets/Scripts/Studio/StudioSceneMain.cs

398 lines
19 KiB
C#
Raw Normal View History

2025-12-11 21:05:44 +09:00
using Cysharp.Threading.Tasks;
2025-12-17 11:16:34 +09:00
using RTGLite;
2025-12-11 21:05:44 +09:00
using System;
using System.Collections.Generic;
using UnityEngine;
2025-12-17 11:16:34 +09:00
using UnityEngine.InputSystem;
2025-12-11 21:05:44 +09:00
using UVC.Core;
using UVC.Data;
using UVC.Data.Core;
using UVC.Locale;
2025-12-16 19:35:43 +09:00
using UVC.Studio.Modal.Settings;
2025-12-11 21:05:44 +09:00
using UVC.UI.Commands;
using UVC.UI.Loading;
using UVC.UI.Menu;
using UVC.UI.Modal;
using UVC.UI.Toolbar;
2025-12-11 21:05:44 +09:00
using UVC.UI.Toolbar.Model;
using UVC.UI.ToolBar;
using UVC.UI.Tooltip;
using UVC.UI.Window.PropertyWindow;
using UVC.Util;
2025-12-17 11:16:34 +09:00
using ActionCommand = UVC.UI.Commands.ActionCommand;
2025-12-11 21:05:44 +09:00
namespace UVC.Studio
{
[DefaultExecutionOrder(90)]
public class StudioSceneMain : SingletonScene<StudioSceneMain>
{
2025-12-16 19:35:43 +09:00
[Inject]
2025-12-11 21:05:44 +09:00
private TopMenuController topMenu;
2025-12-16 19:35:43 +09:00
[Inject]
2025-12-11 21:05:44 +09:00
private Toolbox toolBox;
2025-12-16 19:35:43 +09:00
[Inject]
2025-12-11 21:05:44 +09:00
private StudioSideTabBar sideTabBar;
2025-12-15 20:17:38 +09:00
[Inject]
private PropertyWindow propertyWindow;
2025-12-11 21:05:44 +09:00
2025-12-17 11:16:34 +09:00
//test code
MoveGizmo mMoveGizmo; // 이동 기즈모
RotateGizmo mRotateGizmo; // 회전 기즈모
ScaleGizmo mScaleGizmo; // 크기 조절 기즈모
2025-12-16 19:35:43 +09:00
2025-12-11 21:05:44 +09:00
public Action Initialized;
/// <summary>
/// 초기 화 메서드입니다.
/// Awake 메서드에서 호출되며, MonoBehaviour가 생성될 때 한 번만 실행됩니다.
/// </summary>
protected override void Init()
{
2025-12-16 19:35:43 +09:00
2025-12-11 21:05:44 +09:00
if (!TooltipManager.Instance.IsInitialized) TooltipManager.Instance.Initialize();
2025-12-16 19:35:43 +09:00
2025-12-11 21:05:44 +09:00
StudioAppMain.Instance.Initialized += OnAppInitialized;
}
private async void OnAppInitialized()
2025-12-16 19:35:43 +09:00
{
// SceneContext 초기화 완료 대기 (Injection이 수행된 후)
var sceneCtx = FindAnyObjectByType<StudioSceneContext>();
if (sceneCtx != null)
{
2025-12-16 20:31:27 +09:00
// Injection이 완료될 때까지 대기
2025-12-16 19:35:43 +09:00
await sceneCtx.WaitForInitializationAsync();
Initialize();
}
}
private void Initialize()
2025-12-11 21:05:44 +09:00
{
SetupTopMenu();
SetupToolBox();
2025-12-16 19:35:43 +09:00
sideTabBar.InitTab();
2025-12-11 21:05:44 +09:00
2025-12-16 19:35:43 +09:00
Initialized?.Invoke();
2025-12-11 21:05:44 +09:00
2025-12-16 19:35:43 +09:00
UILoading.Hide();
2025-12-17 11:16:34 +09:00
// 오브젝트를 이동, 회전, 크기 조절할 수 있는 변환 기즈모를 생성합니다
mMoveGizmo = RTGizmos.get.CreateObjectMoveGizmo();
mRotateGizmo = RTGizmos.get.CreateObjectRotateGizmo();
mScaleGizmo = RTGizmos.get.CreateObjectScaleGizmo();
// 이 간단한 데모에서는 단일 타겟 오브젝트가 있으며 모든 기즈모가 이 오브젝트를 제어합니다
GameObject targetObject = GameObject.Find("Cube");
mMoveGizmo.objectTransformGizmo.SetTarget(targetObject);
mRotateGizmo.objectTransformGizmo.SetTarget(targetObject);
mScaleGizmo.objectTransformGizmo.SetTarget(targetObject);
// 기본적으로 이동 기즈모를 제외한 모든 기즈모를 비활성화합니다. 그런 다음 단축키로 기즈모를 켜고 끌 수 있습니다.
mRotateGizmo.enabled = false;
mScaleGizmo.enabled = false;
}
void Update()
{
// 단축키를 사용하여 활성 기즈모를 변경합니다.
// 참고: 이러한 키 중 일부는 카메라 탐색 키와 충돌할 수 있으므로,
// 카메라가 현재 탐색 중이 아닌 경우에만 진행합니다.
if (RTCamera.get.navigationMode == ECameraNavigationMode.None)
{
if (RTInput.get.KeyWentDown(Key.W)) // 이동 기즈모 활성화
{
mMoveGizmo.enabled = true;
mRotateGizmo.enabled = false;
mScaleGizmo.enabled = false;
mMoveGizmo.objectTransformGizmo.Refresh();
}
else
if (RTInput.get.KeyWentDown(Key.E)) // 회전 기즈모 활성화
{
mMoveGizmo.enabled = false;
mRotateGizmo.enabled = true;
mScaleGizmo.enabled = false;
mRotateGizmo.objectTransformGizmo.Refresh();
}
else
if (RTInput.get.KeyWentDown(Key.R)) // 크기 조절 기즈모 활성화
{
mMoveGizmo.enabled = false;
mRotateGizmo.enabled = false;
mScaleGizmo.enabled = true;
mScaleGizmo.objectTransformGizmo.Refresh();
}
}
2025-12-11 21:05:44 +09:00
}
private void SetupTopMenu()
{
if (topMenu == null)
{
Debug.LogWarning("TopMenuController is not assigned in SceneMain.");
return;
}
topMenu.AddMenuItem(new MenuItemData("file", "menu_file", subMenuItems: new List<MenuItemData>
{
new MenuItemData("file_new", "menu_file_new", new DebugLogCommand("새 파일 선택됨 (Command 실행)")),
new MenuItemData("file_open", "menu_file_open", new DebugLogCommand("파일 열기 선택됨 (Command 실행)")),
new MenuItemData("file_save", "menu_file_save", new DebugLogCommand("파일 저장 선택됨 (Command 실행)")),
new MenuItemData("file_saveas", "menu_file_save_as", new DebugLogCommand("다른 이름으로 저장 선택됨 (Command 실행)")),
new MenuItemData("file_insert_db", "menu_file_insert_db", new DebugLogCommand("데이터베이스 삽입 선택됨 (Command 실행)")),
new MenuItemData("file_export", "menu_file_export", subMenuItems: new List<MenuItemData>
{
new MenuItemData("file_export_layout", "menu_file_export_layout", new DebugLogCommand("Layout Json 내보내기 선택됨 (Command 실행)")),
new MenuItemData("file_export_meta", "menu_file_export_meta", new DebugLogCommand("Meta Data Json 내보내기 선택됨 (Command 실행)")),
new MenuItemData("file_export_gltf", "menu_file_export_gltf", new DebugLogCommand("GLTF 내보내기 선택됨 (Command 실행)")),
}),
}));
// pool 로그
topMenu.AddMenuItem(new MenuItemData("edit", "menu_edit", subMenuItems: new List<MenuItemData>
{
new MenuItemData("edit_undo", "menu_edit_undo", new DebugLogCommand("되돌리기 선택됨 (Command 실행)")),
new MenuItemData("edit_redo", "menu_edit_redo", new DebugLogCommand("다시 실행 선택됨 (Command 실행)")),
new MenuItemData("edit_duplicate", "menu_edit_duplicate", new DebugLogCommand("복제 선택됨 (Command 실행)")),
new MenuItemData("edit_delete", "menu_edit_delete", new DebugLogCommand("삭제 선택됨 (Command 실행)")),
new MenuItemData("edit_create_plane", "menu_edit_create_plane", new DebugLogCommand("평면 생성 선택됨 (Command 실행)")),
}));
topMenu.AddMenuItem(new MenuItemData("setting", "menu_setting", subMenuItems: new List<MenuItemData>
{
2025-12-16 19:35:43 +09:00
new MenuItemData("setting_db", "menu_setting_db", new SettingOpenCommand("shortcut:Database")),
new MenuItemData("setting_general", "menu_setting_general", new SettingOpenCommand("shortcut:General")),
new MenuItemData("setting_library", "menu_setting_library", new SettingOpenCommand("shortcut:Library")),
new MenuItemData("setting_shortcut", "menu_setting_shortcut", new SettingOpenCommand("shortcut:Shortcut")),
2025-12-11 21:05:44 +09:00
}));
topMenu.Initialize();
}
private void SetupToolBox()
{
// ToolbarModel 인스턴스 생성
var toolbarModel = new ToolbarModel();
// --- 툴바 모델 구성 시작 ---
// 저장
toolbarModel.AddToggleButton("button_save", false,
"Studio/Images/toolbar_icon_save_on_40",
"Studio/Images/toolbar_icon_save_off_40",
onToggle: (isSelected) => Debug.Log($"화면 녹화 상태: {(isSelected ? " " : "")} (OnToggle 콜백)"),
command: new DebugLogCommand("저장 버튼 클릭됨 (Command 실행)"),
tooltip:"tooltip_save");
// undo
toolbarModel.AddStandardButton("button_undo",
"Studio/Images/toolbar_icon_undo_40",
command: new DebugLogCommand("되돌리기 버튼 클릭됨"),
tooltip: "tooltip_undo");
// redo
toolbarModel.AddStandardButton("button_redo",
"Studio/Images/toolbar_icon_redo_40",
command: new DebugLogCommand("다시 실행 버튼 클릭됨"),
tooltip: "tooltip_redo");
toolbarModel.AddSeparator();
//select
toolbarModel.AddRadioButton("SizeControlGroup", "Selection Tool", true,
"Studio/Images/toolbar_icon_select_on_40",
"Studio/Images/toolbar_icon_select_off_40",
onToggle: (isSelected) => { if (isSelected) Debug.Log("Selection Tool 선택됨"); },
command: new ActionCommand(() => Debug.Log("Selection Tool Command 실행")),
"tooltip_selection_tool");
// move
toolbarModel.AddRadioButton("SizeControlGroup", "Movement Tool", false,
"Studio/Images/toolbar_icon_move_on_40",
"Studio/Images/toolbar_icon_move_off_40",
onToggle: (isSelected) => { if (isSelected) Debug.Log("Movement Tool 선택됨"); },
command: new ActionCommand(() => Debug.Log("Movement Tool Command 실행")),
"tooltip_movement_tool");
// rotate
toolbarModel.AddRadioButton("SizeControlGroup", "Rotation Tool", false,
"Studio/Images/toolbar_icon_rotate_on_40",
"Studio/Images/toolbar_icon_rotate_off_40",
onToggle: (isSelected) => { if (isSelected) Debug.Log("Rotation Tool 선택됨"); },
command: new ActionCommand(() => Debug.Log("Rotation Tool Command 실행")),
"tooltip_rotation_tool");
//scale
toolbarModel.AddRadioButton("SizeControlGroup", "Scale Tool", false,
"Studio/Images/toolbar_icon_scale_on_40",
"Studio/Images/toolbar_icon_scale_off_40",
onToggle: (isSelected) => { if (isSelected) Debug.Log("Scale Tool 선택됨"); },
command: new ActionCommand(() => Debug.Log("Scale Tool Command 실행")),
"tooltip_scale_tool");
toolbarModel.AddSeparator();
//duplicate
toolbarModel.AddStandardButton("button_duplicate",
"Studio/Images/toolbar_icon_duplicate_40",
command: new DebugLogCommand("duplicate 버튼 클릭됨"),
tooltip: "tooltip_duplicate");
//align
var alignBtnModel = new ToolbarExpandableButton {
Text = "button_align",
IconSpritePath = "Studio/Images/toolbar_icon_align_40",
ClickCommand = new ActionCommand(() => Debug.Log("align 주 버튼 클릭됨 (Command)")),
Tooltip = "tooltip_align",
UpdateIconOnSelection = false,
2025-12-11 21:05:44 +09:00
OnSubButtonSelected = (selectedSubButtonModel) =>
{
// LocalizationManager를 사용하여 텍스트를 현재 언어에 맞게 가져올 수 있습니다.
string localizedSubButtonText = LocalizationManager.Instance != null ? LocalizationManager.Instance.GetString(selectedSubButtonModel.Text) : selectedSubButtonModel.Text;
Debug.Log($"정렬 옵션 '{localizedSubButtonText}' 선택됨 (OnSubButtonSelected 콜백). 주 버튼 업데이트 로직 실행 가능.");
}
};
// 확장 버튼 모델에 하위 버튼 추가
alignBtnModel.SubButtons.Add(new ToolbarStandardButton
{
Text = "horizontal_left", // 하위 버튼 텍스트/키
IconSpritePath = "Studio/Images/toolbar_icon_align_hl_40", // 하위 버튼 아이콘
Tooltip = "tooltip_horizontal_left", // 하위 버튼 툴팁
ClickCommand = new DebugLogCommand("왼쪽 정렬 선택됨 (Sub-Command 실행)")
});
alignBtnModel.SubButtons.Add(new ToolbarStandardButton
{
Text = "horizontal_center", // 하위 버튼 텍스트/키
IconSpritePath = "Studio/Images/toolbar_icon_align_hc_40", // 하위 버튼 아이콘
Tooltip = "tooltip_horizontal_center", // 하위 버튼 툴팁
ClickCommand = new DebugLogCommand("중앙 정렬 선택됨 (Sub-Command 실행)")
});
alignBtnModel.SubButtons.Add(new ToolbarStandardButton
{
Text = "horizontal_right", // 하위 버튼 텍스트/키
IconSpritePath = "Studio/Images/toolbar_icon_align_hr_40", // 하위 버튼 아이콘
Tooltip = "tooltip_horizontal_right", // 하위 버튼 툴팁
ClickCommand = new DebugLogCommand("오른쪽 정렬 선택됨 (Sub-Command 실행)")
});
alignBtnModel.SubButtons.Add(new ToolbarStandardButton
{
Text = "vertical_top", // 하위 버튼 텍스트/키
IconSpritePath = "Studio/Images/toolbar_icon_align_vt_40", // 하위 버튼 아이콘
Tooltip = "tooltip_vertical_top", // 하위 버튼 툴팁
ClickCommand = new DebugLogCommand("위쪽 정렬 선택됨 (Sub-Command 실행)")
});
alignBtnModel.SubButtons.Add(new ToolbarStandardButton
{
Text = "vertical_middle", // 하위 버튼 텍스트/키
IconSpritePath = "Studio/Images/toolbar_icon_align_vm_40", // 하위 버튼 아이콘
Tooltip = "tooltip_vertical_middle", // 하위 버튼 툴팁
ClickCommand = new DebugLogCommand("중앙 정렬 선택됨 (Sub-Command 실행)")
});
alignBtnModel.SubButtons.Add(new ToolbarStandardButton
{
Text = "vertical_bottom", // 하위 버튼 텍스트/키
IconSpritePath = "Studio/Images/toolbar_icon_align_vb_40", // 하위 버튼 아이콘
Tooltip = "tooltip_vertical_bottom", // 하위 버튼 툴팁
ClickCommand = new DebugLogCommand("아래쪽 정렬 선택됨 (Sub-Command 실행)")
});
alignBtnModel.SubButtons.Add(new ToolbarStandardButton
{
Text = "horizontal_even", // 하위 버튼 텍스트/키
IconSpritePath = "Studio/Images/toolbar_icon_align_he_40", // 하위 버튼 아이콘
Tooltip = "tooltip_horizontal_even", // 하위 버튼 툴팁
ClickCommand = new DebugLogCommand("가로 균등 정렬 선택됨 (Sub-Command 실행)")
});
alignBtnModel.SubButtons.Add(new ToolbarStandardButton
{
Text = "vertical_even", // 하위 버튼 텍스트/키
IconSpritePath = "Studio/Images/toolbar_icon_align_ve_40", // 하위 버튼 아이콘
Tooltip = "tooltip_vertical_even", // 하위 버튼 툴팁
ClickCommand = new DebugLogCommand("세로 균등 정렬 선택됨 (Sub-Command 실행)")
});
toolbarModel.AddItem(alignBtnModel);
//snap
toolbarModel.AddToggleButton("button_snap", true,
"Studio/Images/toolbar_icon_snap_40",
2025-12-11 21:05:44 +09:00
"Studio/Images/toolbar_icon_snap_40",
command: new DebugLogCommand("snap 버튼 클릭됨"),
tooltip: "tooltip_snap");
//guide
toolbarModel.AddToggleButton("button_guide", true,
"Studio/Images/toolbar_icon_guide_40",
2025-12-11 21:05:44 +09:00
"Studio/Images/toolbar_icon_guide_40",
command: new DebugLogCommand("guide 버튼 클릭됨"),
tooltip: "tooltip_guide");
toolbarModel.AddSeparator();
//node
toolbarModel.AddRadioButton("NodeControlGroup", "Node Tool", false,
"Studio/Images/toolbar_icon_node_on_40",
"Studio/Images/toolbar_icon_node_off_40",
onToggle: (isSelected) => { if (isSelected) Debug.Log("Node Tool 선택됨"); },
command: new ActionCommand(() => CursorManager.Instance.SetCursor(CursorType.Node)),
2025-12-11 21:05:44 +09:00
"tooltip_node_tool");
//link
toolbarModel.AddRadioButton("NodeControlGroup", "Link Tool", false,
"Studio/Images/toolbar_icon_link_on_40",
"Studio/Images/toolbar_icon_link_off_40",
onToggle: (isSelected) => { if (isSelected) Debug.Log("Link Tool 선택됨"); },
command: new ActionCommand(() => CursorManager.Instance.SetCursor(CursorType.Link)),
2025-12-11 21:05:44 +09:00
"tooltip_link_tool");
//arc
toolbarModel.AddRadioButton("NodeControlGroup", "Arc Tool", false,
"Studio/Images/toolbar_icon_arc_on_40",
"Studio/Images/toolbar_icon_arc_off_40",
onToggle: (isSelected) => { if (isSelected) Debug.Log("Arc Tool 선택됨"); },
command: new ActionCommand(() => CursorManager.Instance.SetCursor(CursorType.Arc)),
2025-12-11 21:05:44 +09:00
"tooltip_arc_tool");
// --- 툴바 모델 구성 끝 ---
toolBox.SetData(toolbarModel);
toolBox.Initialize();
toolBox.OnAction += (itemModel) =>
{
Debug.Log($"툴박스 아이템 '{itemModel.Text}' 실행됨 (OnAction 콜백). 추가 동작 로직 실행 가능.");
if(itemModel.ActionType == ToolbarActionType.Radio)
{
if(itemModel.Text == "SizeControlGroup")
{
// 선택, 이동, 회전, 크기 조절 툴 관련 동작 처리
toolBox.ClearRadioButtonSelection("NodeControlGroup");
CursorManager.Instance.SetDefaultCursor();
}
else if(itemModel.Text == "NodeControlGroup")
{
// 노드, 링크, 아크 툴 관련 동작 처리
toolBox.ClearRadioButtonSelection("SizeControlGroup");
}
}
};
2025-12-11 21:05:44 +09:00
}
}
}