ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • (21) 클리어한 스테이지만 활성화★
    Galaxy Ball/2. 싱글플레이 - 스토리모드 2024. 6. 3. 17:55

    이번건 굉장히 중요한 기능임과 동시에 내가 연출 다음으로 어려워하고 있는 부분이기도 하다

    사실 아직 저장, 불러오기, 싱글톤에 대한 지식이 완벽하지 않기에 어려워하고 있는것이다

     

    이번글에서는 클리어한 스테이지 & 클리어할 차례가 된 스테이지는 활성화 시키고,

    클리어하지 못한 스테이지는 비활성화하도록 하겠다

    그리고 클리어 여부에 따라 구체의 색상도 바꿔보도록 하겠다

     

    지금은 튜토리얼 씬에 적용하는것이지만 한번 구현을 성공하게 되면 메인씬에 구현시키는것은 똑같은 원리이기에

    이번에 성공해보는것이 굉장히 중요하다

     

     

    우선 머릿속에 떠오르는걸 먼저 적어두고 구현을 시작해보겠다

     

    1. StageGameManager에 식별을 위한 StageClearID 만든뒤 1로 초기화

    (StageClearID는 싱글톤으로 씬을 변환해도 그 값이 초기화되지 않음)

    2. 모든 스테이지 구체에 StageState 스크립트 제작 후 부착

    (* StageState : 본인 스테이지보다 StageClearID가 낮다면 구체가 검정색이 된뒤 플레이버튼 비활성화)

    (만약 StageClearID가 높다면 색상을 파란색으로 변경, 같다면 빨간색으로 변경. 이 둘은 플레이버튼 활성화)

    3. 플레이어 공에 부착된 플레이 UI 띄우기 기능을 이제 스테이지 구체에 기능 옮겨주기

     

     

    자 그럼 한번 순서대로 구현해보자

     

     

    1. StageGameManager에 식별을 위한 StageClearID 만든뒤 1로 초기화

    (StageClearID는 싱글톤으로 씬을 변환해도 그 값이 초기화되지 않음)

    우선 싱글톤으로 StageClearID라는 변수를 StageGameManager에 추가해보자

     

    싱글톤 (Singleton Pattern)

    싱글톤 : 프로그래밍 디자인 패턴 중 추상 객체 인스턴스 생성 패턴중의 하나로  1. 게임 시스템에서 전체를 관장하는 스크립트(단일 시스템 자원 관리 차원)2. 게임 시스템상 전역 변수의 역

    sangeun00.tistory.com

    혹시라도 헷갈린다면 기본적인 싱글톤에 관한 정리글을 보고 참고하자

     

    public class StageGameManager : MonoBehaviour
    {
        public static StageGameManager instance = null;
        public int StageClearID;
    
        private Vector3 clickPosition;
        public bool isDragging = false;
        public static float shotDistance;
        public static Vector3 shotDirection;
    
        private void Awake()
        {
            if (instance == null) //instance가 null. 즉, 시스템상에 존재하고 있지 않을때
            {
                instance = this; //내자신을 instance로 넣어줍니다.
                DontDestroyOnLoad(gameObject); //OnLoad(씬이 로드 되었을때) 자신을 파괴하지 않고 유지
            }
            else
            {
                if (instance != this) //instance가 내가 아니라면 이미 instance가 하나 존재하고 있다는 의미
                    Destroy(this.gameObject); //둘 이상 존재하면 안되는 객체이니 방금 AWake된 자신을 삭제
            }
        }

     

    딱 int타입 변수 하나 추가하는것이기 때문에 별다른 특이사항은 없다

     

    2. 모든 스테이지 구체에 StageState 스크립트 제작 후 부착

    (* StageState : 본인 스테이지보다 StageClearID가 낮다면 구체가 검정색이 된뒤 플레이버튼 비활성화)

    (만약 StageClearID가 높다면 색상을 파란색으로 변경, 같다면 빨간색으로 변경. 이 둘은 플레이버튼 활성화)

     

    사실상 가장 중요한 단계. 

     

    이번에는 조건이 좀 까다롭기에 단계를 정하고, 그 단계에 따라 코드를 작성해보겠다

     

    1. 해당 스크립트가 부착된 오브젝트의 6번째 문자를 가져오기 ex) Stage'6' => 6

    2. StageClearID와 비교하여 6번째 문자가 크면 "Big", 같으면 "Same", 작으면 "Small" 출력

    3. 이제 그 문자출력에서 해당 오브젝트의 색상변경으로 기능을 변경

    4. 플레이 박스를 띄워주는 기능을 PlayerControl에서 Stage로 옮김

    5. 문자가 StageClearID보다 작거나 같으면 플레이버튼 활성화, 크면 비활성화

     

     

    1. 해당 스크립트가 부착된 오브젝트의 6번째 문자를 가져오기 ex) Stage'6' => 6

     

    using UnityEngine;
    
    public class StageState : MonoBehaviour
    {
        void Start()
        {
                char sixthChar = gameObject.name[5];
                Debug.Log("6번째 글자: " + sixthChar);
        }
    }

     

     

    2. StageClearID와 비교하여 6번째 문자가 크면 "Big", 같으면 "Same", 작으면 "Small" 출력

    public class StageState : MonoBehaviour
    {
        private StageGameManager gameManager;
    
        void Start()
        {
            int stagenum = int.Parse(gameObject.name[5].ToString()); gameManager = StageGameManager.instance;
            int stageClearID = gameManager.StageClearID;
    
            if(stageClearID < stagenum)
            {
                Debug.Log("big");
            }
            if (stageClearID == stagenum)
            {
                Debug.Log("same");
            }
            if (stageClearID > stagenum)
            {
                Debug.Log("small");
            }
        }
    }

     

     

    3. 이제 그 문자출력에서 해당 오브젝트의 색상변경으로 기능을 변경

    public class StageState : MonoBehaviour
    {
        private StageGameManager gameManager;
        private SpriteRenderer spriteRenderer;
    
        void Start()
        {
            int stagenum = int.Parse(gameObject.name[5].ToString());
            gameManager = StageGameManager.instance;
            int stageClearID = gameManager.StageClearID;
    
            spriteRenderer = GetComponent<SpriteRenderer>();
    
            if (stageClearID < stagenum)
            {
                Debug.Log("big");
                spriteRenderer.color = new Color32(73, 73, 73, 255);
            }
            else if (stageClearID == stagenum)
            {
                Debug.Log("same");
                spriteRenderer.color = new Color32(255, 61, 61, 255);
            }
            else
            {
                Debug.Log("small");
                spriteRenderer.color = new Color32(69, 155, 255, 255);
            }
        }
    }

     

     

    4. 플레이 박스를 띄워주는 기능을 PlayerControl에서 Stage로 옮김

    using UnityEngine;
    
    public class StageState : MonoBehaviour
    {
        public GameObject StageStart;
        public int stagenum;
        public static int chooseStage;
        private StageGameManager gameManager;
        private SpriteRenderer spriteRenderer;
    
        void Start()
        {
            this.stagenum = int.Parse(gameObject.name[5].ToString());
            gameManager = StageGameManager.instance;
            int stageClearID = gameManager.StageClearID;
    
            spriteRenderer = GetComponent<SpriteRenderer>();
    
            if (stageClearID < this.stagenum)
            {
                Debug.Log("big");
                spriteRenderer.color = new Color32(73, 73, 73, 255);
            }
            else if (stageClearID == this.stagenum)
            {
                Debug.Log("same");
                spriteRenderer.color = new Color32(255, 61, 61, 255);
            }
            else
            {
                Debug.Log("small");
                spriteRenderer.color = new Color32(69, 155, 255, 255);
            }
        }
    
        private void OnTriggerStay2D(Collider2D collision)
        {
            if (collision.gameObject.tag == "StageBall")
            {
                StageStart.gameObject.SetActive(true);
            }
            chooseStage = stagenum;
            Debug.Log(chooseStage);
            FindObjectOfType<ShowStageBox>().UpdateStageInfo(chooseStage);
        }
    
        private void OnTriggerExit2D(Collider2D collision)
        {
            if (collision.gameObject.tag == "StageBall")
                StageStart.gameObject.SetActive(false);
        }
    }
    using UnityEngine;
    using UnityEngine.SceneManagement;
    using UnityEngine.UI;
    
    public class StageGoBtn : MonoBehaviour
    {
        public Button GoBtn;
    
        private void Start()
        {
            this.GoBtn.onClick.AddListener(() =>
            {
                // 씬을 로드하기 전에 chooseStage 값을 저장
                GlobalData.SelectedStage = StageState.chooseStage; // 수정!!!
                SceneManager.LoadScene("Story-InGame");
            });
        }
    }
    
    public static class GlobalData
    {
        public static int SelectedStage;
    }

    추가로 플레이 버튼에 들어갈 StageGoBtn도 수정해줘야 한다

    내가 이걸 발견 못해서 하루종일...

     

     

     

     

    5. 문자가 StageClearID보다 작거나 같으면 플레이버튼 활성화, 크면 비활성화

     

    using UnityEngine;
    
    public class StageState : MonoBehaviour
    {
        public GameObject StageStart;
        public GameObject StartButton; //통제할 버튼 추가
        public int stagenum;
        public static int chooseStage;
        private bool isclear; //활성화/비활성화할 조건 추가
        private StageGameManager gameManager;
        private SpriteRenderer spriteRenderer;
    
        void Start()
        {
            this.stagenum = int.Parse(gameObject.name[5].ToString());
            gameManager = StageGameManager.instance;
            int stageClearID = gameManager.StageClearID;
    
            spriteRenderer = GetComponent<SpriteRenderer>();
    
            if (stageClearID < this.stagenum)
            {
                isclear = false; // 클리어한 스테이지보다 높은 경우
                spriteRenderer.color = new Color32(73, 73, 73, 255);
            }
            else if (stageClearID == this.stagenum)
            {
                isclear = true; // 나머지는 true
                spriteRenderer.color = new Color32(255, 61, 61, 255);
            }
            else
            {
                isclear = true;
                spriteRenderer.color = new Color32(69, 155, 255, 255);
            }
        }
    
        private void OnTriggerStay2D(Collider2D collision)
        {
            if (collision.gameObject.tag == "StageBall")
            {
                StageStart.gameObject.SetActive(true);
                if(!isclear)
                {
                    StartButton.gameObject.SetActive(false); // 버튼을 통제할 새로운 조건 추가
                }
            }
            chooseStage = stagenum;
            Debug.Log(chooseStage);
            FindObjectOfType<ShowStageBox>().UpdateStageInfo(chooseStage);
        }
    
        private void OnTriggerExit2D(Collider2D collision)
        {
            if (collision.gameObject.tag == "StageBall")
                StageStart.gameObject.SetActive(false);
        }
    }

    추가한 내용은 주석에 달아두었다

     

     

    하...드디어 끝났다. 

    1. StageGameManager에 식별을 위한 StageClearID 만든뒤 1로 초기화

    (StageClearID는 싱글톤으로 씬을 변환해도 그 값이 초기화되지 않음)

    2. 모든 스테이지 구체에 StageState 스크립트 제작 후 부착

    (* StageState : 본인 스테이지보다 StageClearID가 낮다면 구체가 검정색이 된뒤 플레이버튼 비활성화)

    (만약 StageClearID가 높다면 색상을 파란색으로 변경, 같다면 빨간색으로 변경. 이 둘은 플레이버튼 활성화)

    3. 플레이어 공에 부착된 플레이 UI 띄우기 기능을 이제 스테이지 구체에 기능 옮겨주기

     

    이 모든게 전부 성공적으로 구현되는것을 확인할 수 있다

    이제 남은건 스테이지 클리어 조건과 스테이지 클리어씬을 만들고

    하나하나 클리어할때마다 StageClearID에 1씩 더해주기만 하면 된다

     

    그리고 그거까지 마무리 된다면 이제 정말 스테이지만 열심히 Json으로 만들어주기만 하면 된다

     

Designed by Tistory.