7.4 KiB
7.4 KiB
Studio 모듈 가이드
Studio는 3D 씬 에디터 애플리케이션입니다. 3D 오브젝트 배치, Transform 편집, Undo/Redo, 파일 저장/내보내기 기능을 제공합니다.
모듈 구조
Studio/
├── StudioAppMain.cs # 앱 진입점
├── StudioAppContext.cs # 앱 레벨 DI 컨텍스트
├── StudioSceneMain.cs # 씬 초기화
├── StudioSceneContext.cs # 씬 레벨 DI 컨텍스트
├── StudioSideTabBar.cs # 사이드 탭 바
├── Config/
│ ├── StudioAppConfig.cs # 앱 설정
│ ├── StudioConstants.cs # 상수
│ ├── Setting.cs # 사용자 설정 (그리드, 스냅)
│ └── Library.cs # 에셋 라이브러리
├── Command/ # Command 패턴 (Undo/Redo)
│ ├── TransformChangeCommand.cs
│ ├── PropertyChangeCommand.cs
│ ├── EditDeleteCommand.cs
│ ├── EditDuplicateCommand.cs
│ ├── EditCreatePlaneCommand.cs
│ ├── EditUndoCommand.cs
│ ├── EditRedoCommand.cs
│ ├── FileNewCommand.cs
│ ├── FileOpenCommand.cs
│ ├── FileSaveCommand.cs
│ └── FileExport*.cs
├── Manager/
│ ├── UndoRedoManager.cs # Undo/Redo 히스토리
│ ├── StageObjectManager.cs # 스테이지 오브젝트 관리
│ ├── SelectionManager.cs # 선택 상태 관리
│ ├── SelectionInputHandler.cs
│ ├── ShortcutManager.cs # 단축키 관리
│ └── GizmoUndoBridge.cs # RTGizmo ↔ Undo 연동
├── Modal/
│ └── Settings/ # 설정 모달
├── Tab/
│ ├── StudioSideTabBarHierarchy.cs # 계층 탭
│ └── StudioSideTabBarAccordion.cs # 아코디언 탭
└── UI/
└── Buttons/ # UI 버튼 컴포넌트
핵심 시스템
1. 앱 진입점 (StudioAppMain)
namespace UVC.Studio
{
[DefaultExecutionOrder(100)]
public class StudioAppMain : SingletonApp<StudioAppMain>
{
public Action Initialized;
protected override async void Init()
{
Log4netCodeConfigurator.Setup();
UILoading.Show();
RTG.get.initialized += OnRTGInit;
await SettupConfigAsync();
Initialized?.Invoke();
}
private async void OnRTGInit()
{
// RTGizmo 초기화
RTGizmos.get.CreateViewGizmo(RTCamera.get.settings.targetCamera);
// Setting 서비스에서 그리드/스냅 설정 적용
Setting setting = InjectorAppContext.Instance.Get<Setting>();
RTGrid.get.settings.cellSize = new Vector3(
setting.Data.general.gridSize, ...);
RTGizmos.get.skin.globalGizmoStyle.positionSnap =
setting.Data.general.snapPosition;
}
}
}
2. Undo/Redo 시스템
UndoRedoManager
public class UndoRedoManager : SingletonScene<UndoRedoManager>
{
private readonly Stack<IUndoableCommand> _undoStack = new();
private readonly Stack<IUndoableCommand> _redoStack = new();
public event Action? OnHistoryChanged;
public event Action<IUndoableCommand>? OnUndo;
public event Action<IUndoableCommand>? OnRedo;
public bool CanUndo => _undoStack.Count > 0;
public bool CanRedo => _redoStack.Count > 0;
// Command 실행 및 히스토리 기록
public void ExecuteCommand(IUndoableCommand command, object? parameter = null);
// 이미 실행된 Command를 히스토리에만 기록 (RTGizmo 연동)
public void RecordCommand(IUndoableCommand command);
public void Undo();
public void Redo();
public void Clear();
}
TransformChangeCommand
public class TransformChangeCommand : IUndoableCommand
{
public string Description { get; }
// 생성자에서 Before 상태 캡처
public TransformChangeCommand(Transform transform, string description = "객체 이동");
public TransformChangeCommand(IEnumerable<Transform> transforms, string description);
// 드래그 완료 후 After 상태 캡처
public void CaptureAfterState();
// 변경사항 확인
public bool HasChanges();
// Undo/Redo
public void Undo(object? parameter = null);
public void Redo();
// 파괴된 객체 복구 (StageObject ID 기반)
public bool TryResolveAllTransforms();
public bool IsValid();
}
3. StageObjectManager
public class StageObjectManager
{
// 오브젝트 등록/조회
public void Register(StageObject obj);
public StageObject? GetById(string id);
public StageObject? GetByGameObject(GameObject go);
}
4. SelectionManager
public class SelectionManager
{
public event Action<IReadOnlyList<GameObject>>? OnSelectionChanged;
public IReadOnlyList<GameObject> SelectedObjects { get; }
public void Select(GameObject obj);
public void AddToSelection(GameObject obj);
public void Deselect(GameObject obj);
public void ClearSelection();
}
Command 패턴
IUndoableCommand 인터페이스
public interface IUndoableCommand
{
string Description { get; }
void Execute(object? parameter = null);
void Undo(object? parameter = null);
void Redo();
// 병합 지원 (연속 드래그 등)
bool CanMerge(IUndoableCommand other);
void Merge(IUndoableCommand other);
}
Command 사용 예시
// Transform 변경 Command
var cmd = new TransformChangeCommand(selectedTransforms, "객체 이동");
// ... 드래그 완료 후 ...
cmd.CaptureAfterState();
if (cmd.HasChanges())
{
UndoRedoManager.Instance.RecordCommand(cmd);
}
// Undo/Redo 실행
UndoRedoManager.Instance.Undo();
UndoRedoManager.Instance.Redo();
RTGizmo 연동
GizmoUndoBridge
RTGizmo의 드래그 이벤트를 Undo 시스템에 연결합니다.
// RTGizmo 드래그 시작 시
private TransformChangeCommand? _pendingCommand;
void OnGizmoDragStart(IEnumerable<Transform> targets)
{
_pendingCommand = new TransformChangeCommand(targets, "Transform 변경");
}
// RTGizmo 드래그 완료 시
void OnGizmoDragEnd()
{
if (_pendingCommand != null)
{
_pendingCommand.CaptureAfterState();
if (_pendingCommand.HasChanges())
{
UndoRedoManager.Instance.RecordCommand(_pendingCommand);
}
_pendingCommand = null;
}
}
파일 Command
| Command | 설명 |
|---|---|
FileNewCommand |
새 프로젝트 |
FileOpenCommand |
프로젝트 열기 |
FileSaveCommand |
저장 |
FileSaveAsCommand |
다른 이름으로 저장 |
FileInsertDbCommand |
DB에 삽입 |
FileExportLayoutCommand |
레이아웃 내보내기 |
FileExportMetaCommand |
메타데이터 내보내기 |
FileExportGltfCommand |
glTF 내보내기 |
설정 모달
Modal/Settings/
├── SettingModal.cs # 설정 모달 메인
├── SettingGeneralTabContent.cs # 일반 설정 탭
├── SettingDatabaseTabContent.cs # 데이터베이스 설정 탭
├── SettingShortcutTabContent.cs # 단축키 설정 탭
├── SettingOpenCommand.cs # 설정 모달 열기 Command
└── SettingOpenCommandMono.cs # MonoBehaviour 래퍼
의존성
- RTGLite: Gizmo, Grid, Camera 제어
- UVC 라이브러리: Core (DI, Singleton), UI, Data
- UniTask: 비동기 처리