2D 팀 프로젝트 진행중(UI 연결 작업)
주말까지 작업을 좀 진행해서 해놓은게 많다. 일단 점수구현은 저번에 한걸로 됐고 주말에 UI에 쓸 이미지들을 제작했는데 오늘 주로 한 것은 버튼 이벤트 연결이다. 솔직히 버튼 이벤트 연결은 어렵지 않아서 딱히 트러블 슈팅할 것도 없어 오늘은 새로 작성한 스크립트에 대해서만 설명하고 마무리하려 한다. 원래 ScoreManager의 God Mode에서 직접적으로 게임을 클리어 처리 할 수 있었는데 이제 실제로 연동해야 해서 그 밑작업도 했다. (사실 연동까지 다 했는데 GameManager로 기능을 따로 빼야 한다고 해서...내일 다시 작업해야 한다...어렵진 않지만 귀찮다 흑흑)
화면에 목표시간까지 출력하고, 전에는 시간이 초만 보였는데 (60초가 넘어가면 1분 1초가 아니라 61초로 표시되는 등) 분, 초가 표시되게 수정하였다.
public void InitializeTotals(int fireTotal, int iceTotal, int targetTime)
{
........
int tm = targetTime / 60;
int ts = targetTime % 60;
targetTimeText.text = $"목표 시간: {tm:D2}:{ts:D2}";
}
D(Decimal)은 정수 값을 10진수 문자열로 포맷한다. 여기서 사용한 D2는 최소 두자리로 표현하되, 한 자리일 경우 앞에 0을 채움을 말한다.(3.ToString("D2") -> "03"
D계열은 정수 전용 포맷 지정자이므로 정수형에서 쓸 수 있기 때문에 int를 쓰도록 하자. 만약 실수에 쓰고 싶다면 F2 같은 부동소수점 전용 지정자를 사용.
캔버스에 붙여 게임 흐름에 필요한 UI들을 관리한다.
[Header("등급 표시용 UI")]
[SerializeField] private Image gradeImage;
[SerializeField] private Sprite[] gradeSprites;// A,B,C
[Header("조건 체크 아이콘")]
[SerializeField] private Image timeCheckIcon;
[SerializeField] private Image coinCheckIcon;
[SerializeField] private Sprite checkSprite;
[SerializeField] private Sprite crossSprite;
public struct RankResult
{
public GRADE Grade; // A, B, C
public bool TimeSuccess; // 시간 조건 달성 여부
public bool CoinSuccess; // 코인 조건 달성 여부
public RankResult(GRADE grade, bool timeSuccess, bool coinSuccess)
{
Grade = grade;
TimeSuccess = timeSuccess;
CoinSuccess = coinSuccess;
}
}
//스테이지 클리어 후 등급 결정 UI
public void ShowClearUI(RankResult result)
{
clearUI.SetActive(true);
gradeImage.sprite = gradeSprites[(int)result.Grade];
timeCheckIcon.sprite = result.TimeSuccess ? checkSprite : crossSprite;
coinCheckIcon.sprite = result.CoinSuccess ? checkSprite : crossSprite;
Time.timeScale = 0f;
}
RankResult구조체를 만들어 등급과 두 개의 성공 조건(시간, 코인)을 하나로 묶어 UI쪽으로 간편하게 넘길 수 있도록 한다.
gradeSprites[(int)result.Grade]
만약 A등급이면 index 0 이미지를, B라면 index 1이미지. C등급이면 index 2이미지를 가져와 보여준다.
조건 아이콘
result.TimeSuccess가 true면 checkSprite가, 아니면 crossSprite가 보이게 한다. 원작 게임도 이렇게 하길래 따라해보았다.
이로인해 추가된 코드는 ScoreManger에서 다음과 같다.
public void Rank()
{
//제한 시간을 넘기지 않으면 false로 넘어옴. !가 붙었으므로 true임
bool timeOK = !timeTracker.isTimeExceeded;
//모든 파이어스타 먹으면 true
bool fireOK = fireCollected == fireTotal;
//모든 아이스스타 먹으면 true
bool iceOK = iceCollected == iceTotal;
(등급 결정 코드..)
//추가된 코드
var rankResult = new StageUIController.RankResult(result, timeOK, fireOK && iceOK);
stageUI.ShowClearUI(rankResult);
}
오늘은 UI작업을 많이 해서 크게 어렵진 않았지만 어떻게 구조를 짜야 좋을까에 대한 고민을 좀 했다. 종이에 좀 끄적이다 보니 확실히 정리가 잘 되는 느낌이었다.
내일은 GameManager에 게임종료, 게임 클리어 ui를 연결하고 esc 기능을 넣으려 한다. 그 작업이 다 끝나면 코딩과는 상관없는 타이틀 로고와 아이콘들을 그릴 예정이다. 예전에도 ui를 했었는데 지금도 느끼지만 난 그런 ui만드는 것에 재능이 없는 것 같다... 아트팀이 괜히 있는게 아니다. 저 작업들이 끝나면 게임 클리어 ui에 애니메이션도 연결하려 한다. 아마 여기까지 완료하면 내가 맡은 일은 내일 모두 완료된다. 빨리 끝내고 발표 ppt 작성 좀 도와주고 개인 공부를 좀 하고 싶다.