본문 바로가기

유니티/확장 프로젝트[3D]

3D 미니 프로젝트 2 - alpha ] 버그 수정

프로젝트에서 UI 작업을 진행 중, 지난 번에 정리했었던 강화 시스템에서 오류가 생기게 되었다..

 

3D 미니 프로젝트 2 - 4 ] 강화 시스템

지난 포스팅에서는 골드메탈님의 강의 중 공격에 대해 정리 해 보았다. 3D 미니 프로젝트 2 - 3 ] 공격 지난 포스팅에서는 아이템 수집 및 장착을 구현하였다. 3D 미니 프로젝트 2 - 2 ] 아이템 수집

mini-noriter.tistory.com

 

두 가지의 오류가 생기게 되었는데, 까먹기 전에 정리 해 두고자 한다.

 


1. 총 강화가 적용되지 않는 문제 (겉 값 문제)

 

바로 문제 해결을 위해 고민하느라 캡쳐를 해 두지 못하였다..

 

생긴 문제를 글로 정리 해서 설명하자면

  • 무기에 대한 정보는 PlayerCode.cs에 저장 된 WeaponList(실제 무기 오브젝트)PlayerItem.cs에 있는 WeaponItemInfo 객체에 저장된다.
  • WeaponList에서는 무기별로 고정된 Index를 가지게 된다. (해머 - 0번 / 건 - 1번 / 머신건 - 2번)
  • WeaponItemInfo 객체에서는 무기 습득 순서에 따라서 Index가 부여 된다.

즉, 결론적으로 이야기 하자면 WeaponList와 WeaponItemInfo 간의 인덱스 차이 때문에 생기게 된 문제이다.

 

Enchant를 성공하게 되면 WeaponItemInfo에 있는 객체는 연결되어 있기에 자동으로 값이 갱신되지만 WeaponList에 있는 오브젝트는 수동으로 갱신을 해 주어야 한다.

 

따라서 PlayerItem.cs에서 그러한 역할을 담당하게끔 코드를 만들어 놓았다.

public void SetEnchantInfo(int returnIndex)
    {
        // 강화 후 정보를 무기에 적용하는 과정

        weapon = playerInfo.WeaponList[weapons[returnIndex].weaponCode].GetComponent<Weapon>(); // 무기 자체를 불러 온다.

        weapon.Damage = weapons[weapons[returnIndex].weaponCode].baseAtk + weapons[weapons[returnIndex].weaponCode].enchantAtk; // 강화 수치만큼 늘어나게끔!
        weapon.AtkDelay = weapons[weapons[returnIndex].weaponCode].baseDelay + weapons[weapons[returnIndex].weaponCode].enchantDelay; // 딜레이는 강화 수치만큼 줄어들게! (이미 enchantDelay가 마이너스이기 때문에 +를 적는다.)
        weapon.criticalPercent = weapons[weapons[returnIndex].weaponCode].criticalPercent; // 강화 수치만큼 늘어나게끔!

        if(weapons[returnIndex].type == Weapon.AtkType.Range)
        {
            Bullet bullet = weapon.bullet.GetComponent<Bullet>();
            bullet.SetDamage(weapon.Damage);
        }

    }

바로 이 함수였는데.. 여기서 WeaponList와 weapons(WeaponItemInfo 객체 이름)의 Index가 같음을 볼 수 있다.

 

둘의 Index 순서는 같을 수도 있고, 다를 수도 있지만, 순서가 달라질 경우에는 정보가 제대로 갱신되지 않게 된다.

 

따라서, 0번 WeaponList 인덱스를 가진 해머를 가장 처음 먹게 되면 WeaponItemInfo에서도 0번 인덱스를 가지게 되어 별 상관 없게 되지만 가장 먼저 1번 인덱스를 가지는 건을 습득하게 되면 WeaponItemInfo 까지만 정보가 갱신되고, 실제 데미지에 영향을 주는 WeaponList에 있는 Weapon.cs값이 변하지 않게 된다.

 

즉, 위 함수 코드를 제대로 의도한 대로 설정하지 않은 실수였다..

 

public void SetEnchantInfo(int returnIndex)
    {
        // 강화 후 정보를 무기에 적용하는 과정

        int weaponCode = weapons[returnIndex].weaponCode; // 무기 고유의 코드를 받아와야 한다.

        weapon = playerInfo.WeaponList[weaponCode].GetComponent<Weapon>(); // 무기 자체를 불러 온다.(WeaponList)

        weapon.Damage = weapons[returnIndex].baseAtk + weapons[returnIndex].enchantAtk; // 강화 수치만큼 늘어나게끔! (weapons에서는 returnIndex를 그대로!)
        weapon.AtkDelay = weapons[returnIndex].baseDelay + weapons[returnIndex].enchantDelay; // 딜레이는 강화 수치만큼 줄어들게! (이미 enchantDelay가 마이너스이기 때문에 +를 적는다.)
        weapon.criticalPercent = weapons[returnIndex].criticalPercent; // 강화 수치만큼 늘어나게끔!

        if(weapons[returnIndex].type == Weapon.AtkType.Range)
        {
            Bullet bullet = weapon.bullet.GetComponent<Bullet>();
            bullet.SetDamage(weapon.Damage);
        }

    }

위와 같이 weaponCode에는 WeaponList에 들어가는 무기 index를 가져와 주고, weapons(WeaponItemInfo 객체) 에는 returnIndex를 그대로 써 주어야 한다.

 

강화 적용이 완료 된 모습

이렇게 해 주면 Index 1인 건만 먹고도 제대로 강화가 적용되게 된다.

 


2. 가끔 해머를 먹지 않아도 해머 선택 버튼이 활성화 되어 있는 문제

 

강화 창에서 무기를 먹어야 상단에 있는 무기 선택 버튼이 활성화 된다.

 

그런데 가끔 해머를 먹지 않았는데 해머의 강화 선택 버튼이 활성화 된 경우가 생기게 되었다.

활성화 된 것도 모자라 전혀 강화를 하지 않았는데 풀강이 된 상태가 되어 있다.

 

천천히 코드를 보면서 생각 해 본 결과

  1. 우선 해머의 itemCode는 0이다.
  2. weapons에 저장 된 것이 없을 때는 null이 아니고, 모든 원소들이 0으로 들어간 상태이다.
  3. 2번과 같은 이유로 아무것도 저장되지 않았을 때는 weapons[0].baseAtk 가 0인 조건을 사용한다.(baseAtk는 무조건 있어야 하기 때문)
  4. weaponCode 역시 0이기 때문에 1번에 의해서 해머가 있는 것처럼 감지가 될 수 있다.
  5. 아래 코드에서 볼 수 있듯이 enchantCount 와 maxEnchant가 둘 다 0으로 같기 때문에 풀강이 된 상태로 선택할 수 있게 되는 것이다.
public void ChangeEnchantWeapon(int itemCode)
    {
        WeaponItemInfo imsi = checkWeapon(itemCode);
        enchant.SetTarget(imsi);
        enchant.returnIndex = weaponIndex;

        switch (itemCode)
        {
            case 1:
                if (imsi.enchantCount == imsi.maxEnchant)
                {
                    fullEnchantNotice(imsi);
                    return;
                }    
                SetInfo(imsi);
                enchant.isWeaponOn = true;
                WeaponImg.sprite = img1;
                break;
            case 2:
                if (imsi.enchantCount == imsi.maxEnchant)
                {
                    fullEnchantNotice(imsi);
                    return;
                }
                SetInfo(imsi);
                enchant.isWeaponOn = true;
                WeaponImg.sprite = img2;
                break;
            case 3:
                if (imsi.enchantCount == imsi.maxEnchant)
                {
                    fullEnchantNotice(imsi);
                    return;
                }
                SetInfo(imsi);
                enchant.isWeaponOn = true;
                WeaponImg.sprite = img3;
                break;
        }
    }

강화 할 무기를 바꾸는 함수이다.

case 하위에 있는 조건문에서 enchantCount와 maxEnchant가 0으로 같아서 풀강이 된 상태가 나오게 된다.

 

그렇다면 해결책은..?

 

원인을 알게 되었으니.. 무기들의 itemCode를 1씩 올려주는 방법을 택했다.

 

물론... 이것은 아이템이 별로 없기에 가능하다.

 

조건적으로 무기가 없을 때만 나오게 되는 변수를 하나 넣어 준다던가.. 그러는 것이 더 좋을 수도 있지만.. 그래도 인덱스와 무기 번호를 맞추는 것이 좋겠다 싶어서 아싸리 바꾸어 주었다.

 

PlayerCode에서 버튼을 누르는 조건, SaveInfo에서 저장되는 형태 등등을 다 바꾸어 주었다.

 

자세한 코드 변경은 깃헙에서 볼 수 있다.

 

GitHub - kkyoulza/Unity: practice unity 2D, 3D and so on.

practice unity 2D, 3D and so on. Contribute to kkyoulza/Unity development by creating an account on GitHub.

github.com