Project_WL/Assets/Script/Mgr/MobControlMgr.cs

172 lines
7.9 KiB
C#

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class MobControlMgr : MyCoroutine
{
public int SpawnerID;
public float MobGenRange = 10f;
public TextMeshPro text_lv;
MonsterAppearData m_MonsterAppearData;
Dictionary<int, List<Actor>> dic_actors = new Dictionary<int, List<Actor>>();
int orderIndex, killmobcount;
IEnumerator Start()
{
MobControlMgrList.Ins.Add(transform.position);
text_lv.text = "Lv.???";
m_MonsterAppearData = table_monsterappear.Ins.Get_Data_orNull(SpawnerID);
if (!DSUtil.CheckNull(m_MonsterAppearData))
{
text_lv.text = DSUtil.Format("Lv.{0}", m_MonsterAppearData.n_AppearMonsterLv);
var list_make_mobs = Get_Mobs();
for (int i = 0; i < list_make_mobs.Count; i++)
{
var rdnpos = DSUtil.Get_RandomPos_onNavMesh(transform.position, 0f, MobGenRange);
var mobData = list_make_mobs[i];
yield return StartCoroutine(Make_Mob(mobData, i, rdnpos));
}
// 생성한 몬스터를 m_MonsterAppearData.n_MaxMonsterCount 만큼 활성화
for (int i = 0; i < m_MonsterAppearData.n_MaxMonsterCount; i++)
dic_actors[0][i].On_Regen();
}
}
List<MonsterTableData> Get_Mobs()
{
var list_make_mobs = new List<MonsterTableData>();
switch (m_MonsterAppearData.e_SpawnerType)
{ // 생성할 몹 정보
case eSpawnerType.Random: // s_AppearMonsterID에 지정된 몬스터가 n_MaxMonsterCount 수량만큼 Spawner 범위 내 랜덤으로 생성되는 방식
for (int i = 0; i < m_MonsterAppearData.n_MaxMonsterCount * 2; i++)
list_make_mobs.Add(m_MonsterAppearData.Get_MobData_orNull());
dic_actors.Add(0, new List<Actor>());
break;
case eSpawnerType.Order: // s_AppearMonsterID에 지정 된 몬스터가 n_MaxMonsterCount 수량만큼 Spawner 범위 내 순서대로 생성되는 방식 (예: 1001|1002|1003 → 1001|1002|1003 → 순서를 반복해 생성)
int index = 0;
for (int i = 0; i < m_MonsterAppearData.n_MaxMonsterCount * 2; i++)
{
list_make_mobs.Add(m_MonsterAppearData.Get_MobData_orNull(index));
++index;
if (index >= m_MonsterAppearData.Get_MobTypeCount()) index = 0;
}
dic_actors.Add(0, new List<Actor>());
orderIndex = m_MonsterAppearData.n_MaxMonsterCount - 1;
break;
case eSpawnerType.Phase:
// s_AppearMonsterID에 지정 된 몬스터가 n_MaxMonsterCount 수량만큼 Spawner 범위 한 종류씩 순차적으로 생성되는 방식
// (예: 1001|1002|1003일 경우 1001번 몬스터가 사망하면 1002번 몬스터가 n_MaxMonsterCount 만큼 f_SpawnerDelay 후 생성)
case eSpawnerType.PhaseAllKill:
// s_AppearMonsterID에 지정 된 몬스터가 n_MaxMonsterCount 수량만큼 Spawner 범위 한 종류씩 순차적으로 생성되고, 모든 몬스터가 제거되면 다음 페이즈가 발생되는 방식 (※주로 컨텐츠에서 활용될 예정)
// (예: 1001|1002|1003일 경우 1001번 몬스터를 전부 제거해야 1002번 몬스터가 n_MaxMonsterCount 만큼 f_SpawnerDelay 후 일괄 생성)
for (int i = 0; i < m_MonsterAppearData.Get_MobTypeCount(); i++)
{
dic_actors.Add(i, new List<Actor>());
for (int j = 0; j < m_MonsterAppearData.n_MaxMonsterCount; j++)
list_make_mobs.Add(m_MonsterAppearData.Get_MobData_orNull(i));
}
break;
}
return list_make_mobs;
}
IEnumerator Make_Mob(MonsterTableData mobData, int i, Vector3 rdnpos)
{
bool makeComplete = false;
AddrResourceMgr.Ins.LoadObject<GameObject>(mobData.s_MonsterPrefab, handle =>
{
var mob = DSUtil.Get_Clone<MobActor>(handle.Result, transform);
AddrResourceMgr.Ins.Set_AddressableReleaseSelf(mob.gameObject);
ActorInfo.Ins.Add_Actor(mob, eRole.Mob, SpawnerID, mobData.s_MonsterPrefab);
switch (m_MonsterAppearData.e_SpawnerType)
{
case eSpawnerType.Random:
case eSpawnerType.Order:
dic_actors[0].Add(mob);
break;
case eSpawnerType.Phase:
case eSpawnerType.PhaseAllKill:
var list_ids = m_MonsterAppearData.Get_MobIds();
int findindex = list_ids.FindIndex(f => f == mobData.n_MonsterID);
if (findindex >= 0 && findindex < dic_actors.Count) // 인덱스가 유효한지 체크
dic_actors[findindex].Add(mob);
else
Debug.LogError($"Invalid findindex: {findindex}, MonsterID: {mobData.n_MonsterID}");
break;
}
mob.Set(true, null, null, m_MonsterAppearData.n_SpawnerID, false);
mob.Set(mobData, rdnpos, actDie, i);
mob.Off();
mob.MagicID = 0;
makeComplete = true;
});
while (!makeComplete) yield return null;
}
private void actDie(int mobid)
{
if (m_MonsterAppearData != null)
{
++killmobcount;
switch (m_MonsterAppearData.e_SpawnerType)
{ // 사망 후 리젠
case eSpawnerType.Random:
Set_Coroutine(() =>
{
var deadmobs = dic_actors[0].FindAll(f => !f.isActiveAndEnabled);
deadmobs[Random.Range(0, deadmobs.Count)].On_Regen();
}, m_MonsterAppearData.f_SpawnerDelay);
break;
case eSpawnerType.Order:
Set_Coroutine(() =>
{
if (dic_actors[0].Count > 0)
{
orderIndex = orderIndex % dic_actors[0].Count;
while (true)
{
var mob = dic_actors[0][orderIndex++];
if (!mob.isActiveAndEnabled)
{
mob.On_Regen();
break;
}
orderIndex = orderIndex % dic_actors[0].Count;
}
}
}, m_MonsterAppearData.f_SpawnerDelay);
break;
case eSpawnerType.Phase:
Set_Coroutine(() =>
{
var ids = m_MonsterAppearData.Get_MobIds();
var index = ids.FindIndex(f => f == mobid);
var nextindex = index + 1;
if (nextindex >= dic_actors.Count) nextindex = 0;
dic_actors[nextindex].Find(f => !f.isActiveAndEnabled).On_Regen();
}, m_MonsterAppearData.f_SpawnerDelay);
break;
case eSpawnerType.PhaseAllKill:
if (killmobcount == m_MonsterAppearData.n_MaxMonsterCount)
{
Set_Coroutine(() =>
{
killmobcount = 0;
++orderIndex; if (orderIndex >= dic_actors.Count) orderIndex = 0;
for (int i = 0; i < dic_actors[orderIndex].Count; i++)
dic_actors[orderIndex][i].On_Regen();
}, m_MonsterAppearData.f_SpawnerDelay);
}
break;
}
}
}
}