마지막 챌린지 구현 하는 날~
구현하기에 앞서 오늘은 조원 분께서 내가 알고싶었던 기능을 알려주셔서 먼저 짚고 넘어가야겠다.
string 값을 넣어 줄 때 나는 ------ $"가나다 {int변수} " ------ 이런식으로 문자열 보간을 이용해 많이 써오고 있었다.
그런데 float값을 넣어 줄 땐 다음 코드와 같이 ------ + score.ToString("N2") ------ 소숫점 표현 때문에 +를 이용해 썼다.
bestTxt.text = score > 0f ? "현재 난이도 최고기록 : " + score.ToString("F2") : "";
기존에 내가 쓰던 문법 중 일부이다.
위처럼 쓰면 보간을 이용하지 못해 개인적으로 기분이 영 별로다.
하지만 오늘 알아낸 방법 두 가지
bestTxt.text = score > 0f ? $"현재 난이도 최고기록 : {string.Format("{0:F2}", score)}" : "";
이 방법은 조원분께서 알려주신 방법이다.
문자열 보간을 써도 되는 방법이 있네???
바로 써먹어 보......려고하는데 문득 생각이 들었다.
그냥 Tostring()을 보간 안에다 쓰면 안 되나?
bestTxt.text = score > 0f ? $"현재 난이도 최고기록 : {score.ToString("F2")}" : "";
이렇게 말이다.
빨간줄은 없는데...? 되나?
......
역시 일단 부딪혀 보고 아님 말고가 정답이다.
오늘도 중요한 마음가짐 하나를 배웠다.
근데... 더 줄일 수 있을거 같은 느낌인데???
글을 쓰던와중 찾아보았다. 분명 있을 느낌이다.
bestTxt.text = score > 0f ? $"현재 난이도 최고기록 : {score:F2}" : "";
역시 있었다. 앞으론 이걸 써야지~
별거 아니지만 그래도 새로운 것을 배웠으니 대만족!
자 이제 오늘의 구현으로 넘어가자.
오늘의 구현
난이도 해금 구현
난이도 해금을 어떤식으로 보여줄까?
1. 해금 된 난이도는 버튼이미지를 '흰색'으로 칠하고, 잠금 된 난이도는 버튼이미지를 '회색'으로 칠한다.
2. 잠금 된 난이도는 버튼을 클릭해도 반응이 없어야 한다.
3. 해당 레벨을 클리어 시 다음 레벨이 해금된다.
1. 해금 된 난이도는 버튼이미지를 '흰색'으로 칠하고, 잠금 된 난이도는 버튼이미지를 '회색'으로 칠한다.
바꾸기 전. 모든 난이도가 흰색으로 해금여부를 알 수 없다.
LevelUnlock 스크립트를 새로 만들어 작성해주자.
using UnityEngine;
using UnityEngine.UI;
public class LevelUnlock : MonoBehaviour
{
[SerializeField] Image[] levels;
}
Image 배열을 선언해 하이어라키 Easy, Normal, Hard 버튼을 levels 에 할당 해주자.
(각 오브젝트엔 Image 컴포넌트가 있다.)
using UnityEngine;
using UnityEngine.UI;
public class LevelUnlock : MonoBehaviour
{
[SerializeField] Image[] levels;
private void Start()
{
for (int i = 1; i < levels.Length; i++)
{
Diff diff = (Diff)i;
if(PlayerPrefs.GetInt(diff.ToString()) == 0)
levels[i].color = Color.gray;
}
}
}
계속해서 for문으로 levels의 개수만큼 루프를 돌며 해금되지 않은 레벨의 버튼은 회색으로 바꿔준다.
여기서 GameManager 스크립트에서 만들어 둔 Diff enum 타입 diff변수를
for문 안에서 선언 후 int i의 값을 DIff로 캐스팅 한 뒤 할당해준다.
enum의 각 값에는 int값이 할당되어 있으므로 i 를 Diff로 형변환 시 지금 코드에선 차례대로
Diff.Normal / Diff.Hard 가 된다.
Easy 버튼은 인덱스를 맞춰주기 위해서 할당만 해두었다.
그리고 if문 조건으로 PlayerPrefs.GetInt 를 이용해
"Normal" / "Hard" 키에 할당되어있는 int 값을 가져와 0과 같은지 비교한다.
나는 해금의 조건을 0 == 잠금, 1 == 해금 으로 표현할 것이기 때문에 if문 조건에 부합한다면 잠금상태이다.
잠금 상태인 레벨은 이미지를 회색으로 바꿔주도록 하자.
2. 잠금 된 난이도는 버튼을 클릭해도 반응이 없어야 한다.
이대로 실행한다면 잠금된 레벨이 회색으로만 보일 뿐 작동은 하게 되어있다.
그러니 잠금된 버튼은 무시되도록하자.
버튼 이벤트는 startBtn 스크립트의 gameStart 함수를 호출한다. 이 부분을 수정하자.
public class startBtn : MonoBehaviour
{
public void gameStart(int diff)
{
Diff diffString = (Diff)diff;
int selectLevel = PlayerPrefs.GetInt(diffString.ToString());
if (selectLevel == 0 && (int)diffString > 0)
return;
Difficulty.Diificulty = diff;
SceneManager.LoadScene("MainScene");
}
}
LevelUnlock 에서 했듯이 마찬가지로 Diff enum 변수 diffString에 int diff값을 Diff로 형변환 해준다.
int변수 selectLevel 에는 해당 레벨의 잠금여부가 할당된다.
버튼을 누름으로써 실행하고자 하는 난이도를 알게 되었고, 그 값이 변수 diffString 에 Diff 타입으로 들어있다.
enum값을 string으로 변환하는 ToString 함수를 이용해
PlayerPrefs.GetInt() 함수의 인자로 각 난이도가 적혀있는 string을 넘겨준다.
예) Normal 버튼을 누르면 diffString = Diff.Normal 이니 "Normal" 이 인자로 넘어간다.
각 난이도 키에 저장된 값을 selectLevel 변수에 할당하고 if문에서 조건을 확인한다.
앞서 0이면 잠금상태라고 했다. 혹시 diffString에 Easy가 담겨있었다면 항상 그 값은 0일것이다.
그러니 이 때는 조건범위에서 제외해야 하기 때문에 diffString의 int가 0보단 커야한다. (Easy = 0 이니까)
그러므로 if 문에서 잠금상태로 판명난 버튼은 바로 return으로 반환 해 씬이 넘어가지 않도록 한다.
3. 해당 레벨을 클리어 시 다음 레벨이 해금된다.
레벨을 클리어하는 부분이므로 GameManager를 수정하도록 하자. 이 때 "클리어" 시에만 해금이 되므로,
클리어 시 발동하는 코드만 수정하면 된다.
if (cardsLeft == 2)
{
Diff nextLevel = diff + 1;
PlayerPrefs.SetInt(nextLevel.ToString(), 1);
}
클리어 될 때 Diff nextLevel 에 diff + 1 값을 할당한다.
enum 은 기본적으로 int 값으로 할당 되어 있기 때문에 현재 난이도인 diff + 1 을 해도 enum 타입인 Diff값에 할당이 된다.
즉 diff + 1 하여 nextLevel 에는 현재난이도 + 1 == 다음난이도 가 할당된다.
그리고 PlayerPrefs.SetInt() 함수의 키(key)로 enum을 string으로 변환해주는 ToString() 함수를 써 nextLevel.ToString() 값을, 앞서 말한대로 value 값은 해금 값인 1을 저장한다.
이 때, 현재 난이도가 Easy 라면 nextLevel.ToString() == "Normal" 이 된다.
Easy 모드 클리어 시 다시 StartScene으로 전환 했을 때,
LevelUnlock 클래스의 레벨 잠금 조건에 따라 중간 레벨은 해금 되어야 한다.
'스파르타 내배캠' 카테고리의 다른 글
스파르타 내배캠 Unity 3기 6일차 (1) | 2023.12.29 |
---|---|
스파르타 내배캠 Unity 3기 5일차 (0) | 2023.12.28 |
스파르타 내배캠 Unity 3기 3일차 (2) | 2023.12.26 |
스파르타 내배캠 Unity 3기 2일차 (2) | 2023.12.22 |
스파르타 내배캠 Unity 3기 1일차 (1) | 2023.12.21 |