Unity2D
Unity) [유니티 2D] 데이터 테이블을 연동하여 다양한 몬스터 생성하기
HSH12345
2023. 5. 6. 03:12
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonsterGenerator : MonoBehaviour
{
public GameObject player;
public GameObject[] generatePoint;
public List<GameObject> portalPintArr; // 포탈 리스트
private List<GameObject> monsterPrefabList;
[System.NonSerialized]
public Queue<GameObject> monsterPool;
private int numberOfMonsters;
public float generateInterval = 5f;
private int maxCnt = 12;
private int difficultIdx;
private int startDifficultyIdx;
private int mostFarSpawnPoint;
private int secondFarSpawnPoint;
private bool isAwaked;
public bool isFinished;
Coroutine generateRoutine;
List<int> monsterIDList;
private bool test;
public void Init()
{
this.player = GameObject.FindGameObjectWithTag("Player");
this.monsterPrefabList = new List<GameObject>();
this.monsterPool = new Queue<GameObject>();
this.startDifficultyIdx = SetDifficultyID(14000); //인자 -> 룸id
this.monsterIDList = DataManager.Instance.GetMonsetIDList(this.SetGroupID(4, "meleeRangedExplosive")); //인자로 스테이지와 몬스터 타입
for (int i = 0; i < monsterIDList.Count; i++)
{
int monsterID = monsterIDList[i];
var prefabName = string.Format("Prefabs/Monsters/{0}", DataManager.Instance.GetMonsterData(monsterID).prefabPath);
this.monsterPrefabList.Add(Resources.Load<GameObject>(prefabName));
}
this.generateRoutine = StartCoroutine(this.GenerateMonstersRoutine());
// Init Update 돕니다.
this.isAwaked = true;
//ChestTest
if (this.test == false)
{
EventDispatcher.Instance.Dispatch<Transform, bool>(EventDispatcher.EventName.ChestItemGeneratorMakeChest,
this.transform);
this.test = true;
}
}
void Update()
{
if (this.isAwaked)
{
this.mostFarSpawnPoint = 0;
this.secondFarSpawnPoint = 0;
float maxDist = 0;
float secondMaxDist = 0;
for (int i = 0; i < this.generatePoint.Length; i++)
{
float distance = Vector2.Distance(this.player.transform.position, this.generatePoint[i].transform.position);
if (distance > maxDist)
{
secondMaxDist = maxDist;
this.secondFarSpawnPoint = this.mostFarSpawnPoint;
maxDist = distance;
this.mostFarSpawnPoint = i;
}
else if (distance > secondMaxDist)
{
secondMaxDist = distance;
this.secondFarSpawnPoint = i;
}
}
if (AllMonstersInactive())
{
if (this.generateRoutine != null) StopCoroutine(this.generateRoutine);
this.generateRoutine = StartCoroutine(this.GenerateMonstersRoutine());
if (this.maxCnt <= 0 && !this.isFinished)
{
this.RoomClearInitializing();
}
}
}
}
private void RoomClearInitializing()
{
this.portalPintArr.ForEach((x) => x.SetActive(true));
InfoManager.instance.ChangeDungeonStepInfo();
this.isFinished = true;
EventDispatcher.Instance.Dispatch<Transform>(EventDispatcher.EventName.UIPortalArrowControllerInitializingArrows,
this.transform);
EventDispatcher.Instance.Dispatch<Transform, bool>(EventDispatcher.EventName.ChestItemGeneratorMakeChest,
this.transform);
}
private bool AllMonstersInactive()
{
GameObject[] monsters = GameObject.FindGameObjectsWithTag("Monster");
foreach (GameObject monster in monsters)
{
if (monster.activeSelf)
{
return false;
}
}
return true;
}
IEnumerator GenerateMonstersRoutine()
{
while (this.maxCnt >= 0)
{
var difficulty = DataManager.Instance.GetDifficultyData(this.difficultIdx + this.startDifficultyIdx);
this.numberOfMonsters = difficulty.monsterAmount;
this.maxCnt--;
for (int i = 0; i < this.numberOfMonsters; i++)
{
int monsterIdx = i % this.monsterIDList.Count;
GameObject monsterGo;
if (this.monsterPool.Count > 0)
{
monsterGo = this.monsterPool.Dequeue();
if (monsterGo.activeSelf) monsterGo = Instantiate(this.monsterPrefabList[monsterIdx]);
monsterGo.SetActive(true);
}
else
{
monsterGo = Instantiate(this.monsterPrefabList[monsterIdx]);
}
monsterGo.GetComponent<Monster>().Init(this, difficulty.monsterHP, difficulty.monsterDefense);
int spawnPoint = Random.Range(0, 2) == 0 ? this.mostFarSpawnPoint : this.secondFarSpawnPoint;
monsterGo.transform.position = this.generatePoint[spawnPoint].transform.position;
}
this.difficultIdx++;
yield return new WaitForSeconds(this.generateInterval);
}
}
private int SetDifficultyID(int roomId)
{
int id = 13000;
if (roomId >= 14000 && roomId <= 14035)
{
id += (roomId - 14000) * 12;
}
return id;
}
private int SetGroupID(int stageNum, string monsterType)
{
int id = 15000 + (stageNum - 1) * 6;
switch (monsterType)
{
case "melee":
break;
case "ranged":
id += 1;
break;
case "meleeRanged":
id += 2;
break;
case "meleeExplosive":
id += 3;
break;
case "rangedExplosive":
id += 4;
break;
case "meleeRangedExplosive":
id += 5;
break;
}
return id;
}
}
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public partial class DataManager
{
public static readonly DataManager Instance = new DataManager();
private DataManager() { }
public Dictionary<int,TestData> dicTestDatas;
public void LoadAllDatas()
{
this.LoadMonsterData();
this.LoadMonsterGroupData();
this.LoadDifficultyData();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using System.Linq;
public partial class DataManager
{
public Dictionary<int, MonsterData> dicMonsterData;
public Dictionary<int, MonsterGroupData> dicMonsterGroupData;
public Dictionary<int, DifficultyData> dicDifficultyData;
public void LoadMonsterData()
{
var asset = Resources.Load<TextAsset>("Data/monster_data");
if (asset != null)
{
var json = asset.text;
MonsterData[] arr = JsonConvert.DeserializeObject<MonsterData[]>(json);
this.dicMonsterData = arr.ToDictionary(x => x.id);
Debug.Log("MonsterDataLoadComplete");
}
else Debug.LogError("Data/monster_data not found.");
}
public List<MonsterData> GetMonsterDatas()
{
return this.dicMonsterData.Values.ToList();
}
public MonsterData GetMonsterData(int id)
{
return this.dicMonsterData[id];
}
public void LoadMonsterGroupData()
{
var asset = Resources.Load<TextAsset>("Data/monster_group_data");
if (asset != null)
{
var json = asset.text;
MonsterGroupData[] arr = JsonConvert.DeserializeObject<MonsterGroupData[]>(json);
this.dicMonsterGroupData = arr.ToDictionary(x => x.id);
Debug.Log("MonsterGroupDataLoadComplete");
}
else Debug.LogError("Data/monster_group_data not found.");
}
public List<int> GetMonsetIDList(int id)
{
List<int> listMonsterID = new List<int>();
var data = dicMonsterGroupData[id];
if (data.monsterId1 >= 15000) listMonsterID.Add(data.monsterId1);
if (data.monsterId2 >= 15000) listMonsterID.Add(data.monsterId2);
if (data.monsterId3 >= 15000) listMonsterID.Add(data.monsterId3);
if (data.monsterId4 >= 15000) listMonsterID.Add(data.monsterId4);
if (data.monsterId5 >= 15000) listMonsterID.Add(data.monsterId5);
if (data.monsterId6 >= 15000) listMonsterID.Add(data.monsterId6);
if (data.monsterId7 >= 15000) listMonsterID.Add(data.monsterId7);
return listMonsterID;
}
public void LoadDifficultyData()
{
var asset = Resources.Load<TextAsset>("Data/difficulty_data");
if (asset != null)
{
var json = asset.text;
DifficultyData[] arr = JsonConvert.DeserializeObject<DifficultyData[]>(json);
this.dicDifficultyData = arr.ToDictionary(x => x.id);
Debug.Log("DifficultyDataLoadComplete");
}
else Debug.LogError("Data/difficulty_data not found.");
}
public DifficultyData GetDifficultyData(int id)
{
return this.dicDifficultyData[id];
}
}
json 파일 형식의 데이터테이블을 작성하고 해당 테이블을 참조하여 생성할 몬스터의 종류와 몬스터 능력치를 설정합니다.