Unity 스킬 획득,관리 시스템(3)

2021. 7. 11. 07:41Unity/VR

전편에 이어 이제 획득한 스킬을 적용하는 단계까지 구현하였다.

추가된 기능은 필요한 Ui 2개를 더 만들었고 Ui의 상호작용에 따라 스킬의 적용까지이다.


 

로직

 

이번에도 클래스 단위별로 설명하겠다.

먼저 가장 메인이 되는 SkillManager Class를 보자

여기서 가장 메인이 되는 기능은 UseAbleUi와 CurrentSkillUi를 나타낼 Ui의 생성과 초기화, 그리고 현재 적용스킬의 관리이다.

  public List<GameObject> useAble = new List<GameObject>();    
  public Dictionary<int, GameObject> currentMagic = new Dictionary<int, GameObject>();
  public GameObject magicApplyUi; //canvas
  public GameObject skillAbleUi;
  public GameObject CurrentSkillUi;
  
  public void UseAbleUiApply()
    {
        Instantiate(magicApplyUi);

        foreach (GameObject item in useAble)
        {
            var skillAbletemp = Instantiate(skillAbleUi);
            skillAbletemp.transform.SetParent(GameObject.Find("ContentUseAble").transform, false);
            skillAbletemp.GetComponent<SkillUi>().Init(item);
        }
        foreach(KeyValuePair<int, GameObject> item in currentMagic)
        {
            var CurrentSkilltemp = Instantiate(CurrentSkillUi);
            CurrentSkilltemp.transform.SetParent(GameObject.Find("ContentCurrentMagic").transform, false);
            CurrentSkilltemp.GetComponent<CurrentSkillUi>().Init(item.Key,item.Value);
        }
    }

 

 public Dictionary<int, GameObject> currentMagic = new Dictionary<int, GameObject>();

currentMagic이라는 딕셔너리를 보자. 

이 딕셔너리는 int가 Key이고 GameObject가 Value인 자료이다.

여기서 오는 int는 index값으로 useAble에서 GameObject를 받아 적용중인 스킬에 넣을 때 위치를 고려하기 위한 값이다. 이렇게 함으로써 자신이 고른 스킬을 1,2,3중 어느위치에나 할당을 해줄 수 있는 것이다.

 

Instantiate(magicApplyUi);

Ui를 만들기전 기본이 되는 Canvas를 설정해 주었다.

 

 foreach (GameObject item in useAble)
        {
            var skillAbletemp = Instantiate(skillAbleUi);
            skillAbletemp.transform.SetParent(GameObject.Find("ContentUseAble").transform, false);
            skillAbletemp.GetComponent<SkillUi>().Init(item);
        }
 foreach(KeyValuePair<int, GameObject> item in currentMagic)
        {
            var CurrentSkilltemp = Instantiate(CurrentSkillUi);
            CurrentSkilltemp.transform.SetParent(GameObject.Find("ContentCurrentMagic").transform, false);
            CurrentSkilltemp.GetComponent<CurrentSkillUi>().Init(item.Key,item.Value);
        }

이 두개의 foreach문은 전편에서와 같은 로직이기 때문에 설명은 건너 뛰겠다.

 

  public GameObject tempApplyMagic;

이 클래스는 Ui의 생성,초기화 말고도 기능이 한개 더 존재하는데 그게 Ui 적용 로직에 중간 매개체와 현재 적용중인 3개의 스킬 관리 역할이다. tempApplyMagic이 중간 매개체이다. 또한 위에서 말했던 currentMagic이 스킬관리 역할을 하고 있다.

 

 

다음은 SkillUi Class이다. 이 클래스는 현재 획득한 스킬들을 SkillManager이서 데이터를 받아 Ui에 띄워주는 역할을 한다.

public Text nameText;
public Button button;
    
public void Init(GameObject name)
    {
        nameText.text = name.name;
        tempUiObj = name;
    }

 

private SkillManager skillManager;

private void OnClick()
    {
        skillManager.tempApplyMagic = tempUiObj;
    }

그리고 Onclick이 되었을 때

선택된 스킬을 SkillManager에 잠시 저장해주는 역할을 한다.

 

다음은 CurrentSkillUi이다.

public void Init(int index, GameObject name)
    {
        nameText.text = name.name;
        tempIndex = index;
    }

이 곳에서도 역시 Ui초기화를 하는 기능이 있고 특징 적인 부분은 클래스 내부 안에서 index를 관리하는 변수가 있다.

여기로 들어오는 자료는 딕셔너리 형태로 Key가 int이고 Value가 GameObject인 자료가 온다.

 

private SkillManager skillManager;
private MagicPrepare magicPrepare;

private void OnClick()
    {
        nameText.text = skillManager.tempApplyMagic.name; //UI갱신

        skillManager.currentMagic[tempIndex] = skillManager.tempApplyMagic;
        magicPrepare.magic[tempIndex] = skillManager.tempApplyMagic; //index로 할당 *중요*
    }

OnClick이 되었을 때 Ui가 현재 적용중인 Ui가 갱신이 되고 SkillManager에 현재 상태를 통보 해준다.

또한 가장 중요한 작업인 적용중인 스킬을 실제 사용되는 부분에 index를 통해서 할당을 해준다.

 

이렇게 MagicPrepare에 적용이 될 스킬 3개가 결정이 되는 로직인 것이다.

  public GameObject[] magicCube = new GameObject[3];
  public GameObject[] magic = new GameObject[3];


    private void OnTriggerExit(Collider other)
    {
        if (controllerL.inputDevice.TryGetFeatureValue(CommonUsages.grip, out float triggerTargetL))
        {
            if (controllerR.inputDevice.TryGetFeatureValue(CommonUsages.grip, out float triggerTargetR))
            {
                if(other.gameObject.name == "MagicPrepare_R")
                {
                    if (triggerTargetL >= 0.9 && triggerTargetR >= 0.9)
                    {
                        Debug.Log("Magic!");
                        var tempMagic1 = Instantiate(magicCube[0], magicPos_1);
                        tempMagic1.GetComponent<MagicCubeManager>().magic = magic[0];
                        var tempMagic2 = Instantiate(magicCube[1], magicPos_2);
                        tempMagic2.GetComponent<MagicCubeManager>().magic = magic[1];
                        var tempMagic3 = Instantiate(magicCube[2], magicPos_3);
                        tempMagic3.GetComponent<MagicCubeManager>().magic = magic[2];

                    }
                }
            }
        }
    }

이제 받은 magic을 하나하나 개인별로 뿌려주면 직접 스킬을 사용할 준비가 끝난다.

여기서 MagicCube는 마법구의 모양이고 Magic이 실제 스킬object이다.

 

 

왼쪽부터 현재 사용중인 스킬, 사용가능한 스킬, 획득가능한 스킬이다.

아직 아무 것도 건드리지 않은 상태며 사용가능한 스킬의 기본 값은 RapidShot으로 두었다.

 

획득가능한 스킬로부터 몇개를 획득하고 난 후의 모습이다. 사용가능한 스킬들이 늘어난 것을 볼 수 있다.

 

Rapid샷을 2번란으로 옮겨 보았다. index도 꼬이지 않고 Ui갱신 까지 잘 작동하는 모습을 볼 수가 있다.

 

 

마지막 실 사용 까지의 모습이다.