RestaurantManagementUi 작업 중

This commit is contained in:
NTG_DESKTOP 2025-07-28 04:32:41 +09:00
parent b575c422cf
commit 9fda677d2c
17 changed files with 398 additions and 198 deletions

View File

@ -4,9 +4,9 @@ SpriteAtlasImporter:
externalObjects: {} externalObjects: {}
textureSettings: textureSettings:
serializedVersion: 2 serializedVersion: 2
anisoLevel: 0 anisoLevel: 1
compressionQuality: 0 compressionQuality: 50
maxTextureSize: 0 maxTextureSize: 2048
textureCompression: 0 textureCompression: 0
filterMode: 1 filterMode: 1
generateMipMaps: 0 generateMipMaps: 0
@ -17,10 +17,10 @@ SpriteAtlasImporter:
packingSettings: packingSettings:
serializedVersion: 2 serializedVersion: 2
padding: 4 padding: 4
blockOffset: 0 blockOffset: 1
allowAlphaSplitting: 0 allowAlphaSplitting: 0
enableRotation: 0 enableRotation: 1
enableTightPacking: 0 enableTightPacking: 1
enableAlphaDilation: 0 enableAlphaDilation: 0
secondaryTextureSettings: {} secondaryTextureSettings: {}
variantMultiplier: 1 variantMultiplier: 1

View File

@ -119,6 +119,19 @@ TextureImporter:
ignorePlatformSupport: 0 ignorePlatformSupport: 0
androidETC2FallbackOverride: 0 androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0 forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: iOS
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet: spriteSheet:
serializedVersion: 2 serializedVersion: 2
sprites: [] sprites: []

View File

@ -6129,6 +6129,10 @@ PrefabInstance:
propertyPath: m_fontSize propertyPath: m_fontSize
value: 32 value: 32
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 2189377788458160067, guid: d11d5cf80be02d7469f07db925af284a, type: 3}
propertyPath: m_Navigation.m_Mode
value: 0
objectReference: {fileID: 0}
- target: {fileID: 2189377788458160067, guid: d11d5cf80be02d7469f07db925af284a, type: 3} - target: {fileID: 2189377788458160067, guid: d11d5cf80be02d7469f07db925af284a, type: 3}
propertyPath: m_Colors.m_NormalColor.b propertyPath: m_Colors.m_NormalColor.b
value: 0.45098042 value: 0.45098042
@ -6678,6 +6682,10 @@ PrefabInstance:
propertyPath: m_fontSize propertyPath: m_fontSize
value: 32 value: 32
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 2189377788458160067, guid: d11d5cf80be02d7469f07db925af284a, type: 3}
propertyPath: m_Navigation.m_Mode
value: 0
objectReference: {fileID: 0}
- target: {fileID: 2189377788458160067, guid: d11d5cf80be02d7469f07db925af284a, type: 3} - target: {fileID: 2189377788458160067, guid: d11d5cf80be02d7469f07db925af284a, type: 3}
propertyPath: m_Colors.m_NormalColor.b propertyPath: m_Colors.m_NormalColor.b
value: 0.45098042 value: 0.45098042
@ -7847,6 +7855,10 @@ PrefabInstance:
propertyPath: m_fontSize propertyPath: m_fontSize
value: 32 value: 32
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 2189377788458160067, guid: d11d5cf80be02d7469f07db925af284a, type: 3}
propertyPath: m_Navigation.m_Mode
value: 0
objectReference: {fileID: 0}
- target: {fileID: 2189377788458160067, guid: d11d5cf80be02d7469f07db925af284a, type: 3} - target: {fileID: 2189377788458160067, guid: d11d5cf80be02d7469f07db925af284a, type: 3}
propertyPath: m_Colors.m_NormalColor.b propertyPath: m_Colors.m_NormalColor.b
value: 0.45098042 value: 0.45098042

View File

@ -19,7 +19,8 @@ public static class GameEvents
public static class RestaurantEvents public static class RestaurantEvents
{ {
public static ItemSlotSelectedEvent ItemSlotSelectedEvent = new(); public static ItemSlotSelectedEvent ItemSlotSelectedEvent = new();
public static TodayMenuChangedEvent TodayMenuChangedEvent = new(); public static TodayMenuAddedEvent TodayMenuAddedEvent = new();
public static TodayMenuRemovedEvent TodayMenuRemovedEvent = new();
} }
// public static class VoyageEvents // public static class VoyageEvents
@ -79,7 +80,12 @@ public class ItemSlotSelectedEvent : IEvent
public ItemViewModel Model; public ItemViewModel Model;
} }
public class TodayMenuChangedEvent : IEvent {} public class TodayMenuAddedEvent : IEvent {}
public class TodayMenuRemovedEvent : IEvent
{
public RecipeType RecipeType;
}
#endregion #endregion
} }

View File

@ -0,0 +1,77 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Sirenix.OdinInspector;
using UnityEngine;
namespace DDD
{
[CreateAssetMenu(fileName = "TodayMenuDataSo", menuName = "GameState/TodayMenuDataSo")]
public class TodayMenuDataSo : GameFlowTask
{
[ReadOnly, SerializeField] private List<string> _foodRecipeIds = new();
[ReadOnly, SerializeField] private List<string> _drinkRecipeIds = new();
public IReadOnlyList<string> FoodRecipeIds => _foodRecipeIds;
public IReadOnlyList<string> DrinkRecipeIds => _drinkRecipeIds;
public int MaxFoodCount = 8;
public int MaxDrinkCount = 6;
public override Task OnReadyNewFlow(GameFlowState newFlowState)
{
_foodRecipeIds.Clear();
_drinkRecipeIds.Clear();
return Task.CompletedTask;
}
public bool TryAddTodayMenu(IInventorySlotUi itemSlotUi)
{
string recipeId = itemSlotUi.Model.Id;
if (_foodRecipeIds.Count >= MaxFoodCount || _foodRecipeIds.Contains(recipeId)) return false;
if (itemSlotUi.Model.ItemType == ItemType.Recipe)
{
if (DataManager.Instance.RecipeDataSo.TryGetDataById(recipeId, out RecipeData recipeData))
{
if (recipeData.RecipeType == RecipeType.FoodRecipe)
{
_foodRecipeIds.Add(recipeId);
}
else if (recipeData.RecipeType == RecipeType.DrinkRecipe)
{
_drinkRecipeIds.Add(recipeId);
}
}
}
EventBus.Broadcast(RestaurantEvents.TodayMenuAddedEvent);
return true;
}
public bool TryRemoveTodayMenu(IInventorySlotUi itemSlotUi)
{
string recipeId = itemSlotUi.Model.Id;
var evt = RestaurantEvents.TodayMenuRemovedEvent;
if (_foodRecipeIds.Remove(recipeId))
{
evt.RecipeType = RecipeType.FoodRecipe;
}
else if (_drinkRecipeIds.Remove(recipeId))
{
evt.RecipeType = RecipeType.DrinkRecipe;
}
else
{
return false;
}
EventBus.Broadcast(evt);
return true;
}
public bool IsContainTodayMenu(string recipeId) => _foodRecipeIds.Contains(recipeId) || _drinkRecipeIds.Contains(recipeId);
}
}

View File

@ -2,7 +2,9 @@ namespace DDD
{ {
public interface IInventorySlotUi public interface IInventorySlotUi
{ {
void Initialize(ItemViewModel model); ItemViewModel Model { get; }
void UpdateCount(int newCount); void Initialize(ItemViewModel model, RecipeType recipeType = RecipeType.None);
bool CanCraft();
void SetActive(bool value);
} }
} }

View File

@ -1,49 +1,105 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using UnityEngine.EventSystems;
namespace DDD namespace DDD
{ {
public class InventoryView : MonoBehaviour, IEventHandler<InventoryChangedEvent> public class InventoryView : MonoBehaviour, IEventHandler<InventoryChangedEvent>, IEventHandler<TodayMenuAddedEvent>, IEventHandler<TodayMenuRemovedEvent>
{ {
[SerializeField] private Transform _slotParent; [SerializeField] private Transform _slotParent;
[SerializeField] private GameObject _slotPrefab; [SerializeField] private GameObject _slotPrefab;
private TodayMenuDataSo _todayMenuDataSo;
private InventoryCategoryType _currenInventoryCategoryType = InventoryCategoryType.None;
private readonly Dictionary<string, IInventorySlotUi> _slotLookup = new(); private readonly Dictionary<string, IInventorySlotUi> _slotLookup = new();
private readonly Dictionary<string, ItemViewModel> _modelLookup = new();
private void OnEnable() private void OnEnable()
{ {
EventBus.Register<InventoryChangedEvent>(this); EventBus.Register<InventoryChangedEvent>(this);
EventBus.Register<TodayMenuAddedEvent>(this);
EventBus.Register<TodayMenuRemovedEvent>(this);
} }
private void OnDisable() private void OnDisable()
{ {
EventBus.Unregister<InventoryChangedEvent>(this); EventBus.Unregister<InventoryChangedEvent>(this);
EventBus.Unregister<TodayMenuAddedEvent>(this);
EventBus.Unregister<TodayMenuRemovedEvent>(this);
} }
public void ShowItems(Func<ItemData, bool> predicate) public async Task Initialize()
{ {
_todayMenuDataSo = await AssetManager.LoadAsset<TodayMenuDataSo>(DataConstants.TodayMenuDataSo);
Debug.Assert(_todayMenuDataSo != null, "_todayMenuDataSo != null");
Clear(); Clear();
var models = ItemViewModelFactory.CreateRestaurantManagementInventoryItem(predicate); var models = ItemViewModelFactory.CreateRestaurantManagementInventoryItem();
_slotLookup.Clear();
_modelLookup.Clear();
foreach (var model in models) foreach (var model in models)
{ {
var go = Instantiate(_slotPrefab, _slotParent); var go = Instantiate(_slotPrefab, _slotParent);
var slot = go.GetComponent<IInventorySlotUi>(); var slot = go.GetComponent<IInventorySlotUi>();
slot.Initialize(model); slot.Initialize(model);
// 슬롯 참조 저장 var interactor = go.GetComponent<TodayMenuInteractor>();
_slotLookup[model.Id] = slot; interactor.Initialize(TodayMenuEventType.Add);
}
if (_slotParent.childCount > 0) _slotLookup[model.Id] = slot;
{ _modelLookup[model.Id] = model;
EventSystem.current.SetSelectedGameObject(_slotParent.GetChild(0).gameObject);
} }
} }
public void UpdateCategoryView(InventoryCategoryType category)
{
_currenInventoryCategoryType = category;
foreach (var kvp in _slotLookup)
{
var id = kvp.Key;
var slot = kvp.Value;
var model = slot.Model;
// 1. 오늘의 메뉴에 등록된 경우 필터링
bool isRegisteredTodayMenu = model.ItemType == ItemType.Recipe && _todayMenuDataSo.IsContainTodayMenu(id);
// 2. 현재 선택된 카테고리에 맞는지 필터링
bool matchCategory = MatchesCategory(model, _currenInventoryCategoryType);
// 3. 조건을 모두 만족할 경우만 활성화
bool shouldShow = !isRegisteredTodayMenu && matchCategory;
slot.SetActive(shouldShow);
}
}
private bool MatchesCategory(ItemViewModel model, InventoryCategoryType category)
{
switch (category)
{
case InventoryCategoryType.Food:
if (model.ItemType != ItemType.Recipe) return false;
return DataManager.Instance.RecipeDataSo.TryGetDataById(model.Id, out var foodRecipe) && foodRecipe.RecipeType == RecipeType.FoodRecipe;
case InventoryCategoryType.Drink:
if (model.ItemType != ItemType.Recipe) return false;
return DataManager.Instance.RecipeDataSo.TryGetDataById(model.Id, out var drinkRecipe) && drinkRecipe.RecipeType == RecipeType.DrinkRecipe;
case InventoryCategoryType.Ingredient:
return model.ItemType == ItemType.Ingredient;
default:
return false;
}
}
public void UpdateView()
{
UpdateCategoryView(_currenInventoryCategoryType);
}
private void Clear() private void Clear()
{ {
foreach (Transform child in _slotParent) foreach (Transform child in _slotParent)
@ -56,8 +112,18 @@ public void Invoke(InventoryChangedEvent evt)
{ {
if (_slotLookup.TryGetValue(evt.ItemId, out var slot)) if (_slotLookup.TryGetValue(evt.ItemId, out var slot))
{ {
slot.UpdateCount(evt.NewCount); slot.Model.UpdateCount(evt.NewCount);
} }
} }
public void Invoke(TodayMenuAddedEvent evt)
{
UpdateView();
}
public void Invoke(TodayMenuRemovedEvent evt)
{
UpdateView();
}
} }
} }

View File

@ -17,10 +17,11 @@ public class ItemSlotUi : MonoBehaviour, IInventorySlotUi
public ItemViewModel Model { get; private set; } public ItemViewModel Model { get; private set; }
public void Initialize(ItemViewModel model) public void Initialize(ItemViewModel model, RecipeType recipeType = RecipeType.None)
{ {
Model = model; Model = model;
_button.onClick.RemoveAllListeners();
_button.onClick.AddListener(() => _button.onClick.AddListener(() =>
{ {
RestaurantEvents.ItemSlotSelectedEvent.Model = Model; RestaurantEvents.ItemSlotSelectedEvent.Model = Model;
@ -30,47 +31,59 @@ public void Initialize(ItemViewModel model)
if (model != null) if (model != null)
{ {
_icon.sprite = model.Icon; _icon.sprite = model.Icon;
_countText.text = model.Count?.ToString() ?? string.Empty; _countText.text = model.Count.ToString();
_countText.gameObject.SetActive(true); EnableCountText();
_markImage.gameObject.SetActive(false);
_button.interactable = true; _button.interactable = true;
} }
else else
{ {
_countText.gameObject.SetActive(false); if (recipeType == RecipeType.FoodRecipe)
_markImage.gameObject.SetActive(true); {
SetEmptyFood();
}
else if (recipeType == RecipeType.DrinkRecipe)
{
SetEmptyDrink();
}
EnableMarkImage();
_button.interactable = false; _button.interactable = false;
} }
} }
public void UpdateCount(int newCount) public bool CanCraft()
{ {
_countText.text = newCount.ToString(); return Model.Count > 0;
} }
public void SetMark(bool registered) public void EnableCountText()
{
//_markImage.sprite = registered ? _checkSprite : _xSprite;
_countText.gameObject.SetActive(false);
_markImage.gameObject.SetActive(true);
}
public void ClearMark()
{ {
_countText.gameObject.SetActive(true); _countText.gameObject.SetActive(true);
_markImage.gameObject.SetActive(false); _markImage.gameObject.SetActive(false);
} }
public void EnableMarkImage()
{
// TODO : 추후에 현재 등록된 요리도구와 매칭되는지 체크
//_markImage.sprite = registered ? _checkSprite : _xSprite;
_countText.gameObject.SetActive(false);
_markImage.gameObject.SetActive(true);
}
public void SetEmptyFood() public void SetEmptyFood()
{ {
_icon.sprite = _emptyFoodSprite; _icon.sprite = _emptyFoodSprite;
_markImage.gameObject.SetActive(false); _markImage.gameObject.SetActive(false);
_button.interactable = false;
} }
public void SetEmptyDrink() public void SetEmptyDrink()
{ {
_icon.sprite = _emptyDrinkSprite; _icon.sprite = _emptyDrinkSprite;
_markImage.gameObject.SetActive(false); _markImage.gameObject.SetActive(false);
_button.interactable = false;
} }
public void SetActive(bool value) => gameObject.SetActive(value);
} }
} }

View File

@ -1,4 +1,3 @@
using System;
using UnityEngine; using UnityEngine;
namespace DDD namespace DDD
@ -10,13 +9,30 @@ public class ItemViewModel
public string NameKey; public string NameKey;
public string DescriptionKey; public string DescriptionKey;
public Sprite Icon; public Sprite Icon;
public int? Count; public int Count;
public Action<ItemViewModel> OnCountChanged; public RecipeType RecipeType => ItemType == ItemType.Recipe ? DataManager.Instance.RecipeDataSo.GetDataById(Id).RecipeType : RecipeType.None;
public void UpdateCount() public void UpdateCount(int newCount)
{ {
OnCountChanged?.Invoke(this); if (ItemType == ItemType.Recipe)
{
int craftableCount = 0;
if (RecipeType == RecipeType.FoodRecipe)
{
craftableCount = DataManager.Instance.FoodDataSo.GetDataById(Id).GetCraftableCount();
}
else if (RecipeType == RecipeType.DrinkRecipe)
{
craftableCount = DataManager.Instance.DrinkDataSo.GetDataById(Id).GetCraftableCount();
}
Count = craftableCount;
}
else if (ItemType == ItemType.Ingredient)
{
Count = newCount;
}
} }
} }
} }

View File

@ -1,4 +1,3 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -6,7 +5,7 @@ namespace DDD
{ {
public static class ItemViewModelFactory public static class ItemViewModelFactory
{ {
public static List<ItemViewModel> CreateRestaurantManagementInventoryItem(Func<ItemData, bool> predicate) public static List<ItemViewModel> CreateRestaurantManagementInventoryItem()
{ {
var result = new List<ItemViewModel>(); var result = new List<ItemViewModel>();
var recipeDataMap = DataManager.Instance.RecipeDataSo.GetDataList().ToDictionary(r => r.Id, r => r); var recipeDataMap = DataManager.Instance.RecipeDataSo.GetDataList().ToDictionary(r => r.Id, r => r);
@ -18,7 +17,7 @@ public static List<ItemViewModel> CreateRestaurantManagementInventoryItem(Func<I
{ {
var id = kvp.Key; var id = kvp.Key;
var item = InventoryManager.Instance.GetItemDataByIdOrNull(id); var item = InventoryManager.Instance.GetItemDataByIdOrNull(id);
if (item == null || !predicate(item)) continue; if (item == null) continue;
var model = new ItemViewModel var model = new ItemViewModel
{ {
@ -29,7 +28,7 @@ public static List<ItemViewModel> CreateRestaurantManagementInventoryItem(Func<I
{ {
ItemType.Recipe => CalculateCraftableCount(item.Id), ItemType.Recipe => CalculateCraftableCount(item.Id),
ItemType.Ingredient => InventoryManager.Instance.GetItemCount(id), ItemType.Ingredient => InventoryManager.Instance.GetItemCount(id),
_ => null _ => 0
} }
}; };
@ -45,6 +44,7 @@ public static List<ItemViewModel> CreateRestaurantManagementInventoryItem(Func<I
model.NameKey = food.NameKey; model.NameKey = food.NameKey;
model.DescriptionKey = food.DescriptionKey; model.DescriptionKey = food.DescriptionKey;
} }
break; break;
case RecipeType.DrinkRecipe: case RecipeType.DrinkRecipe:
if (drinkDataMap.TryGetValue(itemKey, out var drink)) if (drinkDataMap.TryGetValue(itemKey, out var drink))
@ -52,6 +52,7 @@ public static List<ItemViewModel> CreateRestaurantManagementInventoryItem(Func<I
model.NameKey = drink.NameKey; model.NameKey = drink.NameKey;
model.DescriptionKey = drink.DescriptionKey; model.DescriptionKey = drink.DescriptionKey;
} }
break; break;
} }
} }
@ -75,10 +76,53 @@ private static int CalculateCraftableCount(string recipeId)
return recipe.RecipeType switch return recipe.RecipeType switch
{ {
RecipeType.FoodRecipe => DataManager.Instance.FoodDataSo.TryGetDataById(itemKey, out var food) ? food.GetCraftableCount() : 0, RecipeType.FoodRecipe => DataManager.Instance.FoodDataSo.TryGetDataById(itemKey, out var food)
RecipeType.DrinkRecipe => DataManager.Instance.DrinkDataSo.TryGetDataById(itemKey, out var drink) ? drink.GetCraftableCount() : 0, ? food.GetCraftableCount()
: 0,
RecipeType.DrinkRecipe => DataManager.Instance.DrinkDataSo.TryGetDataById(itemKey, out var drink)
? drink.GetCraftableCount()
: 0,
_ => 0 _ => 0
}; };
} }
public static ItemViewModel CreateByRecipeId(string recipeId)
{
var recipeSo = DataManager.Instance.RecipeDataSo;
if (!recipeSo.TryGetDataById(recipeId, out var recipe))
return null;
var item = InventoryManager.Instance.GetItemDataByIdOrNull(recipeId);
if (item == null) return null;
var model = new ItemViewModel
{
Id = recipeId,
ItemType = item.ItemType,
Icon = DataManager.Instance.GetSprite(recipeId)
};
switch (recipe.RecipeType)
{
case RecipeType.FoodRecipe:
if (DataManager.Instance.FoodDataSo.TryGetDataById(recipe.ItemKey, out var food))
{
model.NameKey = food.NameKey;
model.DescriptionKey = food.DescriptionKey;
}
break;
case RecipeType.DrinkRecipe:
if (DataManager.Instance.DrinkDataSo.TryGetDataById(recipe.ItemKey, out var drink))
{
model.NameKey = drink.NameKey;
model.DescriptionKey = drink.DescriptionKey;
}
break;
}
return model;
}
} }
} }

View File

@ -1,52 +0,0 @@
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
namespace DDD
{
[CreateAssetMenu(fileName = "TodayMenuDataSo", menuName = "GameState/TodayMenuDataSo")]
public class TodayMenuDataSo : ScriptableObject
{
[ReadOnly, SerializeField] private List<string> _foodRecipeIds = new();
[ReadOnly, SerializeField] private List<string> _drinkRecipeIds = new();
public IReadOnlyList<string> FoodRecipeIds => _foodRecipeIds;
public IReadOnlyList<string> DrinkRecipeIds => _drinkRecipeIds;
public int MaxFoodCount = 8;
public int MaxDrinkCount = 6;
public bool TryAddFoodRecipe(string recipeId)
{
if (_foodRecipeIds.Count >= MaxFoodCount || _foodRecipeIds.Contains(recipeId))
return false;
_foodRecipeIds.Add(recipeId);
EventBus.Broadcast(RestaurantEvents.TodayMenuChangedEvent);
return true;
}
public bool TryAddDrinkRecipe(string recipeId)
{
if (_drinkRecipeIds.Count >= MaxDrinkCount || _drinkRecipeIds.Contains(recipeId))
return false;
_drinkRecipeIds.Add(recipeId);
EventBus.Broadcast(RestaurantEvents.TodayMenuChangedEvent);
return true;
}
public bool RemoveRecipe(string recipeId)
{
bool removed = _foodRecipeIds.Remove(recipeId) || _drinkRecipeIds.Remove(recipeId);
if (removed)
{
EventBus.Broadcast(RestaurantEvents.TodayMenuChangedEvent);
}
return removed;
}
public bool Contains(string recipeId) => _foodRecipeIds.Contains(recipeId) || _drinkRecipeIds.Contains(recipeId);
}
}

View File

@ -1,21 +1,32 @@
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
namespace DDD namespace DDD
{ {
public enum TodayMenuEventType
{
None = 0,
Add,
Remove
}
public class TodayMenuInteractor : MonoBehaviour, IInteractableUi public class TodayMenuInteractor : MonoBehaviour, IInteractableUi
{ {
private ItemSlotUi _slotUi; private IInventorySlotUi _inventorySlotUi;
private TodayMenuDataSo _todayMenuDataSo; private TodayMenuDataSo _todayMenuDataSo;
private TaskCompletionSource<bool> _isInitialized = new(); private TaskCompletionSource<bool> _isInitialized = new();
private TodayMenuEventType _todayMenuEventType = TodayMenuEventType.None;
private void Awake() private void Awake()
{ {
_slotUi = GetComponent<ItemSlotUi>(); _inventorySlotUi = GetComponent<IInventorySlotUi>();
} }
private async void Start() public async void Initialize(TodayMenuEventType todayMenuEventType)
{ {
_todayMenuEventType = todayMenuEventType;
_todayMenuDataSo = await AssetManager.LoadAsset<TodayMenuDataSo>(DataConstants.TodayMenuDataSo); _todayMenuDataSo = await AssetManager.LoadAsset<TodayMenuDataSo>(DataConstants.TodayMenuDataSo);
_isInitialized.SetResult(true); _isInitialized.SetResult(true);
} }
@ -24,24 +35,39 @@ public async void OnInteract()
{ {
await _isInitialized.Task; await _isInitialized.Task;
string recipeId = _slotUi.Model.Id; switch (_todayMenuEventType)
if (_todayMenuDataSo.Contains(recipeId))
{ {
_todayMenuDataSo.RemoveRecipe(recipeId); case TodayMenuEventType.Add:
_slotUi.ClearMark(); OnAdded();
break;
case TodayMenuEventType.Remove:
OnRemoved();
break;
case TodayMenuEventType.None:
default:
throw new ArgumentOutOfRangeException();
} }
else }
{
var recipe = DataManager.Instance.RecipeDataSo.GetDataById(recipeId);
bool added = recipe.RecipeType switch private void OnAdded()
{ {
RecipeType.FoodRecipe => _todayMenuDataSo.TryAddFoodRecipe(recipeId), if (_inventorySlotUi.CanCraft() == false)
RecipeType.DrinkRecipe => _todayMenuDataSo.TryAddDrinkRecipe(recipeId), {
_ => false var evt = GameEvents.RequestShowGlobalMessageEvent;
}; // TODO : 테스트용 메세지 추후 삭제 및 변경
evt.NewMessageKey = "today_menu_added_error_message_001";
evt.FadeDuration = 0.5f;
evt.ShowDuration = 1f;
EventBus.Broadcast(evt);
return;
} }
_todayMenuDataSo.TryAddTodayMenu(_inventorySlotUi);
}
private void OnRemoved()
{
_todayMenuDataSo.TryRemoveTodayMenu(_inventorySlotUi);
} }
} }
} }

View File

@ -3,21 +3,22 @@
namespace DDD namespace DDD
{ {
public class TodayMenuView : MonoBehaviour, IEventHandler<TodayMenuChangedEvent> public class TodayMenuView : MonoBehaviour, IEventHandler<TodayMenuAddedEvent>, IEventHandler<TodayMenuRemovedEvent>
{ {
[SerializeField] private GameObject _slotPrefab; [SerializeField] private GameObject _slotPrefab;
[SerializeField] private Transform _todayFoodContent; [SerializeField] private Transform _todayFoodContent;
[SerializeField] private Transform _todayDrinkContent; [SerializeField] private Transform _todayDrinkContent;
private List<ItemSlotUi> _foodSlots; private List<IInventorySlotUi> _foodSlots;
private List<ItemSlotUi> _drinkSlots; private List<IInventorySlotUi> _drinkSlots;
private TodayMenuDataSo _todayMenuDataSo; private TodayMenuDataSo _todayMenuDataSo;
private async void Start() private async void Start()
{ {
EventBus.Register<TodayMenuChangedEvent>(this); EventBus.Register<TodayMenuAddedEvent>(this);
EventBus.Register<TodayMenuRemovedEvent>(this);
_todayMenuDataSo = await AssetManager.LoadAsset<TodayMenuDataSo>(DataConstants.TodayMenuDataSo); _todayMenuDataSo = await AssetManager.LoadAsset<TodayMenuDataSo>(DataConstants.TodayMenuDataSo);
@ -27,13 +28,15 @@ private async void Start()
} }
int maxFoodCount = _todayMenuDataSo.MaxFoodCount; int maxFoodCount = _todayMenuDataSo.MaxFoodCount;
_foodSlots = new List<ItemSlotUi>(maxFoodCount); _foodSlots = new List<IInventorySlotUi>(maxFoodCount);
for (int i = 0; i < _todayMenuDataSo.MaxFoodCount; i++) for (int i = 0; i < _todayMenuDataSo.MaxFoodCount; i++)
{ {
var go = Instantiate(_slotPrefab, _todayFoodContent); var go = Instantiate(_slotPrefab, _todayFoodContent);
var slot = go.GetComponent<ItemSlotUi>(); var slot = go.GetComponent<IInventorySlotUi>();
slot.Initialize(null); slot.Initialize(null, RecipeType.FoodRecipe);
slot.SetEmptyFood(); var todayMenuInteractor = go.GetComponent<TodayMenuInteractor>();
todayMenuInteractor.Initialize(TodayMenuEventType.Remove);
_foodSlots.Add(slot); _foodSlots.Add(slot);
} }
@ -43,51 +46,52 @@ private async void Start()
} }
int maxDrinkCount = _todayMenuDataSo.MaxDrinkCount; int maxDrinkCount = _todayMenuDataSo.MaxDrinkCount;
_drinkSlots = new List<ItemSlotUi>(maxDrinkCount); _drinkSlots = new List<IInventorySlotUi>(maxDrinkCount);
for (int i = 0; i < _todayMenuDataSo.MaxDrinkCount; i++) for (int i = 0; i < _todayMenuDataSo.MaxDrinkCount; i++)
{ {
var go = Instantiate(_slotPrefab, _todayDrinkContent); var go = Instantiate(_slotPrefab, _todayDrinkContent);
var slot = go.GetComponent<ItemSlotUi>(); var slot = go.GetComponent<IInventorySlotUi>();
slot.Initialize(null); slot.Initialize(null, RecipeType.DrinkRecipe);
slot.SetEmptyDrink(); var todayMenuInteractor = go.GetComponent<TodayMenuInteractor>();
todayMenuInteractor.Initialize(TodayMenuEventType.Remove);
_drinkSlots.Add(slot); _drinkSlots.Add(slot);
} }
//RefreshView(); UpdateView();
} }
private void OnDestroy() private void OnDestroy()
{ {
EventBus.Unregister<TodayMenuChangedEvent>(this); EventBus.Unregister<TodayMenuAddedEvent>(this);
EventBus.Unregister<TodayMenuRemovedEvent>(this);
} }
public void Invoke(TodayMenuChangedEvent evt) => RefreshView(); public void Invoke(TodayMenuAddedEvent evt)
{
UpdateView();
}
private void RefreshView() public void Invoke(TodayMenuRemovedEvent evt)
{
UpdateView();
}
private void UpdateView()
{ {
for (int i = 0; i < _foodSlots.Count; i++) for (int i = 0; i < _foodSlots.Count; i++)
{ {
if (i < _todayMenuDataSo.FoodRecipeIds.Count) if (i < _todayMenuDataSo.FoodRecipeIds.Count)
{ {
string recipeId = _todayMenuDataSo.FoodRecipeIds[i]; string recipeId = _todayMenuDataSo.FoodRecipeIds[i];
var recipe = DataManager.Instance.RecipeDataSo.GetDataById(recipeId); var model = ItemViewModelFactory.CreateByRecipeId(recipeId);
var item = InventoryManager.Instance.GetItemDataByIdOrNull(recipeId);
var model = new ItemViewModel
{
Id = recipeId,
Icon = DataManager.Instance.GetSprite(recipeId),
ItemType = item.ItemType,
NameKey = DataManager.Instance.FoodDataSo.GetDataById(recipe.ItemKey).NameKey,
DescriptionKey = DataManager.Instance.FoodDataSo.GetDataById(recipe.ItemKey).DescriptionKey
};
_foodSlots[i].Initialize(model); _foodSlots[i].Initialize(model);
//_foodSlots[i].SetMark(true); // 등록 상태 마크 _foodSlots[i].SetActive(true);
} }
else else
{ {
//_foodSlots[i].gameObject.SetActive(false); // 또는 Clear() _foodSlots[i].Initialize(null, RecipeType.FoodRecipe);
} }
} }
@ -96,24 +100,14 @@ private void RefreshView()
if (i < _todayMenuDataSo.DrinkRecipeIds.Count) if (i < _todayMenuDataSo.DrinkRecipeIds.Count)
{ {
string recipeId = _todayMenuDataSo.DrinkRecipeIds[i]; string recipeId = _todayMenuDataSo.DrinkRecipeIds[i];
var recipe = DataManager.Instance.RecipeDataSo.GetDataById(recipeId); var model = ItemViewModelFactory.CreateByRecipeId(recipeId);
var item = InventoryManager.Instance.GetItemDataByIdOrNull(recipeId);
var model = new ItemViewModel
{
Id = recipeId,
Icon = DataManager.Instance.GetSprite(recipeId),
ItemType = item.ItemType,
NameKey = DataManager.Instance.DrinkDataSo.GetDataById(recipe.ItemKey).NameKey,
DescriptionKey = DataManager.Instance.DrinkDataSo.GetDataById(recipe.ItemKey).DescriptionKey
};
_drinkSlots[i].Initialize(model); _drinkSlots[i].Initialize(model);
//_drinkSlots[i].SetMark(true); _drinkSlots[i].SetActive(true);
} }
else else
{ {
//_drinkSlots[i].gameObject.SetActive(false); _drinkSlots[i].Initialize(null, RecipeType.DrinkRecipe);
} }
} }
} }

View File

@ -15,6 +15,7 @@ public override void Open()
{ {
base.Open(); base.Open();
_ = _inventoryView.Initialize();
_sectionTabs.Initialize(OnSectionTabSelected); _sectionTabs.Initialize(OnSectionTabSelected);
_categoryTabs.Initialize(OnCategoryTabSelected); _categoryTabs.Initialize(OnCategoryTabSelected);
} }
@ -69,32 +70,12 @@ private void HandleInteract2()
private void OnSectionTabSelected(RestaurantManagementSectionType section) private void OnSectionTabSelected(RestaurantManagementSectionType section)
{ {
// 추후 Menu, Cookware, Worker에 맞춰 다른 콘텐츠 노출 처리 // TODO : 추후 Menu, Cookware, Worker에 맞춰 다른 콘텐츠 노출 처리
} }
private void OnCategoryTabSelected(InventoryCategoryType category) private void OnCategoryTabSelected(InventoryCategoryType category)
{ {
_inventoryView.ShowItems(itemData => _inventoryView.UpdateCategoryView(category);
{
switch (category)
{
case InventoryCategoryType.Food:
case InventoryCategoryType.Drink:
if (itemData.ItemType != ItemType.Recipe) return false;
RecipeType recipeType = DataManager.Instance.RecipeDataSo.GetDataById(itemData.Id).RecipeType;
return category switch
{
InventoryCategoryType.Food => recipeType == RecipeType.FoodRecipe,
InventoryCategoryType.Drink => recipeType == RecipeType.DrinkRecipe,
_ => false
};
case InventoryCategoryType.Ingredient:
return itemData.ItemType == ItemType.Ingredient;
default:
return false;
}
});
} }
} }
} }

View File

@ -62,11 +62,13 @@ public async Task OnReadyNewFlow(GameFlowState newFlowState)
{ {
CreateRestaurantPlayerSo createRestaurantPlayerSoJob = await AssetManager.LoadAsset<CreateRestaurantPlayerSo>(CreateRestaurantPlayerSo); CreateRestaurantPlayerSo createRestaurantPlayerSoJob = await AssetManager.LoadAsset<CreateRestaurantPlayerSo>(CreateRestaurantPlayerSo);
CreateEnvironmentSo createEnvironmentSoJob = await AssetManager.LoadAsset<CreateEnvironmentSo>(CreateEnvironmentSo); CreateEnvironmentSo createEnvironmentSoJob = await AssetManager.LoadAsset<CreateEnvironmentSo>(CreateEnvironmentSo);
TodayMenuDataSo todayMenuDataSo = await AssetManager.LoadAsset<TodayMenuDataSo>(DataConstants.TodayMenuDataSo);
var playerHandle = createRestaurantPlayerSoJob.OnReadyNewFlow(newFlowState); var playerHandle = createRestaurantPlayerSoJob.OnReadyNewFlow(newFlowState);
var propHandle = createEnvironmentSoJob.OnReadyNewFlow(newFlowState); var propHandle = createEnvironmentSoJob.OnReadyNewFlow(newFlowState);
var todayMenuHandle = todayMenuDataSo.OnReadyNewFlow(newFlowState);
// Combine handles and return it // Combine handles and return it
InputManager.Instance.SwitchCurrentActionMap(InputActionMaps.Restaurant); InputManager.Instance.SwitchCurrentActionMap(InputActionMaps.Restaurant);
await Task.WhenAll(playerHandle, propHandle); await Task.WhenAll(playerHandle, propHandle, todayMenuHandle);
} }
} }
} }

View File

@ -19,12 +19,12 @@
{ {
"type": "UnityEngine.ProBuilder.SemVer, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "type": "UnityEngine.ProBuilder.SemVer, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "about.identifier", "key": "about.identifier",
"value": "{\"m_Value\":{\"m_Major\":6,\"m_Minor\":0,\"m_Patch\":5,\"m_Build\":-1,\"m_Type\":\"\",\"m_Metadata\":\"\",\"m_Date\":\"\"}}" "value": "{\"m_Value\":{\"m_Major\":6,\"m_Minor\":0,\"m_Patch\":6,\"m_Build\":-1,\"m_Type\":\"\",\"m_Metadata\":\"\",\"m_Date\":\"\"}}"
}, },
{ {
"type": "UnityEngine.ProBuilder.SemVer, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "type": "UnityEngine.ProBuilder.SemVer, Unity.ProBuilder, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
"key": "preferences.version", "key": "preferences.version",
"value": "{\"m_Value\":{\"m_Major\":6,\"m_Minor\":0,\"m_Patch\":5,\"m_Build\":-1,\"m_Type\":\"\",\"m_Metadata\":\"\",\"m_Date\":\"\"}}" "value": "{\"m_Value\":{\"m_Major\":6,\"m_Minor\":0,\"m_Patch\":6,\"m_Build\":-1,\"m_Type\":\"\",\"m_Metadata\":\"\",\"m_Date\":\"\"}}"
}, },
{ {
"type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "type": "System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",