[Unity] Project. Personal_7

Lingtea_luv·2025년 6월 16일

Project

목록 보기
23/38
post-thumbnail

Where Am I?


7일차

7일차는 못다한 UI 작업을 마무리하는 날이었다. 이 날의 주요 쟁점은 ESC키의 역할이 중복되어 잘못하면 꼬일 수도 있지 않을까? 였다.

ESC키를 누르면 열려있는 UI를 닫을 수 있도록 하는 기능이 일시정지가 되는 기능이 충돌하게 된 것인데, 이 부분에 대해서는 조금 더 세심하게 구조를 짤 필요가 있지 않을까 싶다. 작업 내역은 다음과 같다.

  1. 제작 UI를 껐을 때 인벤토리에 재료를 돌려받는 기능 추가
  2. ESC키를 누르면 UI를 닫도록 하는 기능
  3. Title Scene UI 제작
  4. GameOver Scene UI 제작
  5. GameClear Scene UI 제작
  6. 환경설정 기능 구현 및 UI 제작, 연동
  7. 일시정지 기능 구현, UI 제작
  8. item 아이콘 이미지 생성, 적용

아이콘이나 Scene 배경에 활용된 이미지는 원하는 이미지, 에셋이 없어 AI 이미지 생성을 활용했다. 나름 나쁘지 않게 나와서 만족스럽게 사용한 것 같다.

이번에 소개할 코드는 CSV 파일을 활용하여 대사, PopUp 문구 관리하는 방법이다.

TextLoader

TextLoader는 CSV 파일을 읽어오기 위한 Class로 TextAsset csvFile = Resources.Load<TextAsset>("popup_texts") 로 Resources폴더에 저장된 popup_texts 이름의 CSV 파일을 불러오는 것이 가능하다.

public class TextLoader : MonoBehaviour
{
	// CSV 파일에서 읽어온 데이터를 저장하기 위한 Dictionary
    private Dictionary<string, string> _popupTexts;

    private void Awake()
    {
        Init();
    }
    
    private void Init()
    {
    	// 데이터 저장을 위한 Dictionary 초기화
        _popupTexts = new Dictionary<string, string>();
            
        // TextAsset : CSV 파일을 담는 변수
        // Resources.Load<TextAsset>() : Resources 폴더에 있는 CSV 파일을 읽어오기 위한 메서드
        // popup_texts : 파일 이름
        TextAsset csvFile = Resources.Load<TextAsset>("popup_texts");
        
        // 해당 파일이 없으면 돌아가기
        if (csvFile == null) return;

		// CSV 파일에 저장된 데이터를 개행(줄바꿈)으로 분리하여 개별 문장으로 저장
        string[] lines = csvFile.text.Split('\n');

		// lines에 저장된 각 문장마다 해당 루틴 실행
        for (int i = 1; i < lines.Length; i++)
        {
        	// 문장의 앞,뒤 공백 제거
            string line = lines[i].Trim();
            
            // 공백을 제거했을 때 아무 것도 없는 경우 스킵
            if (string.IsNullOrEmpty(line)) continue;
			
            // 문장을 ,(쉼표)로 구분
            string[] parts = line.Split(',');
			
            // 쉼표로 구분 했을 때 생기는 문장이 2개 이상인 경우(쉼표가 1개 이상인 경우)
            if (parts.Length >= 2)
            {
            	// 첫 번째는 'ID'
                string id = parts[0];
                
                // 두 번째는 'Text'
                string text = parts[1];
				
                // 세 번째 그 이상부터는 CSV 파일에 저장된 데이터에 따라 다르지만
                // 현재 파일에는 id, text 밖에 없기 때문에 세 번째 이상은 모두 text로 해석
                if (parts.Length > 2)
                {
                	// 다음 문장들을 text에 추가
                    for (int j = 2; j < parts.Length; j++)
                    {
                        text += "," + parts[j];
                    }
                }
                // id를 key, text를 data로 묶어 Dictionary에 저장
                _popupTexts[id] = text;
            }
        }
    }

	// 외부에서 데이터를 가져오기 위한 메서드
    // id : CSV 파일의 ID, Dictionary의 Key
    public string GetPopupText(string id)
    {
        return _popupTexts[id];
    }
}

TextManager

TextManager는 텍스트 출력을 담당하는 매니저로 게임 시작부터 끝까지 사용되기 때문에 Singleton패턴과 함께 DontDestroyOnLoad로 유지시켰다.

public class TextManager : Singleton<TextManager>
{
	// 팝업 문구를 출력하기 위한 UI
    private PopUpUI _popUpUI;
    // CSV파일의 데이터를 가지고 있는 TextLoader를 참조
    private TextLoader _textLoader;
    
    // Singleton 기본 세팅과 DontDestroyOnLoad, TextLoader 초기화 
    protected override void Awake()
    {
        base.Awake();
        DontDestroyOnLoad(gameObject);
        Init();
    }

	// 초기화 순서를 위해 외부 참조(PopUp UI)의 경우 Start()에서 처리
    private void Start()
    {
        ConfigUI();
    }

	// 초기화 순서가 상관 없는 내부 참조(TextLoader)의 경우 Awake()에서 처리
    private void Init()
    {
        _textLoader = transform.GetOrAddComponent<TextLoader>();
    }

	// PopUp UI 초기화, UI Binder를 활용
    private void ConfigUI()
    {
        if (_popUpUI == null)
        {
            _popUpUI = UIBinder.Instance.GetPopUpUI();
        }
    }
    
    // CSV 파일에 저장된 text를 불러오는 메서드
    private void PopupText(string id)
    {
    	// 외부에서 해당 메서드가 호출되어 TextManager가 생성되는 경우 
    	// Start보다 먼저 수행되기 때문에 ConfigUI를 호출해야한다.   
    	// 첫 씬에서 Manager 빈 오브젝트에 묶어 생성할 경우 호출하지 않아도 무관
        ConfigUI();
        
        // CSV 파일에 저장되어있는 데이터 불러오기
        string popupText = _textLoader.GetPopupText(id);
        
        // PopUp UI 활성화 및 출력
        _popUpUI.gameObject.SetActive(true);
        _popUpUI.PopupText(popupText);
    }
    
     // PopUp UI를 닫는 메서드
    private void HideText()
    {
    	// 문구 초기화 및 UI 비활성화
        _popUpUI.ResetText();
        _popUpUI.gameObject.SetActive(false);
    }

	// 일정 시간(time)이 지나면 출력된 PopUp UI창이 닫히도록 구현한 Coroutine
    private IEnumerator PopupTextRoutine(string id, float time)
    {
        PopupText(id);
        yield return new WaitForSeconds(time);
        HideText();
    }
    
    // 외부에서 호출하여 실제로 사용되는 메서드
    public void PopupTextForSecond(string id, float time)
    {
        StartCoroutine(PopupTextRoutine(id, time));
    }
}

PopUpUI

팝업 창의 기능을 담당하는 Class로 하위에 있는 TextMeshPro의 Text를 관리한다.

public class PopUpUI : MonoBehaviour
{
    [Header("Drag&Drop")] 
    [SerializeField] private TMP_Text _popUpText;

    private void Awake()
    {
        Init();
    }

    public void PopupText(string text)
    {
        _popUpText.text = text;
    }
    
    public void ResetText()
    {
        _popUpText.text = "";
    }
    
    private void Init()
    {
        if (_popUpText == null)
        {
            _popUpText = GetComponentInChildren<TMP_Text>();
        }
    }
}
profile
뚠뚠뚠뚠

0개의 댓글