ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • (22) 스테이지 클리어 조건 & 클리어 씬 제작
    Galaxy Ball/2. 싱글플레이 - 스토리모드 2024. 6. 4. 16:57

    클리어 조건을 만들기전에 클리어 씬부터 제작하겠다

     

    우선 구성은 InformationBox와 GalaxyBackGround로 구성되어 있는데

    GalaxyBackGround는 위에 보이는 우주 아이콘들,  InformationBox는 밑에 있는 알림창과 버튼들을 모두 포함하고 있다

     

    using UnityEngine;
    using UnityEngine.SceneManagement;
    using UnityEngine.UI;
    
    public class ClearSceneBtn : MonoBehaviour
    {
        public Button button1;
        public Button button2;
        void Start()
        {
            this.button1.onClick.AddListener(() =>
            {
                SceneManager.LoadScene("Stage");
            });
            this.button2.onClick.AddListener(() =>
            {
                SceneManager.LoadScene("Stage");
            });
        }
    }

     

     

    당연히 버튼의 기능을 구현해야하니 스크립트를 하나 추가했다. 

    기능은 우선 버튼 두개중 무엇을 누르던 Stage씬으로 돌아가게 해주었고 원래는 여기에 

    어떤 버튼을 누르느냐에 따라서 변수 두개를 만들어 하나씩 정보를 저장한뒤 게임 마지막에

    각 버튼을 선택한 횟수를 보여주려고 했는데 아직 확정난 사항이 아니라서 우선은 여기서 보류하겠다

     

    한가지 더 추가해서 화면에 스테이지 클리어라는 문구를 적어주고 싶은데 설명란 위에 적기엔

    설명란 칸이 줄어들고, 위에 달랑 텍스트만 적자니 너무 밋밋하다

     

    그래서 이번에도 꾸준히 컨셉에 맞춰 오브젝트 칸에 콜라이더 입힌 구체를 만든뒤 

    Endless 아이템처럼 스스로 멈추지 않고 계속해서 이동시키려고 한다

     

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class ClearBall : MonoBehaviour
    {
        private Rigidbody2D rb;
        private Vector2 lastVelocity;
    
        void Start()
        {
            float x = Random.Range(1, 5);
            float y = Random.Range(1, 5);
            rb = GetComponent<Rigidbody2D>();
            rb.gravityScale = 0;
            rb.velocity = new Vector2(x,y) * 5;
        }
    
        void FixedUpdate()
        {
            lastVelocity = rb.velocity;
        }
    
        void OnCollisionEnter2D(Collision2D collision)
        {
            Vector2 normal = collision.contacts[0].normal;
            Vector2 reflectDirection = Vector2.Reflect(lastVelocity.normalized, normal);
    
            rb.velocity = reflectDirection * 5;
        }
    }

     

    하지만 코드는 Endless와 살짝 다르다

    큰 차이는 없고 맨 처음 시작하자마자 속도를 5로 초기화하여 바로 날리고 시작하는것

    방향 x,y축값을 랜덤으로 잡아 날려준다는것

     

    그리고 구체 오브젝트 밑에 빈오브젝트를 하나 더 만들어주고 이 안에 TextMeshPro - Text를 넣어

    텍스트를 입혀준다. 이러면 이제 구체를 따라 텍스트도 함께 이동할 것이다

     

     

    이번엔 밑에 들어갈 문구 출력을 구현해보자. 매번 스테이지를 깰때마다 우주에 관한 흥미로운 사실들을 출력할 예정이고

    당연히 스테이지마다 다른 문구가 나올텐데

    인터넷 사이트를 뒤져가며 총 55가지의 사실들을 정리해 엑셀로 저장했다

     

     

    그리고 이걸 Json 파일로 변형해 Resources 폴더에 넣어주었다

    이제 json 파일안에 있는 id값에 따라 출력되는 문구가 각각 다르도록 스크립트를 작성해보겠다

     

    using UnityEngine;
    using Newtonsoft.Json;
    using TMPro;
    
    public class ShowInformationtxt : MonoBehaviour
    {
        public TextAsset JsonFile; // JSON 파일을 저장할 변수
        public TMP_Text informationText; // 정보를 출력할 TextMesh
    
        private void Start()
        {
            // 초기화할 때는 아무 정보도 출력하지 않도록 합니다.
            informationText.text = "";
        }
    
        private void Update()
        {
            UpdateStageInfo();
        }
    
        public void UpdateStageInfo()
        {
            string jsonString = JsonFile.text;
            Information[] stageInfos = JsonConvert.DeserializeObject<Information[]>(jsonString);
    
            int stageID = StageState.chooseStage;
    
            // stageID에 해당하는 String 가져오기
            string stageString = "";
            foreach (Information info in stageInfos)
            {
                if (info.id == stageID)
                {
                    stageString = info.String;
                    break;
                }
            }
    
            informationText.text = stageString;
        }
    }
    
    [System.Serializable]
    public class Information
    {
        public int id;
        public string String;
    }

     

    이번에도 chooseStage값을 StageState에서 받아와 Json 파일 id와 비교하여 출력하도록 했다

     

    위에서 새로 만든 Show Informationtxt 스크립트를 오브젝트 안에 집어넣고

    Json파일과 텍스트 오브젝트도 알맞게 부착해주자

     

     

    스테이지를 클리어하는 즉시 알맞는 텍스트와 함께 클리어씬이 보인다

    마지막으로 빌드세팅에서 Clear 씬을 등록해주기만 하면 씬 완성.

    Clear => Stage로 넘어가는 기능을 구현해주었으니 이번엔 Stage에서 Clear로 넘어가는 기능을 구현해주자

     

    사실 클리어 조건을 걸어주는것은 더더욱 간단하다. 새로 제작할 씬도 없고 코드만 몇줄 추가하면 되기 때문

     

     

    인게임에서 게임의 승패판정을 담당하는 SPGameManager 스크립트 마지막 부분이다

    여기에 태그가 "Enemy"인 게임 오브젝트를 찾아 만약 오브젝트의 수가 0과 같거나 적다면 Clear씬으로 넘어가게 해주었다

     

     

     

    총 정리된 요약본을 한번 보자. 이제 Stage <=> Fail <=> Clear 씬을 자유자재로 드나들수 있다

     

    게임을 하면 할수록 느끼는건데 Endless 아이템을 참 잘 만든것 같다. 

    밸런스를 위해 구체 12개 제한을 걸긴했지만 내심 이걸로 게임이 종료되길 원치 않아했었다

    그리고 이 문제를 Endless가 잘 잡아주니 참 좋은것 같다

     

    그리고 클리어씬과 승리조건까지 전부 만들었으니 한가지 더 할 수 있는게 있다

     

    바로 StageClearID 변수를 더해주어 스테이지를 연속해서 플레이 시켜주는것도 가능하다

     

    이제 승리조건을 만족해서 클리어씬으로 넘어가기전에 StageClearID에 1을 더해주어 

    스테이지 상태가 실시간으로 바뀔것이다

     

    근데 코드를 위처럼 짜면 한가지 문제점이 생긴다

    StageClearID에 1을 더하는 조건 = 스테이지 클리어

    이기 때문에 스테이지 1을 10번 중복해서 클리어하면 계속해서 변수값이 증가한다는것. 

    당연히 이를 방지하는 시스템이 필요하고 이건 조건문 하나로 간단하게 제어해보자

     

     

    StageClearID 즉. 현재까지 클리어한 스테이지 번호와 현재 진행중인 스테이지 번호가 같다면

    클리어시 StageClearID에 1을 더해주고 그게 아니라면 조건문을 건너뛴 뒤 씬만 변환시켜주었다

     

     

Designed by Tistory.