using UnityEngine; using System.Collections.Generic; using System.Linq; using Streamingle; public class ItemController : MonoBehaviour, IController { #region Classes [System.Serializable] public class ItemGroup { [Header("Group Settings")] public string groupName = "New Item Group"; public GameObject[] itemObjects = new GameObject[0]; public ItemGroup(string name) { groupName = name; } public void SetActive(bool active) { if (itemObjects == null) return; foreach (var obj in itemObjects) { if (obj != null) { obj.SetActive(active); } } } public bool IsActive() { if (itemObjects == null || itemObjects.Length == 0) return false; // 모든 오브젝트가 활성화되어 있으면 true return itemObjects.All(obj => obj != null && obj.activeSelf); } public override string ToString() => groupName; } #endregion #region Events public delegate void ItemGroupChangedEventHandler(ItemGroup oldGroup, ItemGroup newGroup); public event ItemGroupChangedEventHandler OnItemGroupChanged; #endregion #region Fields [SerializeField] public List itemGroups = new List(); [Header("Item Control Settings")] [SerializeField] private bool autoFindGroups = true; [SerializeField] private string groupTag = "ItemGroup"; private ItemGroup currentGroup; private StreamDeckServerManager streamDeckManager; #endregion #region Properties public ItemGroup CurrentGroup => currentGroup; public int CurrentIndex => itemGroups.IndexOf(currentGroup); #endregion #region Unity Messages private void Awake() { InitializeItemGroups(); // StreamDeckServerManager 찾기 streamDeckManager = FindObjectOfType(); if (streamDeckManager == null) { Debug.LogWarning("[ItemController] StreamDeckServerManager를 찾을 수 없습니다. 스트림덱 연동이 비활성화됩니다."); } } #endregion #region Initialization public void InitializeItemGroups() { if (itemGroups == null) { itemGroups = new List(); } if (autoFindGroups && itemGroups.Count == 0) { // "ItemGroup" 태그가 붙은 모든 오브젝트를 찾아서 그룹으로 등록 var groupObjects = GameObject.FindGameObjectsWithTag(groupTag); foreach (var groupObj in groupObjects) { var group = new ItemGroup(groupObj.name); group.itemObjects = new GameObject[] { groupObj }; itemGroups.Add(group); } Debug.Log($"[ItemController] {itemGroups.Count}개의 아이템 그룹을 자동으로 찾았습니다."); } // 유효하지 않은 그룹 제거 itemGroups.RemoveAll(group => group == null || group.itemObjects == null || group.itemObjects.Length == 0); Debug.Log($"[ItemController] 총 {itemGroups.Count}개의 아이템 그룹이 등록되었습니다."); } #endregion #region Public Methods public void Set(int index) { if (index < 0 || index >= itemGroups.Count) { Debug.LogWarning($"[ItemController] 잘못된 인덱스: {index}, 유효 범위: 0-{itemGroups.Count - 1}"); return; } var oldGroup = currentGroup; currentGroup = itemGroups[index]; // 모든 그룹 비활성화 후 현재 그룹만 활성화 foreach (var group in itemGroups) { group.SetActive(false); } currentGroup.SetActive(true); // 이벤트 발생 OnItemGroupChanged?.Invoke(oldGroup, currentGroup); // StreamDeck에 알림 NotifyItemChanged(); Debug.Log($"[ItemController] 그룹 변경: {currentGroup.groupName} (인덱스: {index})"); } public void ToggleGroup(int index) { if (index < 0 || index >= itemGroups.Count) { Debug.LogWarning($"[ItemController] 잘못된 인덱스: {index}, 유효 범위: 0-{itemGroups.Count - 1}"); return; } var group = itemGroups[index]; bool newState = !group.IsActive(); group.SetActive(newState); // StreamDeck에 알림 NotifyItemChanged(); Debug.Log($"[ItemController] 그룹 토글: {group.groupName} -> {(newState ? "활성" : "비활성")}"); } public void ToggleGroup(ItemGroup group) { if (group == null) return; int index = itemGroups.IndexOf(group); if (index >= 0) { ToggleGroup(index); } } public void ToggleCurrentGroup() { if (currentGroup != null) { ToggleGroup(CurrentIndex); } } public void ActivateAllGroups() { foreach (var group in itemGroups) { group.SetActive(true); } NotifyItemChanged(); Debug.Log("[ItemController] 모든 그룹 활성화"); } public void DeactivateAllGroups() { foreach (var group in itemGroups) { group.SetActive(false); } NotifyItemChanged(); Debug.Log("[ItemController] 모든 그룹 비활성화"); } public void AddGroup(string groupName, GameObject[] objects = null) { var newGroup = new ItemGroup(groupName); if (objects != null) { newGroup.itemObjects = objects; } itemGroups.Add(newGroup); NotifyItemChanged(); Debug.Log($"[ItemController] 그룹 추가: {groupName}"); } public void RemoveGroup(int index) { if (index < 0 || index >= itemGroups.Count) return; var removedGroup = itemGroups[index]; itemGroups.RemoveAt(index); // 현재 그룹이 제거된 경우 첫 번째 그룹으로 변경 if (removedGroup == currentGroup) { currentGroup = itemGroups.Count > 0 ? itemGroups[0] : null; } NotifyItemChanged(); Debug.Log($"[ItemController] 그룹 제거: {removedGroup.groupName}"); } #endregion #region StreamDeck Integration private void NotifyItemChanged() { if (streamDeckManager != null) { var updateMessage = new { type = "item_changed", timestamp = System.DateTime.UtcNow.ToString("o"), version = "1.0", data = new { item_data = GetItemListData(), current_item = GetCurrentItemState() } }; string json = JsonUtility.ToJson(updateMessage); streamDeckManager.BroadcastMessage(json); Debug.Log("[ItemController] 아이템 변경 알림 전송됨"); } } public ItemListData GetItemListData() { return new ItemListData { item_count = itemGroups.Count, items = itemGroups.Select((g, i) => new ItemPresetData { index = i, name = g.groupName, isActive = g.IsActive() }).ToArray(), current_index = CurrentIndex }; } public ItemStateData GetCurrentItemState() { if (currentGroup == null) return null; return new ItemStateData { current_index = CurrentIndex, item_name = currentGroup.groupName, isActive = currentGroup.IsActive(), total_items = itemGroups.Count }; } public string GetItemListJson() { return JsonUtility.ToJson(GetItemListData()); } public string GetItemStateJson() { return JsonUtility.ToJson(GetCurrentItemState()); } #endregion #region Data Classes [System.Serializable] public class ItemPresetData { public int index; public string name; public bool isActive; } [System.Serializable] public class ItemListData { public int item_count; public ItemPresetData[] items; public int current_index; } [System.Serializable] public class ItemStateData { public int current_index; public string item_name; public bool isActive; public int total_items; } #endregion #region IController Implementation public string GetControllerId() { return "item_controller"; } public string GetControllerName() { return "Item Controller"; } public object GetControllerData() { return GetItemListData(); } public void ExecuteAction(string actionId, object parameters) { switch (actionId) { case "toggle_item": { if (parameters is int toggleIndex) { ToggleGroup(toggleIndex); } } break; case "set_item": { if (parameters is int setIndex) { Set(setIndex); } } break; case "activate_all": ActivateAllGroups(); break; case "deactivate_all": DeactivateAllGroups(); break; default: Debug.LogWarning($"[ItemController] 알 수 없는 액션: {actionId}"); break; } } #endregion }