상세 컨텐츠

본문 제목

유니티 공부(15)

유니티

by MJ_119 2023. 10. 26. 15:37

본문

출처 : 골드메탈 유니티 뱀서라이크 14+

https://www.youtube.com/watch?v=QxsH5fE0iAo&list=PLO-mt5Iu5TeZF8xMHqtT_DhAPKmjF6i3x&index=19

 

 

 

캐릭터 해금 시스템

 

1. 추가 캐릭터 버튼

 

2. 잠금과 해금

 - PlayerPrefs : 간단한 저장 기능을 제공하는 유니티 제공 클래스

enum Achive { UnlockPotato, UnlockBean } // 업적 관리 { 업적이름 , ... }
Achive[] achives;

void Init()
    {
        PlayerPrefs.SetInt("MyData", 1);

        PlayerPrefs.SetInt("UnlockPotato", 0);
        PlayerPrefs.SetInt("UnlockBean", 0); // 업적이 많을시에(ex. 몇백개) 하나하나씩 초기화 하기 너무 많으니 아래와 같이 코딩

        foreach(Achive achive in achives)
        {
            PlayerPrefs.SetInt(achive.ToString(), 0);
        }
    }

 

 

3. 업적 달성 로직

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AchiveManager : MonoBehaviour
{
    public GameObject[] lockCharacter;
    public GameObject[] unlockCharacter;

    enum Achive { UnlockPotato, UnlockBean } // 업적 관리 { 업적이름 , ... }
    Achive[] achives;

    void Awake()
    {
        achives = (Achive[])Enum.GetValues(typeof(Achive)); // 위의 enum Achive{}의 데이터값을 가져와서 Achive[] achives에 넣음

        if (!PlayerPrefs.HasKey("MyData")) // 업적 데이터 초기화
        {
            Init();
        }

    }

    void Init()
    {
        PlayerPrefs.SetInt("MyData", 1);

        PlayerPrefs.SetInt("UnlockPotato", 0);
        PlayerPrefs.SetInt("UnlockBean", 0); // 업적이 많을시에(ex. 몇백개) 하나하나씩 초기화 하기 너무 많으니 아래와 같이 코딩

        foreach(Achive achive in achives)
        {
            PlayerPrefs.SetInt(achive.ToString(), 0);
        }
    }

    void Start()
    {
        UnlockCharacter();
    }

    void UnlockCharacter()
    {
        for(int index=0; index<lockCharacter.Length; index++)
        {
            string achiveName = achives[index].ToString();
            bool isUnlock = PlayerPrefs.GetInt(achiveName) == 1;
            lockCharacter[index].SetActive(!isUnlock);
            unlockCharacter[index].SetActive(isUnlock);
        }
    }

    // Update is called once per frame
    void LateUpdate()
    {
        foreach( Achive achive in achives)
        {
            CheckAchive(achive);
        }
    }

    void CheckAchive(Achive achive)
    {
        bool isAchive = false;

        switch (achive)
        {
            case Achive.UnlockPotato:
                isAchive = GameManager.instance.kill >= 10;
                break;

            case Achive.UnlockBean:
                isAchive = GameManager.instance.gameTime == GameManager.instance.maxGameTime;
                break;
        }

        if (isAchive && PlayerPrefs.GetInt(achive.ToString()) == 0 ) {
            PlayerPrefs.SetInt(achive.ToString(), 1);
        }
    }
    
}

 

4. 해금 알려주기

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AchiveManager : MonoBehaviour
{
    public GameObject[] lockCharacter;
    public GameObject[] unlockCharacter;
    public GameObject uiNotice;

    enum Achive { UnlockPotato, UnlockBean } // 업적 관리 { 업적이름 , ... }
    Achive[] achives;
    WaitForSecondsRealtime wait; // 멈추지 않는 시간

    void Awake()
    {
        achives = (Achive[])Enum.GetValues(typeof(Achive)); // 위의 enum Achive{}의 데이터값을 가져와서 Achive[] achives에 넣음
        wait = new WaitForSecondsRealtime(5);

        if (!PlayerPrefs.HasKey("MyData")) // 업적 데이터 초기화
        {
            Init();
        }

    }

    void Init()
    {
        PlayerPrefs.SetInt("MyData", 1);

        PlayerPrefs.SetInt("UnlockPotato", 0);
        PlayerPrefs.SetInt("UnlockBean", 0); // 업적이 많을시에(ex. 몇백개) 하나하나씩 초기화 하기 너무 많으니 아래와 같이 코딩

        foreach(Achive achive in achives)
        {
            PlayerPrefs.SetInt(achive.ToString(), 0);
        }
    }

    void Start()
    {
        UnlockCharacter();
    }

    void UnlockCharacter()
    {
        for(int index=0; index<lockCharacter.Length; index++)
        {
            string achiveName = achives[index].ToString();
            bool isUnlock = PlayerPrefs.GetInt(achiveName) == 1;
            lockCharacter[index].SetActive(!isUnlock);
            unlockCharacter[index].SetActive(isUnlock);
        }
    }

    // Update is called once per frame
    void LateUpdate()
    {
        foreach( Achive achive in achives)
        {
            CheckAchive(achive);
        }
    }

    void CheckAchive(Achive achive)
    {
        bool isAchive = false;

        switch (achive)
        {
            case Achive.UnlockPotato:
                isAchive = GameManager.instance.kill >= 10;
                break;

            case Achive.UnlockBean:
                isAchive = GameManager.instance.gameTime == GameManager.instance.maxGameTime;
                break;
        }

        if (isAchive && PlayerPrefs.GetInt(achive.ToString()) == 0 ) {
            PlayerPrefs.SetInt(achive.ToString(), 1);

            // Notice 활성화 부분
            for(int index=0; index<uiNotice.transform.childCount; index++)
            {
                bool isActive = index == (int)achive;
                uiNotice.transform.GetChild(index).gameObject.SetActive(isActive);
            }
            StartCoroutine(NoticeRoutine());
        }
    }

    IEnumerator NoticeRoutine()
    {
        uiNotice.SetActive(true); // UI창 등장
        yield return wait; // 5초후
        uiNotice.SetActive(false); // UI창 제거
    }
    
}

 

 

 

Awake는 변수 초기화를 주로 작성하고

Start는 게임을 시작할 때 미리 준비해야할 동작을 실행하는 느낌이라 보시면 되겠습니다.

 

Start는 활성화 될 때마다 실행되기 때문에 변수 초기화를 여기에 넣으면 불필요하게 여러번 초기화 되는 경우가 있을 수 있고, Awake에 모든 준비로직을 담으면 미처 다른 오브젝트에서 컴포넌트가 준비되기도 전에 접근해버려서 에러가 발생하는 상황도 일어나기도 합니다.

'유니티' 카테고리의 다른 글

유니티 공부(17)  (0) 2023.11.02
유니티 공부(16)  (1) 2023.10.31
유니티 공부(14)  (0) 2023.10.25
유니티 공부(13)  (1) 2023.10.25
유니티 공부(12)  (0) 2023.10.20

관련글 더보기