1. 일괄 판매 후 판매 시 index out of range
GameManager에 List를 4개를 만들어줬다.
- Unit Object를 저장할 List, Unit Object를 생성할 때 부여할 Id, Unit의 Rank, Unit의 Gold
처음에는 List를 Unit Object와 Unit Object를 생성할 때 부여할 Id만 만들어뒀다가, GetComponent를 사용하는 게 별로 좋지 않다고 해서 최대한 사용을 덜 하기 위해 Unit 정보의 Rank와 Gold에 대한 정보도 담을 수 있도록 추가했다.
그리고 GameManager를 매번 불러와서 Add 시켜주는 게 비효율적인 것 같아서 GameManager 내에 Add와 Remove 함수를 만들어두고 매개변수를 통해서 List에 삽입하고 제거하는 식으로 만들었다.
public void AddCrateUnit(GameObject obj, int id, int rank, int gold)
{
CreateUnit.Add(obj);
CreateUnitId.Add(id);
CreateUnitRank.Add(rank);
CreateUnitGold.Add(gold);
}
public void RemoveCreateUnit(int id)
{
CreateUnit.RemoveAt(id);
CreateUnitId.RemoveAt(id);
CreateUnitRank.RemoveAt(id);
CreateUnitGold.RemoveAt(id);
}
- 일괄 판매
public void SelectSpeciesElf()
{
species = "Elf";
}
public void SelectSpeciesOrc()
{
species = "Orc";
}
public void SelectSpeciesHuman()
{
species = "Human";
}
public void SellBulk()
{
if (species == null) return;
for (int ids = 0; ids < GameManager.Instance.CreateUnit.Count; ids++)
{
if (GameManager.Instance.CreateUnit[ids].CompareTag(species) && GameManager.Instance.CreateUnitRank[ids] <= (int)Rank.D)
{
GameManager.Instance.Player.uiPlayerSpec.playerGold += GameManager.Instance.CreateUnitGold[ids];
sellIds.Add(ids);
}
}
GameManager.Instance.Player.uiPlayerSpec.UImanager.SetGoldUI(GameManager.Instance.Player.uiPlayerSpec.playerGold);
for (int sellId = 0; sellId < sellIds.Count; sellId++)
{
int ids = sellIds[sellId];
GameObject obj = GameManager.Instance.CreateUnit[ids];
MapArea unitMapArea = obj.GetComponentInParent<MapArea>();
if (unitMapArea != null)
{
unitMapArea.hasUnit = false;
unitMapArea.unitObject = null;
}
Destroy(GameManager.Instance.CreateUnit[ids]);
}
for (int sellId = sellIds.Count-1; sellId >= 0 ; sellId--)
{
int removeids = sellIds[sellId];
GameManager.Instance.RemoveCreateUnit(removeids);
}
species = null;
sellIds = new List<int>();
}
일괄 판매를 할 때 판매할 종족을 누르게 되면 species 값이 바뀌게 되고 일괄 판매 버튼을 누를 때 SellBulk가 실행된다.
만약에 선택된 값이 없다면 바로 함수를 끝내버리고, 선택된 값이 있다면 Unit을 생성했을 때 만들어둔 List를 불러와서 for문을 돌린다. List의 Obj Tag가 선택한 종족과 일치하는지 확인하고, Rank가 D급 이하라면 PlayerGold를 판매하는 Unit의 Gold 만큼 증가시키고, 따로 만들어둔 SellIds라는 List에 Index 번호를 저장해둔다.
판매가 끝난 뒤 UI를 업데이트해주고, 판매해뒀던 Index를 저장해뒀던 List를 첫 for문에서는 판매한 Unit을 Destroy시키고, 다음 for문에서 판매한 Unit의 Index를 List에서 제거해 준다. 가장 큰 Index부터 하는 이유는 List는 Remove를 하게 됐을 때 Index 값이 당겨진다.
ex) List<int> a = new List<int>{ 1, 2, 3, 4 }; 이고, a.RemoveAt(2) 를 하게되면 2번 Index 값에 4로 당겨지고 기존에 있던 Index 3번은 없어진다.
여기서 문제가 생겼는데 일괄 판매 이후에 기존에 사용하던 CreateUnitId 값이랑 Index 값이 일치하지가 않아서 index out of range 경고가 생기게 됐다.
처음에는 List를 삭제할 때 Index 번호를 알고 있으니까 높은 순서부터 해서 지우게 되면 그 이후에 Index에 있는 Unit의 CreateUnitId 값을 변경해 줄까 싶었는데 너무 복잡해질 것 같아서 그냥 SellUnit을 하는 함수 부분에 for문을 사용해서
GameManager에 있는 CreateUnit List의 Count 만큼 돌리면서 CreateUnitId가 선택한 Obj의 id랑 같을 때 List에서 제거해 주는 식으로 변경해 줬다.
2. UpgradeGold 차감
처음에 Upgrade Btn들을 만들고서 Species를 각 버튼을 눌렀을 때 해당하는 종족의 Enum 값을 받아오게끔 만들었다.
public void Upgrade()
{
int userGold = GameManager.Instance.Player.uiPlayerSpec.playerGold;
int upgradeGold = GameManager.Instance.Player.uiPlayerSpec.GetEnforceValue((int)species);
int nowUpgradeGold = upgradeGold * 10;
int nextUpgradeGold = (upgradeGold + 1) * 10;
if (userGold < nowUpgradeGold) return;
isUpgrade = true;
GameManager.Instance.Player.uiPlayerSpec.AddEnforce((int)species);
GameManager.Instance.Player.uiPlayerSpec.playerGold = userGold - nowUpgradeGold;
GameManager.Instance.Player.uiPlayerSpec.UImanager.SetGoldUI(GameManager.Instance.Player.uiPlayerSpec.playerGold);
upgradeGoldTxt[(int)species].text = (nextUpgradeGold).ToString();
}
문제가 됐던 부분은 upgradeGold가 표시되는 것과 실제로 적용되는 Gold가 달랐고, 전체적으로 코드 자체가 수정이 필요했다.
일단 기존에 uiPlayerSpec에서 UpgradeGold를 받아왔었는데 지금은 종족 강화 수치만 들고 와서 현재 Upgrade를 하는데 사용되는 Gold와 그다음 표시돼야 될 Gold를 구분시켰다.
그리고 현재 Gold가 nowUpgradeGold보다 적다면 함수를 종료했다.
이렇게 하니 강화가 어느 순간 잘 안되는 부분, Gold 사용량 보다 강화 수치가 더 높았던 경우, 강화 수치에 따른 Gold 표시가 제대로 되지 않았던 부분들이 해결됐다.
3. OnTriggerEnter
Monster가 공격받을 때 처음에는 Bullet 쪽에 OnTriggerEnter를 사용했더니 Unit이 한 마리만 있다면 상관이 없지만 여러 마리의 Unit이 여러 개의 Bullet을 쏘고, 그 Bullet이 Monster가 바로 죽는 Damage가 되면 한 마리의 Monster가 여러 번 죽는 현상이 생겼다.
이유는 Bullet 쪽에서 OnTriggerEnter를 하기 때문에 한 Monster의 Hp 값에서 Damage를 계산하는 부분을 Bullet 별로 실행했기 때문이었다.
ex) Bullet이 4개가 동시에 OnTriggerEnter 이벤트가 실행되면 한 몬스터의 Hp를 각각의 Bullet별로 받아오게 된다.
그래서 처음에는 Monster의 Hp 부분을 Static으로 수정해서 Bullet이 하나의 Monster Hp 값을 받아올 수 있게끔 수정을 하려고 했었는데 생각해 보니 Monster 쪽에서 OnTriggerEnter를 하면 그런 문제가 생기지 않는다는 것을 깨달았다.
하지만 이러고서도 Hp가 딱 0이 됐을 때 반복 실행되면서 여러 번 죽는 현상이 생겨서 CurrentHp가 <= 0 return 하는 식으로 변경하고 나서 문제를 해결했다.
'내배켐 Unity TIL' 카테고리의 다른 글
Unity 56일차 TIL - Unity FSM(디자인 패턴) 트러블슈팅 (0) | 2024.07.01 |
---|---|
Unity 55일차 TIL - Unity FSM(디자인 패턴) (0) | 2024.06.28 |
Unity 47일차 TIL - Unity InputSystem (0) | 2024.06.18 |
Unity 41일차 TIL - 팀 프로젝트 2 (마무리) (0) | 2024.06.10 |
Unity 36일차 TIL - 팀 프로젝트 1 (Unity MiniMap) (1) | 2024.06.03 |