using CodeStage.AntiCheat.ObscuredTypes; using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; public class IngameMgr : MonoBehaviourSingletonTemplate { public AimArrowController m_AimArrowController; [Header("UI")] public TextMeshProUGUI[] texts_money; // 0 코인, 1 아이템, 2 웨이브 public Text t_timer, t_hp, t_exp; public Slider slider_wave, slider_exp; [Header("Monster")] public Transform[] tfs_mobparent; public Transform tf_hudparent; [Header("Fence")] public Transform tf_fence; [Header("서포터")] public GameObject go_Supporter; public Image[] images_skillcool; public TextMeshProUGUI[] texts_skillcool; float f_SupporterCoolTime = 0f, f_SkillCoolTime = 0f; int m_Wave, m_HP, m_Coin, m_Item, m_Exp; StageConfigTableData CurStageData; UnitTableData CurUnitData; Dictionary> mob_pools = new Dictionary>(); float f_Time; ObscuredInt m_Lv, m_MobMakeCount, m_MobDieCount; Dictionary dic_Skill = new Dictionary(); private void OnEnable() { foreach (var kv in mob_pools) foreach (var mob in kv.Value) mob.Off(); ProjectileMgr.Ins.AllOff(); EffectMgr.Ins.AllOff(); CurStageData = table_stageconfig.Ins.Get_Data(10001); CurUnitData = table_unit.Ins.Get_Data(1001); m_HP = CurUnitData.n_DefaultHp; m_Lv = m_Wave = 1; m_Lv.RandomizeCryptoKey(); m_Exp = m_Coin = m_Item = 0; f_Time = 300f; m_MobDieCount = 0; m_MobDieCount.RandomizeCryptoKey(); dic_Skill.Clear(); var patternlst = table_wavepattern.Ins.Get_DataList(CurStageData.n_WavePatternGroupID); for (int i = 0; i < patternlst.Count; i++) m_MobMakeCount += patternlst[i].n_AppearMeleeMonster + patternlst[i].n_AppearRangeMonster; m_MobMakeCount += CurStageData.dic_boss.Count; m_MobMakeCount.RandomizeCryptoKey(); go_Supporter.SetActive(false); f_SupporterCoolTime = f_SkillCoolTime = 0f; Set_SkillUI(); Set_Texts(); Set_Exp(0); StartCoroutine(Co_MakeMob()); } private void Update() { Set_Timer(); Set_SkillUI(); } public void ReturnMob(MobActor mob) { mob.gameObject.SetActive(false); } void Set_SkillUI() { texts_skillcool[0].text = DSUtil.Get_TimeText_MS(f_SkillCoolTime); texts_skillcool[1].text = DSUtil.Get_TimeText_MS(f_SupporterCoolTime); images_skillcool[0].enabled = f_SkillCoolTime > 0; images_skillcool[1].enabled = f_SupporterCoolTime > 0; if (images_skillcool[0].enabled) { f_SkillCoolTime -= Time.deltaTime; images_skillcool[0].fillAmount = f_SkillCoolTime / 10f; } else texts_skillcool[0].text = ""; if (images_skillcool[1].enabled) { f_SupporterCoolTime -= Time.deltaTime; images_skillcool[1].fillAmount = f_SupporterCoolTime / 600f; } else texts_skillcool[1].text = ""; } void Set_Texts() { texts_money[0].text = m_Coin.ToString(); texts_money[1].text = m_Item.ToString(); texts_money[2].text = $"Wave {(m_Wave > CurStageData.n_MaxWave ? CurStageData.n_MaxWave : m_Wave)}/{CurStageData.n_MaxWave}"; slider_wave.value = (m_Wave - 1) / (float)CurStageData.n_MaxWave; t_hp.text = m_HP.ToString(); } void Set_Exp(int exp) { m_Exp += exp; var currentLvData = table_BattleLevelUp.Ins.Get_Data(m_Exp); if (m_Lv < currentLvData.n_Lv || (m_Lv == currentLvData.n_Lv && currentLvData.n_TotalExp <= m_Exp)) { ++m_Lv; GameUI.Ins.Set_OverUI(6, true); Time.timeScale = 0f; } var nextLvData = table_BattleLevelUp.Ins.Get_Data_orNull(currentLvData.n_Lv + 1); if (nextLvData != null) { if (m_Lv == 1) slider_exp.value = (float)m_Exp / currentLvData.n_TotalExp; else slider_exp.value = (float)(m_Exp - currentLvData.n_TotalExp) / (nextLvData.n_TotalExp - currentLvData.n_TotalExp); } else { slider_exp.value = 1f; } } void Set_Timer() { if (f_Time > 0) { f_Time -= Time.deltaTime; t_timer.text = DSUtil.Get_TimeText_MS(f_Time); if(f_Time <= 0f) { GameUI.Ins.Set_UI(7); } } } IEnumerator Co_MakeMob() { var wavedata = table_wavepattern.Ins.Get_Data(CurStageData.n_WavePatternGroupID, m_Wave); if (wavedata == null) { // 클리어 yield break; } // 일반 몬스터 생성 int meleemobcount = 0, rangemobcount = 0; var totalmobcount = wavedata.n_AppearMeleeMonster + wavedata.n_AppearRangeMonster; for (int i = 0; i < totalmobcount; i++) { yield return new WaitForSeconds(wavedata.f_AppearDelay); for (int j = 0; j < wavedata.n_OverlapUnitCount; j++) { // 근거리 or 원거리 몹 생성 후 카운팅 if (totalmobcount < meleemobcount + rangemobcount) break; bool canMelee = meleemobcount < wavedata.n_AppearMeleeMonster; bool canRange = rangemobcount < wavedata.n_AppearRangeMonster; if (!canMelee && !canRange) continue; bool meleemob; if (canMelee && canRange) meleemob = Random.Range(0, 2) == 0; else meleemob = canMelee; int mobid = 0; if (meleemob && meleemobcount < wavedata.n_AppearMeleeMonster) { ++meleemobcount; mobid = CurStageData.list_monster_melee[Random.Range(0, CurStageData.list_monster_melee.Count)]; } else if(!meleemob && rangemobcount < wavedata.n_AppearRangeMonster) { ++rangemobcount; mobid = CurStageData.list_monster_range[Random.Range(0, CurStageData.list_monster_range.Count)]; } MakeMob(false, table_monster.Ins.Get_Data(mobid)); } } if (CurStageData.dic_boss.ContainsKey(m_Wave)) MakeMob(true, table_monster.Ins.Get_Data(CurStageData.dic_boss[m_Wave])); yield return new WaitForSeconds(wavedata.f_NextWaveDelay); ++m_Wave; Set_Texts(); StartCoroutine(Co_MakeMob()); } void MakeMob(bool isboss, MonsterTableData data) { string key = data.s_MonsterPrefabPath; if (!mob_pools.ContainsKey(key)) mob_pools.Add(key, new List()); MobActor mob = null; for (int i = 0; i < mob_pools[key].Count; i++) { if (!mob_pools[key][i].gameObject.activeInHierarchy) { mob = mob_pools[key][i]; break; } } if (mob == null) { mob = DSUtil.Get_Clone(key); mob_pools[key].Add(mob); mob.SetOwner(this, key); } mob.transform.SetParent(tfs_mobparent[Random.Range(0, tfs_mobparent.Length)], false); mob.transform.localPosition = Vector3.zero; mob.transform.localScale = Vector3.one * data.f_Scale; mob.Set(isboss,data, tf_fence.position.y); } public MobActor FindNearestMob(Vector3 pos, MobActor ignore) { MobActor nearest = null; float minDistSq = float.MaxValue; foreach (var kv in mob_pools) { List list = kv.Value; for (int i = 0; i < list.Count; i++) { MobActor mob = list[i]; if (!mob.gameObject.activeInHierarchy) continue; if (mob == ignore) continue; float distSq = (mob.transform.position - pos).sqrMagnitude; if (distSq < minDistSq) { minDistSq = distSq; nearest = mob; } } } return nearest; } public void Get_Dmg(int dmg) { m_HP -= dmg; Set_Texts(); if (m_HP < 0) GameUI.Ins.Set_UI(7); } public void Add_MobKill(int exp) { ++m_MobDieCount; m_MobDieCount.RandomizeCryptoKey(); if (m_MobDieCount >= m_MobMakeCount) GameUI.Ins.Set_UI(8); else Set_Exp(exp); } public void Add_Skill(eSkillType skillType) { if (!dic_Skill.ContainsKey(skillType)) dic_Skill.Add(skillType, 0); ++dic_Skill[skillType]; dic_Skill[skillType].RandomizeCryptoKey(); if (skillType == eSkillType.HpUp) { // 생명력 증가 var tdata = table_skill.Ins.Get_Data(skillType); m_HP += (int)tdata.f_Value; Set_Texts(); } else if (skillType == eSkillType.AttackSpeedUp) m_AimArrowController.Set_AttackLifeTime(); } public StageConfigTableData Get_CurStageTData() { return CurStageData; } public UnitTableData Get_CurUnitTData() { return CurUnitData; } #region 스킬 public float Get_SkillLv(eSkillType skillType) { return dic_Skill.ContainsKey(skillType) ? dic_Skill[skillType] : 0; } public float Get_SkillValue(eSkillType skillType) { if (dic_Skill.ContainsKey(skillType)) { var tdata = table_skill.Ins.Get_Data(skillType); return tdata.f_Value * dic_Skill[skillType]; } return 0; } #endregion public void OnClick_SkillButton(int index) { if (index == 0) { if (f_SkillCoolTime > 0f) return; f_SkillCoolTime = 10f; } else { if (f_SupporterCoolTime > 0f) return; f_SupporterCoolTime = 600f; } } }