2026-01-14 00:22:53 +00:00
|
|
|
using CodeStage.AntiCheat.ObscuredTypes;
|
2026-01-12 12:33:09 +00:00
|
|
|
using System.Collections;
|
2026-01-13 20:40:28 +00:00
|
|
|
using System.Collections.Generic;
|
2026-01-12 12:33:09 +00:00
|
|
|
using TMPro;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.UI;
|
|
|
|
|
|
2026-01-13 00:46:52 +00:00
|
|
|
public class IngameMgr : MonoBehaviourSingletonTemplate<IngameMgr>
|
2026-01-12 12:33:09 +00:00
|
|
|
{
|
2026-01-14 07:29:45 +00:00
|
|
|
public AimArrowController m_AimArrowController;
|
|
|
|
|
|
2026-01-12 22:13:54 +00:00
|
|
|
[Header("UI")]
|
2026-01-12 12:33:09 +00:00
|
|
|
public TextMeshProUGUI[] texts_money; // 0 코인, 1 아이템, 2 웨이브
|
|
|
|
|
public Text t_timer, t_hp, t_exp;
|
|
|
|
|
public Slider slider_wave, slider_exp;
|
|
|
|
|
|
2026-01-12 22:13:54 +00:00
|
|
|
[Header("Monster")]
|
|
|
|
|
public Transform[] tfs_mobparent;
|
2026-01-13 21:40:48 +00:00
|
|
|
public Transform tf_hudparent;
|
2026-01-12 22:13:54 +00:00
|
|
|
|
2026-01-12 22:47:31 +00:00
|
|
|
[Header("Fence")]
|
|
|
|
|
public Transform tf_fence;
|
|
|
|
|
|
2026-01-16 01:25:32 +00:00
|
|
|
[Header("서포터")]
|
|
|
|
|
public GameObject go_Supporter;
|
|
|
|
|
public Image[] images_skillcool;
|
|
|
|
|
public TextMeshProUGUI[] texts_skillcool;
|
|
|
|
|
float f_SupporterCoolTime = 0f, f_SkillCoolTime = 0f;
|
|
|
|
|
|
2026-01-14 04:07:18 +00:00
|
|
|
int m_Wave, m_HP, m_Coin, m_Item, m_Exp;
|
2026-01-12 12:33:09 +00:00
|
|
|
StageConfigTableData CurStageData;
|
2026-01-13 00:46:52 +00:00
|
|
|
UnitTableData CurUnitData;
|
2026-01-13 20:40:28 +00:00
|
|
|
Dictionary<string, List<MobActor>> mob_pools = new Dictionary<string, List<MobActor>>();
|
2026-01-14 00:07:08 +00:00
|
|
|
float f_Time;
|
2026-01-14 04:07:18 +00:00
|
|
|
ObscuredInt m_Lv, m_MobMakeCount, m_MobDieCount;
|
2026-01-14 05:20:39 +00:00
|
|
|
Dictionary<eSkillType, ObscuredInt> dic_Skill = new Dictionary<eSkillType, ObscuredInt>();
|
2026-01-12 12:33:09 +00:00
|
|
|
|
|
|
|
|
private void OnEnable()
|
|
|
|
|
{
|
2026-01-13 21:40:48 +00:00
|
|
|
foreach (var kv in mob_pools) foreach (var mob in kv.Value) mob.Off();
|
2026-01-14 00:22:53 +00:00
|
|
|
ProjectileMgr.Ins.AllOff();
|
2026-01-15 05:28:45 +00:00
|
|
|
EffectMgr.Ins.AllOff();
|
2026-01-13 20:40:28 +00:00
|
|
|
|
2026-01-12 12:33:09 +00:00
|
|
|
CurStageData = table_stageconfig.Ins.Get_Data(10001);
|
2026-01-13 00:46:52 +00:00
|
|
|
CurUnitData = table_unit.Ins.Get_Data(1001);
|
2026-01-12 12:33:09 +00:00
|
|
|
|
2026-01-13 00:46:52 +00:00
|
|
|
m_HP = CurUnitData.n_DefaultHp;
|
2026-01-12 12:33:09 +00:00
|
|
|
m_Lv = m_Wave = 1;
|
2026-01-14 04:07:18 +00:00
|
|
|
m_Lv.RandomizeCryptoKey();
|
2026-01-12 12:33:09 +00:00
|
|
|
m_Exp = m_Coin = m_Item = 0;
|
2026-01-14 23:00:10 +00:00
|
|
|
f_Time = 300f;
|
2026-01-14 00:22:53 +00:00
|
|
|
m_MobDieCount = 0; m_MobDieCount.RandomizeCryptoKey();
|
2026-01-14 05:20:39 +00:00
|
|
|
dic_Skill.Clear();
|
2026-01-14 00:22:53 +00:00
|
|
|
|
|
|
|
|
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();
|
2026-01-12 12:33:09 +00:00
|
|
|
|
2026-01-16 01:25:32 +00:00
|
|
|
go_Supporter.SetActive(false);
|
|
|
|
|
f_SupporterCoolTime = f_SkillCoolTime = 0f;
|
|
|
|
|
Set_SkillUI();
|
2026-01-12 12:33:09 +00:00
|
|
|
Set_Texts();
|
2026-01-14 04:07:18 +00:00
|
|
|
Set_Exp(0);
|
2026-01-12 12:33:09 +00:00
|
|
|
|
|
|
|
|
StartCoroutine(Co_MakeMob());
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-14 00:07:08 +00:00
|
|
|
private void Update()
|
|
|
|
|
{
|
|
|
|
|
Set_Timer();
|
2026-01-16 01:25:32 +00:00
|
|
|
Set_SkillUI();
|
2026-01-14 00:07:08 +00:00
|
|
|
}
|
|
|
|
|
|
2026-01-13 20:40:28 +00:00
|
|
|
public void ReturnMob(MobActor mob)
|
|
|
|
|
{
|
|
|
|
|
mob.gameObject.SetActive(false);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-16 01:25:32 +00:00
|
|
|
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 = "";
|
|
|
|
|
}
|
2026-01-12 12:33:09 +00:00
|
|
|
void Set_Texts()
|
|
|
|
|
{
|
|
|
|
|
texts_money[0].text = m_Coin.ToString();
|
|
|
|
|
texts_money[1].text = m_Item.ToString();
|
2026-01-13 06:20:15 +00:00
|
|
|
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;
|
2026-01-12 12:33:09 +00:00
|
|
|
|
|
|
|
|
t_hp.text = m_HP.ToString();
|
2026-01-14 04:07:18 +00:00
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
}
|
2026-01-12 12:33:09 +00:00
|
|
|
}
|
2026-01-14 00:07:08 +00:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-12 12:33:09 +00:00
|
|
|
|
|
|
|
|
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 원거리 몹 생성 후 카운팅
|
2026-01-12 22:13:54 +00:00
|
|
|
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)];
|
|
|
|
|
}
|
2026-01-12 12:33:09 +00:00
|
|
|
|
2026-01-13 23:57:21 +00:00
|
|
|
MakeMob(false, table_monster.Ins.Get_Data(mobid));
|
2026-01-12 12:33:09 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-13 22:25:49 +00:00
|
|
|
if (CurStageData.dic_boss.ContainsKey(m_Wave))
|
2026-01-13 23:57:21 +00:00
|
|
|
MakeMob(true, table_monster.Ins.Get_Data(CurStageData.dic_boss[m_Wave]));
|
2026-01-13 22:25:49 +00:00
|
|
|
|
2026-01-12 12:33:09 +00:00
|
|
|
yield return new WaitForSeconds(wavedata.f_NextWaveDelay);
|
|
|
|
|
++m_Wave;
|
|
|
|
|
Set_Texts();
|
|
|
|
|
StartCoroutine(Co_MakeMob());
|
|
|
|
|
}
|
2026-01-13 23:57:21 +00:00
|
|
|
void MakeMob(bool isboss, MonsterTableData data)
|
2026-01-13 20:40:28 +00:00
|
|
|
{
|
|
|
|
|
string key = data.s_MonsterPrefabPath;
|
|
|
|
|
|
|
|
|
|
if (!mob_pools.ContainsKey(key))
|
|
|
|
|
mob_pools.Add(key, new List<MobActor>());
|
|
|
|
|
|
|
|
|
|
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<MobActor>(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;
|
2026-01-13 23:57:21 +00:00
|
|
|
mob.Set(isboss,data, tf_fence.position.y);
|
2026-01-13 20:40:28 +00:00
|
|
|
}
|
2026-01-14 22:48:21 +00:00
|
|
|
public MobActor FindNearestMob(Vector3 pos, MobActor ignore)
|
|
|
|
|
{
|
|
|
|
|
MobActor nearest = null;
|
|
|
|
|
float minDistSq = float.MaxValue;
|
|
|
|
|
|
|
|
|
|
foreach (var kv in mob_pools)
|
|
|
|
|
{
|
|
|
|
|
List<MobActor> 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;
|
|
|
|
|
}
|
2026-01-13 20:40:28 +00:00
|
|
|
|
2026-01-13 07:33:06 +00:00
|
|
|
public void Get_Dmg(int dmg)
|
|
|
|
|
{
|
|
|
|
|
m_HP -= dmg;
|
|
|
|
|
Set_Texts();
|
2026-01-13 20:40:28 +00:00
|
|
|
|
|
|
|
|
if (m_HP < 0) GameUI.Ins.Set_UI(7);
|
2026-01-13 07:33:06 +00:00
|
|
|
}
|
2026-01-14 04:07:18 +00:00
|
|
|
public void Add_MobKill(int exp)
|
2026-01-14 00:22:53 +00:00
|
|
|
{
|
|
|
|
|
++m_MobDieCount; m_MobDieCount.RandomizeCryptoKey();
|
|
|
|
|
if (m_MobDieCount >= m_MobMakeCount)
|
|
|
|
|
GameUI.Ins.Set_UI(8);
|
2026-01-14 04:07:18 +00:00
|
|
|
else
|
|
|
|
|
Set_Exp(exp);
|
2026-01-14 00:22:53 +00:00
|
|
|
}
|
2026-01-14 05:20:39 +00:00
|
|
|
public void Add_Skill(eSkillType skillType)
|
|
|
|
|
{
|
|
|
|
|
if (!dic_Skill.ContainsKey(skillType))
|
|
|
|
|
dic_Skill.Add(skillType, 0);
|
|
|
|
|
|
|
|
|
|
++dic_Skill[skillType];
|
|
|
|
|
dic_Skill[skillType].RandomizeCryptoKey();
|
2026-01-14 07:14:50 +00:00
|
|
|
|
|
|
|
|
if (skillType == eSkillType.HpUp)
|
|
|
|
|
{ // 생명력 증가
|
|
|
|
|
var tdata = table_skill.Ins.Get_Data(skillType);
|
|
|
|
|
m_HP += (int)tdata.f_Value;
|
|
|
|
|
Set_Texts();
|
|
|
|
|
}
|
2026-01-14 07:29:45 +00:00
|
|
|
else if (skillType == eSkillType.AttackSpeedUp)
|
|
|
|
|
m_AimArrowController.Set_AttackLifeTime();
|
2026-01-14 05:20:39 +00:00
|
|
|
}
|
2026-01-13 07:33:06 +00:00
|
|
|
|
2026-01-13 00:46:52 +00:00
|
|
|
public StageConfigTableData Get_CurStageTData() { return CurStageData; }
|
|
|
|
|
public UnitTableData Get_CurUnitTData() { return CurUnitData; }
|
2026-01-14 07:14:50 +00:00
|
|
|
|
|
|
|
|
#region 스킬
|
2026-01-15 06:34:35 +00:00
|
|
|
public float Get_SkillLv(eSkillType skillType) { return dic_Skill.ContainsKey(skillType) ? dic_Skill[skillType] : 0; }
|
2026-01-14 07:14:50 +00:00
|
|
|
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
|
2026-01-16 01:25:32 +00:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-01-12 12:33:09 +00:00
|
|
|
}
|