본문 바로가기
스파르타 내배캠

스파르타 내배캠 Unity 3기 4일차

by LemongO 2023. 12. 27.

마지막 챌린지 구현 하는 날~

 

 

구현하기에 앞서 오늘은 조원 분께서 내가 알고싶었던 기능을 알려주셔서 먼저 짚고 넘어가야겠다.

 

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. 해금 된 난이도는 버튼이미지를 '흰색'으로 칠하고, 잠금 된 난이도는 버튼이미지를 '회색'으로 칠한다.

 

Before

바꾸기 전. 모든 난이도가 흰색으로 해금여부를 알 수 없다.

 

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 모드 클리어

 

Easy 모드 클리어 시 다시 StartScene으로 전환 했을 때,

LevelUnlock 클래스의 레벨 잠금 조건에 따라 중간 레벨은 해금 되어야 한다.

 

보통 난이도가 해금되었다