Files
EnglewoodLAB/Assets/Scripts/Command/EditDeleteCommand.cs
SOOBEEN HAN f1894889ee <refactor> Octopus Twin 템플릿 적용
- 기능 외 UI 구조만 적용
- 프로젝트에 걸맞는 UI는 재작업 필요
2026-02-23 18:20:09 +09:00

148 lines
5.4 KiB
C#

#nullable enable
using System.Collections.Generic;
using UnityEngine;
using UVC.UI.Commands;
using UVC.Studio.Manager;
using UVC.Studio.Config;
using UVC.Object3d.Manager;
using UVC.Config;
namespace UVC.Studio.Command
{
/// <summary>
/// 삭제 커맨드 (Undo/Redo 지원)
/// </summary>
public class EditDeleteCommand : IUndoableCommand
{
public string Description => "객체 삭제";
public readonly SelectionManager _selectionManager;
public readonly StageObjectManager _stageObjectManager;
// Undo용 상태 저장
private readonly List<DeletedObjectData> _deletedObjects = new();
/// <summary>
/// 삭제된 객체 데이터
/// </summary>
private class DeletedObjectData
{
public string OriginalId { get; set; } = string.Empty;
public string ObjectName { get; set; } = string.Empty;
public EquipmentItem? Equipment { get; set; }
public Vector3 Position { get; set; }
public Quaternion Rotation { get; set; }
public Vector3 Scale { get; set; }
public GameObject? RestoredGameObject { get; set; }
public string? RestoredStageObjectId { get; set; }
}
public EditDeleteCommand(SelectionManager selectionManager, StageObjectManager stageObjectManager)
{
_selectionManager = selectionManager;
_stageObjectManager = stageObjectManager;
}
public void Execute(object? parameter = null)
{
_deletedObjects.Clear();
var selectedObjects = new List<StageObjectManager.StageObject>(_selectionManager.SelectedObjects);
if (selectedObjects.Count == 0)
{
Debug.Log("[EditDeleteCommand] 선택된 객체가 없습니다.");
return;
}
// 먼저 선택 해제
_selectionManager.DeselectAll();
foreach (var stageObject in selectedObjects)
{
if (stageObject.gameObject == null) continue;
// Undo용 데이터 저장
_deletedObjects.Add(new DeletedObjectData
{
OriginalId = stageObject.Id,
ObjectName = stageObject.gameObject.name,
Equipment = stageObject.Equipment,
Position = stageObject.gameObject.transform.position,
Rotation = stageObject.gameObject.transform.rotation,
Scale = stageObject.gameObject.transform.localScale
});
// 객체 제거 (Unregister가 Destroy도 수행)
_stageObjectManager.Unregister(stageObject.Id);
}
Debug.Log($"[EditDeleteCommand] {_deletedObjects.Count}개 객체 삭제됨");
}
public void Undo(object? parameter = null)
{
// 삭제된 객체들 복원
foreach (var data in _deletedObjects)
{
if (data.Equipment == null) continue;
// 동일 Equipment를 가진 다른 객체를 템플릿으로 사용
GameObject? templateObject = null;
foreach (var kvp in _stageObjectManager.Objects)
{
if (kvp.Value.Equipment?.id == data.Equipment.id && kvp.Value.gameObject != null)
{
templateObject = kvp.Value.gameObject;
break;
}
}
GameObject newObject;
if (templateObject != null)
{
// 템플릿이 있으면 복제
newObject = Object.Instantiate(templateObject);
}
else
{
// 템플릿이 없으면 기본 Cube로 대체 (실제로는 Equipment.gltf 로딩 필요)
newObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
Debug.LogWarning($"[EditDeleteCommand] 템플릿 객체를 찾을 수 없어 Cube로 대체: {data.ObjectName}");
}
// Transform 복원
newObject.transform.position = data.Position;
newObject.transform.rotation = data.Rotation;
newObject.transform.localScale = data.Scale;
newObject.name = data.ObjectName;
// StageObjectManager에 등록
var restoredStageObject = _stageObjectManager.Register(data.Equipment, newObject);
data.RestoredGameObject = newObject;
data.RestoredStageObjectId = restoredStageObject.Id;
}
Debug.Log($"[EditDeleteCommand] Undo: {_deletedObjects.Count}개 객체 복원됨");
}
public void Redo()
{
// 복원된 객체들 다시 삭제
foreach (var data in _deletedObjects)
{
if (data.RestoredStageObjectId != null)
{
_stageObjectManager.Unregister(data.RestoredStageObjectId);
data.RestoredGameObject = null;
data.RestoredStageObjectId = null;
}
}
Debug.Log($"[EditDeleteCommand] Redo: {_deletedObjects.Count}개 객체 다시 삭제됨");
}
public bool CanMerge(IUndoableCommand other) => false;
public void Merge(IUndoableCommand other) { }
}
}