using FirstVillain.Entities; using FirstVillain.EventBus; using System.Collections; using System.Collections.Generic; using UnityEngine; public class SpawnController : MonoBehaviour { [SerializeField] private Transform _playerSpawnPos; [SerializeField] private List _propGenerateArea; [SerializeField] private List _carGenPosList; [SerializeField] private List _planeGenPosList; [SerializeField] private List _itemSpawnPosList; private int _maxPropCount = 50; private int _curPropCount = 0; private Dictionary _itemDict = new(); private Dictionary _carDict = new(); private Dictionary _planeDict = new(); private void Start() { EventBus.Instance.Subscribe(OnPropRemoved); } private void OnDestroy() { EventBus.Instance.Unsubscribe(OnPropRemoved); } #region Player //ÃÖÃÊ Ç÷¹À̾î ÇÁ¸®ÆÕ ·Îµå ¹× »ý¼º //TODO : ¾À ¿ÜºÎ¿¡¼­ ¼±ÅÃµÈ Ç÷¹À̾î Á¤º¸¸¦ ³Ñ°ÜÁÖ°í ÇØ´ç µ¥ÀÌÅ͸¦ ¹Þ¾Æ »ý¼ºÇÑ´Ù. public PlayerController SpawnPlayer(PlayerInfo info) { var player = AddressableManager.Instance.Spawn(info.PrefapName, null); var controller = player.GetComponent(); controller.SetData(info); controller.Block(); RespawnPlayer(controller, true); return controller; } public void RespawnPlayer(PlayerController player, bool isStart = false) { player.transform.position = _playerSpawnPos.position; player.transform.rotation = _playerSpawnPos.rotation; StartCoroutine(RespawnDelay(player, isStart)); } private IEnumerator RespawnDelay(PlayerController controller, bool isStart) { int timer = Constants.PLAYER_SPAWN_TIME; var sec = new WaitForSeconds(1f); while (timer >= 0) { EventBus.Instance.Publish(new EventSpawnTimer(timer)); timer--; yield return sec; } controller.Respawn(); if (isStart) { EventBus.Instance.Publish(new EventStartGame()); } } #endregion Player #region Props public void SpawnProps() { StartCoroutine(SpawnBasicPropsCoroutine()); StartCoroutine(SpawnCarPropsCoroutine()); StartCoroutine(SpawnPlanePropsCoroutine()); } private IEnumerator SpawnBasicPropsCoroutine() { //TODO : ÀϽà Á¤Áö »óÅ°¡ ÀÖÀ¸¸é º¯°æÇÊ¿ä var sec = new WaitForSeconds(1f); while(StageManager.Instance.IsSpawnable) { yield return sec; if (_curPropCount < _maxPropCount) { SelectProp("Basic"); } } } private IEnumerator SpawnCarPropsCoroutine() { var sec = new WaitForSeconds(10f); while (StageManager.Instance.IsSpawnable) { yield return sec; if (_curPropCount < _maxPropCount) { int count = _carGenPosList.Count; List posList = new(); for (int i = 0; i < count; i++) { //ºóÀÚ¸® ã¾Æ¼­ ·£´ý if (!_carDict.ContainsValue(i)) { posList.Add(i); } } if (posList.Count > 0) { int rnd = Random.Range(0, posList.Count); var car = SelectProp("Car", _carGenPosList[posList[rnd]]); if (car != null) { _carDict.Add(car, posList[rnd]); } } } } } private IEnumerator SpawnPlanePropsCoroutine() { var sec = new WaitForSeconds(10f); while (StageManager.Instance.IsSpawnable) { yield return sec; if (_curPropCount < _maxPropCount) { int count = _planeGenPosList.Count; List posList = new(); for (int i = 0; i < count; i++) { //ºóÀÚ¸® ã¾Æ¼­ ·£´ý if (!_planeDict.ContainsValue(i)) { posList.Add(i); } } if (posList.Count > 0) { int rnd = Random.Range(0, posList.Count); var plane = SelectProp("Plane", _planeGenPosList[posList[rnd]]); if (plane != null) { _planeDict.Add(plane, posList[rnd]); } } } } } private PropController SelectProp(string type, Transform parent = null) { var rateTable = TableManager.Instance.GetProbByType(type); int curProb = 0; int rnd = Random.Range(0, 10000); int groupId = 0; foreach (var rate in rateTable) { curProb += rate.Prob; if (rnd < curProb) { groupId = rate.GroupId; break; } } var targets = TableManager.Instance.GetPropGroupList(groupId); curProb = 0; rnd = Random.Range(0, 10000); foreach (var prop in targets) { curProb += prop.GenRate; if (rnd < curProb) { return GenerateProp(prop, parent); } } return null; } private PropController GenerateProp(JPropInfoData data, Transform parent = null) { var prop = AddressableManager.Instance.Spawn(data.PrefabName, parent); var controller = prop.GetComponent(); if(parent != null) { controller.SetData(data); } else { int rnd = Random.Range(0, _propGenerateArea.Count); var bound = _propGenerateArea[rnd].bounds; controller.SetData(data, bound); } _curPropCount++; return controller; } private void OnPropRemoved(EventPropRemoved e) { if (_carDict.ContainsKey(e.Prop)) { _carDict.Remove(e.Prop); } else if (_planeDict.ContainsKey(e.Prop)) { _planeDict.Remove(e.Prop); } AddressableManager.Instance.Release(e.Prop.gameObject); _curPropCount--; } #endregion Props #region Item public void SpawnItems() { StartCoroutine(SpawnItemCoroutine()); } private IEnumerator SpawnItemCoroutine() { var sec = new WaitForSeconds(10f); while (StageManager.Instance.IsSpawnable) { yield return sec; int count = _itemSpawnPosList.Count; for (int i = 0; i < count; i++) { if (!_itemDict.ContainsValue(i)) { _itemDict.Add(SelectItem(i), i); break; } } } } private StageItem SelectItem(int pos) { var items = TableManager.Instance.GetStageItemList(); int rnd = Random.Range(0, items.Count); var table = items[rnd]; var itemPrefab = AddressableManager.Instance.Spawn("StageItem", _itemSpawnPosList[pos]); itemPrefab.transform.localPosition = Vector3.zero; var item = itemPrefab.GetComponent(); item.SetData(table); return item; } public void RemoveItem(StageItem item) { if(_itemDict.ContainsKey(item)) { _itemDict.Remove(item); AddressableManager.Instance.Release(item.gameObject); } } #endregion Item }