ProjectDDD/Assets/_DDD/_Scripts/GameUi/BaseUi.cs

210 lines
6.7 KiB
C#
Raw Normal View History

2025-07-29 15:56:47 +00:00
using System;
2025-08-20 09:08:41 +00:00
using System.ComponentModel;
using System.Linq;
using System.Reflection;
2025-07-21 07:53:39 +00:00
using UnityEngine;
2025-08-20 09:08:41 +00:00
using UnityEngine.UI;
using DDD.MVVM;
2025-07-21 07:53:39 +00:00
namespace DDD
{
public abstract class BaseUi : MonoBehaviour
{
2025-08-20 09:08:41 +00:00
[SerializeField] protected bool _enableBlockImage;
2025-08-05 05:14:39 +00:00
protected CanvasGroup _canvasGroup;
2025-08-14 10:39:27 +00:00
protected GameObject _blockImage;
2025-07-22 07:46:37 +00:00
protected GameObject _panel;
2025-08-20 09:08:41 +00:00
protected BindingContext _bindingContext;
2025-07-21 07:53:39 +00:00
public virtual bool IsBlockingTime => false;
2025-08-20 09:08:41 +00:00
public virtual bool IsOpen => _panel != null && _panel.activeSelf;
2025-08-14 10:39:27 +00:00
2025-07-22 07:46:37 +00:00
protected virtual void Awake()
{
2025-08-05 05:14:39 +00:00
_canvasGroup = GetComponent<CanvasGroup>();
2025-08-20 09:08:41 +00:00
_panel = transform.Find(CommonConstants.Panel)?.gameObject;
_blockImage = transform.Find(CommonConstants.BlockImage)?.gameObject;
_bindingContext = new BindingContext();
SetupAutoBindings();
SetupBindings();
2025-07-22 07:46:37 +00:00
}
2025-08-14 08:21:17 +00:00
protected virtual void OnEnable()
{
2025-08-20 09:08:41 +00:00
2025-08-14 08:21:17 +00:00
}
2025-08-14 10:39:27 +00:00
2025-07-21 07:53:39 +00:00
protected virtual void Start()
{
TryRegister();
2025-08-05 04:00:01 +00:00
ClosePanel();
2025-07-21 07:53:39 +00:00
}
2025-07-29 15:56:47 +00:00
protected virtual void Update()
{
2025-08-20 09:08:41 +00:00
2025-07-29 15:56:47 +00:00
}
2025-08-14 08:21:17 +00:00
protected virtual void OnDisable()
{
2025-08-20 09:08:41 +00:00
2025-08-14 08:21:17 +00:00
}
2025-07-21 07:53:39 +00:00
protected virtual void OnDestroy()
{
TryUnregister();
2025-08-20 09:08:41 +00:00
_bindingContext?.Dispose();
2025-07-21 07:53:39 +00:00
}
2025-08-14 10:39:27 +00:00
2025-07-21 07:53:39 +00:00
protected virtual void TryRegister() { }
protected virtual void TryUnregister() { }
2025-08-20 09:08:41 +00:00
// BaseUi 메서드들을 직접 구현
2025-08-14 10:39:27 +00:00
public virtual void OpenPanel()
{
if (_enableBlockImage)
{
_blockImage.SetActive(true);
}
_panel.SetActive(true);
}
public virtual void ClosePanel()
{
if (_enableBlockImage)
{
_blockImage.SetActive(false);
}
_panel.SetActive(false);
}
2025-08-05 05:14:39 +00:00
public virtual void SetUiInteractable(bool active)
{
2025-08-20 09:08:41 +00:00
if (_canvasGroup != null)
{
_canvasGroup.interactable = active;
_canvasGroup.blocksRaycasts = active;
}
}
public bool IsOpenPanel() => _panel && _panel.activeInHierarchy;
/// <summary>
/// Attribute 기반 자동 바인딩 설정
/// </summary>
private void SetupAutoBindings()
{
var fields = GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)
.Where(f => f.GetCustomAttribute<BindToAttribute>() != null);
foreach (var field in fields)
{
var bindAttribute = field.GetCustomAttribute<BindToAttribute>();
SetupBinding(field, bindAttribute);
}
// 컬렉션 바인딩 설정
var collectionFields = GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)
.Where(f => f.GetCustomAttribute<BindCollectionAttribute>() != null);
foreach (var field in collectionFields)
{
var bindAttribute = field.GetCustomAttribute<BindCollectionAttribute>();
SetupCollectionBinding(field, bindAttribute);
}
}
/// <summary>
/// 개별 필드의 바인딩 설정
/// </summary>
private void SetupBinding(FieldInfo field, BindToAttribute bindAttribute)
{
var target = field.GetValue(this);
IValueConverter converter = null;
if (bindAttribute.ConverterType != null)
{
converter = Activator.CreateInstance(bindAttribute.ConverterType) as IValueConverter;
}
// UI 컴포넌트 타입별 바인딩 타겟 생성
IBindingTarget bindingTarget = target switch
{
Text text => new TextBindingTarget(text, bindAttribute.PropertyPath),
Image image => new ImageBindingTarget(image, bindAttribute.PropertyPath),
GameObject go => new ActiveBindingTarget(go, bindAttribute.PropertyPath),
Slider slider => new SliderBindingTarget(slider, bindAttribute.PropertyPath),
_ => null
};
if (bindingTarget != null)
{
_bindingContext.Bind(bindAttribute.PropertyPath, bindingTarget, converter);
}
}
/// <summary>
/// 컬렉션 바인딩 설정
/// </summary>
private void SetupCollectionBinding(FieldInfo field, BindCollectionAttribute bindAttribute)
{
var target = field.GetValue(this);
if (target is Transform parent)
{
// 컬렉션 바인딩 로직 (필요시 확장)
Debug.Log($"Collection binding for {bindAttribute.PropertyPath} is set up on {parent.name}");
}
}
/// <summary>
/// 추가 바인딩 설정 - 하위 클래스에서 구현
/// </summary>
protected virtual void SetupBindings() { }
/// <summary>
/// ViewModel 속성 변경 이벤트 핸들러
/// </summary>
protected virtual void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
HandleCustomPropertyChanged(e.PropertyName);
2025-08-05 05:14:39 +00:00
}
2025-08-17 07:23:05 +00:00
2025-08-20 09:08:41 +00:00
/// <summary>
/// 커스텀 속성 변경 처리 (하위 클래스에서 오버라이드)
/// </summary>
protected virtual void HandleCustomPropertyChanged(string propertyName)
{
// 하위 클래스에서 구현
}
// 수동 바인딩 헬퍼 메서드들
protected void BindText(Text text, string propertyPath, IValueConverter converter = null)
{
var target = new TextBindingTarget(text, propertyPath);
_bindingContext?.Bind(propertyPath, target, converter);
}
protected void BindImage(Image image, string propertyPath, IValueConverter converter = null)
{
var target = new ImageBindingTarget(image, propertyPath);
_bindingContext?.Bind(propertyPath, target, converter);
}
protected void BindActive(GameObject gameObject, string propertyPath, IValueConverter converter = null)
{
var target = new ActiveBindingTarget(gameObject, propertyPath);
_bindingContext?.Bind(propertyPath, target, converter);
}
protected void BindSlider(Slider slider, string propertyPath, IValueConverter converter = null)
{
var target = new SliderBindingTarget(slider, propertyPath);
_bindingContext?.Bind(propertyPath, target, converter);
}
2025-07-21 07:53:39 +00:00
}
}