TIL
25.04.09 TIL
gaon99
2025. 4. 9. 21:51
최종 프로젝트 4일차
1. 오늘 학습 키워드
리팩토링, 버튼
2. 오늘 학습 한 내용을 나만의 언어로 정리하기
어제 작성하고 오늘 추가로 작성해서 스타트 씬의 흐름을 제작했다.
그리고 작성한 부분을 피드백을 받기 위해 튜터님을 찾아갔다.
내가 작성한 것은 UI의 작업은 모두 Base에서 작동을 하고, 그냥 패널의 교통 정리만 Controller에서 작업을 했는데
이렇게 구조를 짜는 것이 좋지 못해서, 다른 방법을 알려주셨다.
현재 내가 작업을 한 부분에서 Base는 진짜 UI를 띄우는 그런 역할만을 위해 존재하고,
Controller를 통해 해당 UI를 관리하는? 그런 느낌으로 리팩토링 했다.
버튼 입력시에 켜지는 패널과, 원래 작성했었던 부분을 합쳐서 이렇게 작성했다.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class StartController : ControllerUI
{
public StartUI startUI;
[NonSerialized] private bool isFirst;
private Dictionary<string, Action> buttonActions = new();
protected override void Start()
{
InitPanel();
isFirst = IsFirst();
base.Start();
startUI.Initialize();
startUI.OnClickButton += OnButtonClicked;
RegisterButtonActions();
ShowUI(startUI[PanelKey.Title]);
StartCoroutine(WaitForInput());
}
private void OnButtonClicked(string key)
{
if (buttonActions.TryGetValue(key, out var action))
{
action?.Invoke();
}
}
private void RegisterButtonActions()
{
buttonActions["Select_Start"] = () => { ShowUI(startUI[PanelKey.Camp]); };
buttonActions["Select_Mini"] = () => { ShowUI(startUI[PanelKey.Credits]); };
buttonActions["Select_Ending"] = () => { ShowUI(startUI[PanelKey.Credits]); };
buttonActions["Select_Return"] = ReturnToStartUI;
buttonActions["Camp_Hexa"] = () => { ShowUI(startUI[PanelKey.CharacterSelect]); };
buttonActions["Camp_Flag"] = () => { ShowUI(startUI[PanelKey.CharacterSelect]); };
buttonActions["Camp_Return"] = () => { ShowUI(startUI[PanelKey.Select]); };
buttonActions["Char_Start"] = () => { SceneManager.LoadScene("LoadingScene"); };
buttonActions["Char_Return"] = ReturnToStartUI;
buttonActions["Test"] = Test;
}
public void Test()
{
isFirst = true;
}
private void InitPanel()
{
foreach (var panel in startUI.panels.dataList)
{
allUIs.Add(panel.Value);
}
}
public void ReturnToStartUI() // 타이틀로 되돌아가기
{
ShowUI(startUI[PanelKey.Title]);
StartCoroutine(WaitForInput());
}
IEnumerator WaitForInput() // 타이틀에서 입력시에 패널 변경
{
yield return new WaitUntil(() => Input.anyKeyDown);
if (isFirst)
{
PlayerPrefs.SetInt("Confirm", 1);
ShowUI(startUI[PanelKey.Desc]);
yield return StartCoroutine(startUI.TextTextEffect("테스트로 작성하는 스트링입니다\n 짧으면 효과를 보기 힘드니 \n아무 말이나 잠시 적겠습니다.",
() => { ShowUI(startUI[PanelKey.Select]); }));
}
else
{
ShowUI(startUI[PanelKey.Select]);
}
}
public bool IsFirst() // 초회인지 판별
{
return PlayerPrefs.GetInt("Confirm", 0) == 0;
}
}
그리고 버튼과 패널의 수가 점점 늘어나다보니, 너무 보기가 싫어져서 툴 중에 딕셔너리 처럼 사용 가능한 리스트가 있어서
이를 활용하여, 패널 및 버튼을 넣어주었다.
이로서 스타트 ui는 정말 그냥 버튼 혹은 패널 그 기능밖에 없다.
이를 관리해주는 것은 컨트롤에서 일어난다.
using System;
using System.Collections;
using System.Text;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class StartUI : BaseUI
{
// 패널
public SerializableDic<PanelKey,BaseUI> panels = new();
public BaseUI this[PanelKey key] => panels[key];
// 버튼
[Header("Button")]
public SerializableDic<string, Button> buttons = new();
public Action<string> OnClickButton;
[Header("Text")] [SerializeField] private TextMeshProUGUI descText;
public override void Initialize()
{
foreach (var btn in buttons.dataList)
{
string key = btn.Key;
Button button = btn.Value;
if (button != null)
{
button.onClick.RemoveAllListeners();
button.onClick.AddListener(() => OnClickButton(key));
}
}
}
public IEnumerator TextTextEffect(string text, Action onComplete)
{
descText.text = string.Empty;
StringBuilder stringBuilder = new();
for (int i = 0; i < text.Length; i++)
{
char currentChar = text[i];
if (currentChar == '\n') // 줄바꿈을 만났을 경우, 입력 대기
{
stringBuilder.Append(currentChar);
descText.text = stringBuilder.ToString();
yield return new WaitUntil(() => Input.anyKeyDown);
}
else
{
stringBuilder.Append(text[i]);
descText.text = stringBuilder.ToString();
yield return new WaitForSeconds(0.05f);
}
}
yield return new WaitUntil(() => Input.anyKeyDown);
onComplete?.Invoke();
}
}
그리고 라이브 2d를 해보려고 했는데,
맘대로 잘 되질않아 이 부분을 좀 더 해보려고한다.
3. 학습하며 겪었던 문제점 & 에러
라투디, 그리고 리펙토링하면서 왜 이렇게 해야하나 하는 생각도 있었다,
4. 내일 학습 할 것은 무엇인지
크레딧 패널 제작