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

2021. 7. 9. 09:00Unity/VR

전편에 이어서 이번에는 Ui와 그에맞는 로직을 짰다.

현재 추가된 기능은 조건검사클래스에서 넘어온 딕셔너리의 수만큼 Ui가 "동적"할당되고 코스트와 스킬 이름이 초기화가 된다.

또한 Ui에 버튼을 누를시 OnClick 함수를 통해 동적할당시 같이 넘어간 데이터를 기반으로 획득 가능한지 조건 검사를 진행 후 UseAble로 스킬이 넘어가도록 구현이 되있고 완료된 스킬은 딕셔너리에서 삭제가 된다.

이 과정에서 자연스럽게 XR Ui interacting이 진행 되었다.


 

초기 셋팅

 

본 프로젝트는 XR기반으로 설계 되었기 때문에 Ui를 사용하려면 먼저 설정 해야 하는 것이 있다.

먼저 Canvas에 다음 Component를 추가해야 한다.

다음은 EventSystem에 아래 사진의 컴포넌트를 추가한다.

이 두개를 설정하면 XR Rig등 기본적인 요소가 존재 한다는 가정하에 지금부터 만드는 모든 UI들이 상호작용 가능한 상태가 된다.

 

 

Scroll View

 

이번 프로젝트에 사용될 Ui는 Scroll View가 제일 중요하다고 말할 수 있겠다. Scroll View의 가장 큰 특징은 상하좌우로 슬라이드가 가능하다는 것이다. 이 것을 통해 스킬수가 엄청나게 많이 늘어도 상하로 슬라이드 하며 모두 표시가 가능하게 된다.

 

본인은 Scroll View의 상하만 필요하므로 Horizontal의 요소는 모두 삭제 해 놓았고 원할한 동작을 위해 Content란에서 두가지의 컴포넌트를 추가해야 한다.

참고로 Scroll View에서는 Content의 자식으로 설정된 Ui만 인식하므로 유의해서 사용해야 한다.

 

 

 

로직

 

먼저 SkillManager Class를 보자

 public Dictionary<GameObject, int> kakutokuAble = new Dictionary<GameObject, int> (); //획득가능 변수        
 public List<GameObject> useAble = new List<GameObject>();                             //사용가능 변수

저번과는 다르게 Add와 Remove편하게 useAble을 List형태로 바꿔 주었다.

 

 public GameObject kakutokuUi;
 public GameObject skillSysUi;

그리고 Ui의 제어를 위해 이 곳에서 선언을 해주고 정적으로 미리 할당을 해 주었다.

 

 public void KakutokuUiSet() //NPC Onclick function
    {
        Instantiate(kakutokuUi);

        foreach (KeyValuePair<GameObject, int> item in kakutokuAble)
        {
            var skillSysTemp = Instantiate(skillSysUi);
            skillSysTemp.transform.SetParent(GameObject.Find("Content").transform, false);          //false 안붙이면 scale이랑 pos 뒤죽박죽 됨
            skillSysTemp.GetComponent<SkillSysUi>().Init(item.Key, item.Value);
            
        }
    }

이 코드가 SkillManager의 핵심 코드이다. 특정 NPC를 만나게 되면 실행이 될 함수이다.

이 함수가 실행이 되면 먼저 UiCanvas가 Instantiate된다. 그후 딕셔너리에 모든 원소를 Ui에 동적 할당해 주기위해 foreach문으로 순회한다. 

순회문 안의 로직은

  1. 1.스킬을 표기할 Ui를 생성하고 반환 받는다.
  2. 2.Scroll View는 Content의 자식으로 받아야 동작하기 때문에 방금 만든 Ui를 자식화 시켜준다.(SetParent)             - 여기서 마지막 부분의 false를 븉히지 않는다면 scale과 pos값이 이상하게 변화해 의도대로 만들어지지 않는다.
  3. Ui의 text변경과 OnClick에 들어갈 데이터들을 SkillSysUi Class로 보낸다.

 

다음은 SkillSysUi Class이다.

 

현재의 Ui형태는 이렇게 Image Text Text Button으로 구성되있다.

Image를 부모로두고 나머지 Ui들을 자식으로 두었다. 이렇게 하면 SkillSysUi Script작성시 정적으로 간편하게 작성할 수 있게 된다.

 

public Text nameText;
public Text costText;
public Button button;
private GameObject tempGameObj;
public SkillManager skillManager;

먼저 필요한 요소들을 만들어 둔다. tempGameObj는 SkillManager에서올 GameObject를 잠시 담아두는 용도이다.

 

public void Init(GameObject name,int cost)
    {
        nameText.text = name.name;
        costText.text = cost.ToString();
        tempGameObj = name;
    }

SkillManager에서 Ui가 동적할당 되면 바로 실행되는 함수이다. 자료들을 받아 위 변수들을 초기화 해주는 용도이다.

 

 private void Start()
    {
        button.GetComponent<Button>().onClick.AddListener(delegate { OnClick(); });
        skillManager = GameObject.Find("SkillManager").GetComponent<SkillManager>();
    }

Button의 Onclick또한 정적으로 사용이 불가능해 동적으로 사용해야하기 때문에 리스너를 사용해 할당해 주었다.

 

 void OnClick()
    {
        //if cost가 충분 하다면
        //Player cost 감소

        skillManager.useAble.Add(tempGameObj);
        skillManager.kakutokuAble.Remove(tempGameObj);
        foreach (KeyValuePair<GameObject, int> item in skillManager.kakutokuAble)
        {
            Debug.Log(item.Key);
        }
            Debug.Log(tempGameObj.name);
        Debug.Log("스킬 획득");

아직 플레이어 스테이터스가 구현이 안되어서 주석 처리 해놓은 부분이 있다. 

조건검사가 참이면 useAble List에 방금 저장해둔 스킬이 추가가 되고 딕셔너리에서는 삭제가 된다.

 

지금까지의 동작을 실행한 모습이다. Magic3의 버튼을 누르게 될경우이렇게 딕셔너리에서 삭제가 된다.(1,2,4,5,6)

UseAble에서도 잘 저장된 모습을 볼 수 있다.

 

 

 

 

다음 챕터는 MagicPrepare에 적용하는 Ui와 로직이다. 

딱히 새로운게 많이 없어 오늘 사용한 내용이 거의 대부분일 것이다.