167 lines
7.5 KiB
C#
167 lines
7.5 KiB
C#
using UnityEngine;
|
|
|
|
namespace UVC.UI.Window.PropertyWindow
|
|
{
|
|
/// <summary>
|
|
/// 속성창의 UI를 담당하는 View 클래스입니다.
|
|
/// Controller로부터 데이터를 받아와 동적으로 UI 요소들을 생성하고 관리합니다.
|
|
/// 이 클래스는 MonoBehaviour를 상속받아 Unity 씬에 배치될 수 있습니다.
|
|
/// </summary>
|
|
public class PropertyView : MonoBehaviour
|
|
{
|
|
/// <summary>
|
|
/// UI 요소들이 생성될 부모 컨테이너입니다.
|
|
/// Unity 에디터에서 Vertical Layout Group 컴포넌트가 추가된 Panel 등을 연결합니다.
|
|
/// </summary>
|
|
[Tooltip("속성 UI들이 생성될 부모 Transform (예: Vertical Layout Group이 있는 Panel)")]
|
|
[SerializeField] private Transform _container;
|
|
|
|
// 각 속성 타입에 맞는 UI 프리팹들입니다.
|
|
// 실제 프로젝트에서는 이 프리팹들을 만들고 여기에 연결해야 합니다.
|
|
[Header("Property UI Prefabs")]
|
|
[SerializeField] private GameObject _stringPropertyPrefab;
|
|
[SerializeField] private GameObject _numberPropertyPrefab;
|
|
[SerializeField] private GameObject _boolPropertyPrefab;
|
|
[SerializeField] private GameObject _vector2PropertyPrefab;
|
|
[SerializeField] private GameObject _vector3PropertyPrefab;
|
|
[SerializeField] private GameObject _colorPropertyPrefab;
|
|
[SerializeField] private GameObject _datePropertyPrefab;
|
|
[SerializeField] private GameObject _dateTimePropertyPrefab;
|
|
[SerializeField] private GameObject _enumPropertyPrefab;
|
|
[SerializeField] private GameObject _listPropertyPrefab;
|
|
[SerializeField] private GameObject _radioGroupPropertyPrefab;
|
|
[SerializeField] private GameObject _numberRangePropertyPrefab;
|
|
[SerializeField] private GameObject _dateRangePropertyPrefab;
|
|
[SerializeField] private GameObject _dateTimeRangePropertyPrefab;
|
|
|
|
/// <summary>
|
|
/// View가 상호작용할 Controller 인스턴스입니다.
|
|
/// </summary>
|
|
private PropertyWindow _controller;
|
|
|
|
/// <summary>
|
|
/// Controller를 View에 설정하고 UI를 초기화합니다.
|
|
/// </summary>
|
|
/// <param name="controller">사용할 PropertyWindow</param>
|
|
public void Initialize(PropertyWindow controller)
|
|
{
|
|
_controller = controller;
|
|
|
|
// Controller가 null이 아니면, 이벤트 핸들러를 등록하고 UI를 그립니다.
|
|
if (_controller != null)
|
|
{
|
|
_controller.PropertyValueChanged += OnPropertyValueChanged;
|
|
DrawProperties();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Controller에 있는 속성 목록을 기반으로 UI를 생성합니다.
|
|
/// </summary>
|
|
private void DrawProperties()
|
|
{
|
|
// UI를 다시 그리기 전에 기존에 생성된 모든 자식 오브젝트를 삭제합니다.
|
|
foreach (Transform child in _container)
|
|
{
|
|
Destroy(child.gameObject);
|
|
}
|
|
|
|
if (_controller == null) return;
|
|
|
|
// 각 속성 항목에 대해 적절한 UI를 생성합니다.
|
|
foreach (var propertyItem in _controller.Properties)
|
|
{
|
|
// 속성 타입에 맞는 UI 프리팹을 찾습니다.
|
|
GameObject prefab = GetPrefabForProperty(propertyItem.PropertyType);
|
|
if (prefab != null)
|
|
{
|
|
// 프리팹을 인스턴스화하여 컨테이너의 자식으로 추가합니다.
|
|
GameObject uiInstance = Instantiate(prefab, _container);
|
|
|
|
// 생성된 UI 인스턴스에서 IPropertyUI 컴포넌트를 찾아 Setup을 호출합니다.
|
|
var propertyUI = uiInstance.GetComponent<IPropertyUI>();
|
|
if (propertyUI != null)
|
|
{
|
|
propertyUI.Setup(propertyItem, _controller);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"[PropertyView] 프리팹 '{prefab.name}'에 IPropertyUI를 구현한 스크립트가 없습니다.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning($"[PropertyView] '{propertyItem.PropertyType}' 타입에 대한 UI 프리팹이 지정되지 않았습니다.");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 속성 타입에 맞는 UI 프리팹을 반환합니다.
|
|
/// 실제 구현에서는 더 많은 case가 필요합니다.
|
|
/// </summary>
|
|
private GameObject GetPrefabForProperty(PropertyType type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case PropertyType.String:
|
|
return _stringPropertyPrefab;
|
|
case PropertyType.Int:
|
|
return _numberPropertyPrefab;
|
|
case PropertyType.Float:
|
|
return _numberPropertyPrefab;
|
|
case PropertyType.Bool:
|
|
return _boolPropertyPrefab;
|
|
case PropertyType.Vector2:
|
|
return _vector2PropertyPrefab;
|
|
case PropertyType.Vector3:
|
|
return _vector3PropertyPrefab;
|
|
case PropertyType.Color:
|
|
return _colorPropertyPrefab;
|
|
case PropertyType.Date:
|
|
return _datePropertyPrefab;
|
|
case PropertyType.DateTime:
|
|
return _dateTimePropertyPrefab;
|
|
case PropertyType.Enum:
|
|
return _enumPropertyPrefab;
|
|
case PropertyType.DropdownList:
|
|
return _listPropertyPrefab;
|
|
case PropertyType.RadioGroup:
|
|
return _radioGroupPropertyPrefab;
|
|
case PropertyType.IntRange:
|
|
return _numberRangePropertyPrefab;
|
|
case PropertyType.FloatRange:
|
|
return _numberRangePropertyPrefab;
|
|
case PropertyType.DateRange:
|
|
return _dateRangePropertyPrefab;
|
|
case PropertyType.DateTimeRange:
|
|
return _dateTimeRangePropertyPrefab;
|
|
default:
|
|
Debug.LogWarning($"'{type}' 타입에 대한 프리팹이 정의되지 않았습니다.");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Controller에서 PropertyValueChanged 이벤트가 발생했을 때 호출되는 핸들러입니다.
|
|
/// </summary>
|
|
private void OnPropertyValueChanged(object sender, PropertyValueChangedEventArgs e)
|
|
{
|
|
Debug.Log($"[PropertyView] 속성 변경 감지: ID='{e.PropertyId}', 이전 값='{e.OldValue}', 새 값='{e.NewValue}'");
|
|
|
|
// 여기서 특정 속성 값의 변경에 따라 다른 UI를 업데이트하는 로직을 추가할 수 있습니다.
|
|
// 예: 특정 bool 속성이 false가 되면 다른 속성 UI를 비활성화 처리
|
|
// DrawProperties(); // 전체를 다시 그리는 가장 간단하지만 비효율적일 수 있는 방법
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
// 오브젝트가 파괴될 때 이벤트 핸들러를 안전하게 해제합니다. (메모리 누수 방지)
|
|
if (_controller != null)
|
|
{
|
|
_controller.PropertyValueChanged -= OnPropertyValueChanged;
|
|
}
|
|
}
|
|
}
|
|
}
|