using System.Collections.Generic; using UnityEngine; public class MateMgr : Singleton { [SerializeField] MateSkillCutSceneView skillCutSceneView; [SerializeField] MateSkillCoolTimeView skillCoolTimeView; bool isInitialized; Dictionary mateInstanceGroup; SlotGroup settedMates; int currentMateSlotIndex; IVMate activeMate; public SlotGroup SettedMates => settedMates; public IVMate ActiveMate => activeMate; public void Init() { if (isInitialized) return; mateInstanceGroup = new Dictionary(); foreach (var prefab in MateDataGroup.Instance.MatePrefabs.Values) { IVMate mate = Instantiate(prefab); mate.gameObject.SetActive(false); mateInstanceGroup.Add(mate.Data.ID, mate); } settedMates = new SlotGroup(GameProperty.Instance.MateMaxCount); foreach (var row in MateDataGroup.Instance.GetMateDataMatrix(MateData.CompareByID)) { settedMates.GetEmptySlots(out var emptySlots); foreach (var mate in row) { if(emptySlots.Count == 0) break; if(mate.IsSetted) { SetMateAt(mate.ID, mate.SettedSlotIndex); emptySlots.RemoveAt(0); } } } isInitialized = true; } private void Update() { if(!isInitialized || BattleMgr.Instance.BattlePause) return; for(int i = 0; i < settedMates.SlotCount; ++i) { var currentSlot = settedMates.GetSlot(i); if(!currentSlot.IsEmpty) currentSlot.item.UpdateSkillCoolTime(); } if (activeMate is null) return; if (IsSafeToChangeCurrentMate() && activeMate.Skill.IsInCoolTime) { for (int i = currentMateSlotIndex + 1; true; ++i) { int nextIndex = i % settedMates.SlotCount; if (nextIndex == currentMateSlotIndex) break; var slot = settedMates.GetSlot(nextIndex); if (!slot.IsEmpty) { if(!slot.item.Skill.IsInCoolTime) ChangeActiveMate(slot.item, slot.slotIndex); break; } } } if (activeMate.CastSkill()) { skillCutSceneView.SetMate(activeMate); skillCutSceneView.Show(); } } private void ChangeActiveMate(IVMate target, int slotIndex) { if(activeMate == target) return; var player = BattleMgr.Instance.GetPlayer(); Transform spawnTrans = null; Vector2 lookDir = player.transform.position - target.transform.position; if (activeMate != null) { spawnTrans = activeMate.transform; lookDir = activeMate.LookDirection; activeMate.Dispose(); } currentMateSlotIndex = slotIndex; activeMate = target; activeMate.Spawn(player, lookDir, spawnTrans); } public bool IsSafeToChangeCurrentMate() => activeMate?.IsSafeChange ?? true; public void SetMateAt(uint id, int slotIndex) { IVMate targetMate; if (!IsValidSpawnSlotIndex(slotIndex)) throw new System.Exception("Invalid spawn position index"); else if (!mateInstanceGroup.TryGetValue(id, out targetMate)) throw new System.Exception("Invalid mate id"); else if (settedMates.TryGetSlot(targetMate, out SlotGroup.Slot _)) return; if (settedMates.TryGetItem(slotIndex, out IVMate existedMate)) { existedMate.Data.RemoveSlotIndex(); existedMate.Dispose(); settedMates.ClearSlot(slotIndex); if(activeMate == existedMate) activeMate = null; } settedMates[slotIndex] = targetMate; targetMate.Data.SetSlotIndex(slotIndex); if (activeMate is null) ChangeActiveMate(targetMate, slotIndex); skillCoolTimeView?.SetMateAt(settedMates.GetSlot(slotIndex)); } public void RemoveMateAt(int slotIndex) { if (!IsValidSpawnSlotIndex(slotIndex)) throw new System.Exception("Invalid spawn position index"); if (!settedMates.TryGetItem(slotIndex, out IVMate existedMate)) return; existedMate.Data.RemoveSlotIndex(); existedMate.Dispose(); settedMates.ClearSlot(slotIndex); if (activeMate == existedMate) { for(int i = currentMateSlotIndex + 1; true; ++i) { int nextIndex = i % settedMates.SlotCount; if (nextIndex == currentMateSlotIndex) { currentMateSlotIndex = -1; activeMate = null; break; } var slot = settedMates.GetSlot(nextIndex); if(!slot.IsEmpty) { ChangeActiveMate(slot.item, slot.slotIndex); break; } } } skillCoolTimeView?.RemoveMateAt(slotIndex); } public bool IsValidSpawnSlotIndex(int slotIndex) => slotIndex >= 0 && slotIndex < GameProperty.Instance.MateMaxCount; }