Unity

[턴제 생존 게임] 유닛 정보 UI

wny0320 2023. 5. 19. 23:28

컴퓨터가 고장이 났어서 한동안 주요 코드들을 이용하여 만들지 못하고 틀만 잡았음

 

광부(Miner)의 정보를 받아와서 안에 있는 정보들을 시각화하는 UI

이번에 컴퓨터를 고치고 짠 코드이다.

 

턴제 생존 게임이면서 유닛을 각각 관리해주어야 하는 게임이다 보니 유저가 해당 유닛의 정보들을 보여주는 UI가 필요함

 

UI의 화면의 구성은 다음과 같음

또한 유닛의 하이라키에 포함된 오브젝트들은 다음과 같음

직접 수정될 값들의 이름을 대부분 Value로 네이밍 하였음

스크립트에서는 다음과 같이 해당하는 텍스트들을 받아서 저장하고 있음

 

MinerInfo.cs

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class MinerInfo : MonoBehaviour
{
    [SerializeField]
    GameObject exploreTeamOrganizeUI;
    [SerializeField]
    TMP_Text minerNameText;
    [SerializeField]
    List<TMP_Text> statTextList;
    [SerializeField]
    List<TMP_Text> healthTextList;
    [SerializeField]
    List<TMP_Text> perAbilityTextList;
    [SerializeField]
    List<TMP_Text> posAbilityTextList;
    [SerializeField]
    List<TMP_Text> negAbilityTextList;
    private int index = 0;
    public void ExploreTeamOrganizeUIOnOff()
    {
        if(exploreTeamOrganizeUI.activeSelf)
        {
            exploreTeamOrganizeUI.SetActive(false);
        }
        else
        {
            exploreTeamOrganizeUI.SetActive(true);
        }    
    }
    public void ShowMinerInfo()
    {
        if (exploreTeamOrganizeUI.activeSelf == false) return;
        Miner target = MinerManager.Instance.MinerList[index];
        Stat targetStat = target.gameObject.GetComponent<Stat>();
        Health targetHealth = target.gameObject.GetComponent<Health>();
        Ability targetAbility = target.gameObject.GetComponent<Ability>();

        minerNameText.text = target.Name;
        float[] stat = targetStat.GetStat();
        for(int i = 0; i < stat.Length-1; i++)
        {
            statTextList[i].text = stat[i].ToString();
        }
        float[] health = targetHealth.GetHealth();
        for(int i = 0; i < healthTextList.Count-1; i++)
        {
            healthTextList[i].text = health[i].ToString();
        }
        List<List<string>> abilityList = targetAbility.GetAbility();
        for(int i = 0; i < abilityList.Count; i++)
        {
            List<TMP_Text> targetText = new List<TMP_Text>();
            for(int j = 2; j >= 0; j--)
            {
                switch(i)
                {
                    case 0:
                        targetText = perAbilityTextList;
                        break;
                    case 1:
                        targetText = posAbilityTextList;
                        break;
                    case 2:
                        targetText = negAbilityTextList;
                        break;
                }
                if (abilityList[i].Count - 1 < j) targetText[j].text = "";
                else targetText[j].text = abilityList[i][j];
            }
        }
    }
    public void LeftButton()
    {
        index--;
        if (index < 0) index = MinerManager.Instance.MinerList.Count - 1;
    }
    public void RightButton()
    {
        index++;
        if (index > MinerManager.Instance.MinerList.Count - 1) index = 0;
    }
    private void Start()
    {
        exploreTeamOrganizeUI.SetActive(false);
    }
    private void Update()
    {
        ShowMinerInfo();
    }
}

 

ShowMinerInfo()함수에서 UI를 담고 있는 배경인 ExploreTeamOrganizeBackground라는 오브젝트가 비활성화시 코드가 바로 return하게끔 만들어 리소스 활용을 최소화 하였음

 

또한 받아오는 각 코드 내부에서 필요한 값들을 반환해주는 GetStat, GetHealth, GetAbility 등을 구현해두었음

 

해당 인수들을 받아와서 리스트를 순서대로 해당 값에 넣는 것이 코드의 주요 기능

다만 ability쪽은 조금 다르게 설정이 되어있다.

 

ability는 최대 3개를 가질 수 있게 하였으며(임시) Perfect, Positive, Negative로 총 3종류가 있어 한쪽만 3개가 들어갈 수도 있지만 하나도 없거나 3개보다 적은 경우도 있기 때문에 인덱스를 참조할 경우 오류가 발생할 수 있음

따라서 다음 코드를 통해서 인덱스 참조를 하였음

List<List<string>> abilityList = targetAbility.GetAbility();
        for(int i = 0; i < abilityList.Count; i++)
        {
            List<TMP_Text> targetText = new List<TMP_Text>();
            for(int j = 2; j >= 0; j--)
            {
                switch(i)
                {
                    case 0:
                        targetText = perAbilityTextList;
                        break;
                    case 1:
                        targetText = posAbilityTextList;
                        break;
                    case 2:
                        targetText = negAbilityTextList;
                        break;
                }
                if (abilityList[i].Count - 1 < j) targetText[j].text = "";
                else targetText[j].text = abilityList[i][j];
            }
        }

i 인수쪽은 이중 리스트 구조라 0번째 리스트, 1번째 리스트처럼 리스트의 순서를 나타내며 j는 리스트 안에 있는 string의 순서를 나타낸다.

따라서 j가 최대치인 2로 시작하여 0까지 반복하는데 채울 리스트의 수가 j보다 작다면 아래 텍스트부터 공백("")으로 채우게 설정한 것

 

OnOff쪽 함수는 UI 키고 끄기, Button쪽은 유닛을 담고 있는 리스트의 인덱스를 조절하여 참조할 유닛을 바꿔주는 역할을 한다.

 

실행 하는 모습