ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • (2) 챌린지 모드 수정
    Galaxy Ball/3. 싱글플레이 - 챌린지모드 2024. 10. 25. 18:02

    챌린지 모드를 우선 구현이 되도록 만든뒤 정말 많은 시간이 지나고 나서 최적화라는것을 하게 되었고

    그 과정에서 꽤나 많은 변화들이 있었고, 챌린지 모드는 진행불가능한 상태가 되어버렸다

     

    이 참에 그냥 의미도 없어보이는 챌린지 모드를 아예 없애버릴까도 고민이 많았는데...

    단순히 챌린지의 의미를 넘어 언제든지 가볍게 게임을 연습할 수 있는 모드이기 때문에 다시 한번

    다듬어서 만들어보기로 했다

     

    우선 캔버스부터 정리해주자. 웬만하면 UI 요소들은 하나의 캔버스안에 넣어주는것이 가장 바람직하다

     

    이제 챌린지모드의 핵심이 될 챌린지공을 컨트롤하는 스크립트를 다시 짜보겠다. 

    사실 이게 챌린지모드의 핵심이자 전부이기도 하다

     

    using System.Collections;
    using System.Collections.Generic;
    using TMPro;
    using UnityEngine;
    
    public class ChBulletControl : MonoBehaviour
    {
    
       ....
       
        void TakeDamage(int damage)
        {
            durability -= damage;
            if (durability <= 0)
            {
                challengeGameManager.scorenum++;
                Destroy(gameObject);
            }
        }
    
       ....
       
    }

     

    우선 챌린지모드의 공을 컨트롤하는데 사용될 ChBulletControl이라는 스크립트를 새로 만들어주었다

    다른건 적 유닛의 총알을 움직이게 하는 코드와 똑같지만 차이점이라면 TakeDamage에서 공이 데미지를 받아

    파괴되기 직전 챌린지모드의 스코어를 1점 올려준다는 것이다

     

    이제 기본 총알 프리팹을 복사하여 ChBullet이라는 이름으로 하나의 프리팹을 더 만들어준뒤 

    지금짠 코드를 부착시켜주자.

    그리고 이제 스폰될 총알은 ChBullet이 대신한다

     

     

    그리고 한가지 더 만들어야하는게 있으니 바로 플레이어...!!

    만든지 하도 오래된 챌린지모드라서 그런지 플레이어가 싱글플레이어 들어가는 그 프리팹과 같은걸 쓰고 있었다

    당연히 싱글플레이용 플레이어는 SPGameManager와 값을 공유하고 있으니 ChGameManager를 사용하는 챌린지모드와

    연동이 될리가 없다. 그래서 챌린지 플레이어용 코드를 다시 짜주었다(코드는 생략)

     

     

     

    그리고 P1BallPrefab에는 방금 만들어준 ChBall이 들어간다

     

    우선 플레이어와 챌린지용 총알들은 정상적으로 잘 구현된다

     

    하지만 정말 오래전에 만든 모드답게 오류들이 하나둘씩 발견되니 하나씩 해결해보자

     

    우선 인게임에서 아이템을 사용하려니 나온 문제...

    이제야 생각났다. 챌린지모드에서도 아이템을 사용하려면 챌린지모드용

    아이템 프리팹과 그 안에 들어갈 코드들을 전부 새로 작성해줘야 한다...

     

    전에도 이걸 알고 챌린지모드용 아이템 폴더를 미리 만들어둔 상태였다

    하지만 이걸 하나더 만드는게 맞는건가라는 생각도 들고, 이름도 연습하기로 바꿀까 고민중이다

     

    -------------------------------------------------

     

    챌린지모드용 아이템은 빼기로했다. 아직 싱글플레이를 시작도 안했는데 챌린지모드부터 들어간 플레이어들에게

    혼동을 줄 수도 있고, 챌린지보다는 연습모드라고 이름을 짓는게 더 적합해 보이기도 한다

     

     

    이제부터 챌린지 모드 > 연습하기로 이름을 변경해주겠다

    물론 지금부터 아이템을 랜덤 생성해주는 Ch Random Generate는 필요없을 것이다

     

    연습모드의 데드라인을 관리하는 코드중 아이템에 관련된것들은 전부 지워주자

     

    자 이제 거의 모든게 다 정상적으로 작동하지만 한가지 문제가 남아있었다

     

    플레이어의 공이 데드라인에 닿을때마다, 정확히는 패배판정이 나야할때 이런 오류가 뜨며 패배씬으로 넘어가질 않는것

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    using static ChallengeGameManager;
    
    public class ChDeadzone : MonoBehaviour
    {
        ChBallControl chBallControl;
        ChallengeGameManager challengeGameManager;
    
        private void Start()
        {
            challengeGameManager = FindAnyObjectByType<ChallengeGameManager>();
            chBallControl = FindAnyObjectByType<ChBallControl>();
        }
        private void OnTriggerEnter2D(Collider2D collision)
        {
            if (collision.gameObject.tag == "P1ball")
            {
                if (chBallControl.isExpanding)   // 오류가 난 부분
                {
                    GameData.CurrentScore = challengeGameManager.scorenum;
                    SceneManager.LoadScene("ChallengeFail");
                }
            }
        }
    }

     

    주석에 걸어뒀듯이 저 부분에서 오류가 난다

    하지만 딱봐도 알 수 있었다. 데드라인은 충돌한 공에 부착된 ChBallControl 스크립트 속 isExpanding값을 가져와

    판단했어야 했는데 지금 이 코드는 게임을 시작하자마자 ChBallControl를 임의로 하나 찾게 만들고는 그 안에서

    값을 받아와 판단하고 있었으니 정상적으로 작동할리가 없었을것이다

     

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    using static ChallengeGameManager;
    
    public class ChDeadzone : MonoBehaviour
    {
        ChallengeGameManager challengeGameManager;
    
        private void Start()
        {
            challengeGameManager = FindAnyObjectByType<ChallengeGameManager>();
        }
    
        private void OnTriggerEnter2D(Collider2D collision)
        {
            if (collision.gameObject.CompareTag("P1ball"))
            {
                ChBallControl chBallControl = collision.GetComponent<ChBallControl>();
    
                if (!chBallControl.isExpanding)
                {
                    GameData.CurrentScore = challengeGameManager.scorenum;
                    SceneManager.LoadScene("ChallengeFail");
                }
            }
        }
    }

     

    그래서 변경해주었다. 다른거 없이 그냥 충돌이 일어날때마다 충돌한 오브젝트에서 ChBallControl 스크립트를 받아온다

     

    충돌할때마다 스크립트를 가져오니 성능에 지장이 갈것같을수도 있지만 

    어차피 게임 종료될때 딱 한번 실행되는거라 큰 지장이 없을것이다

     

     

    이제 게임오버도 정상적으로 잘 작동하는것을 확인할 수 있다

     

     

    아 그리고 좌측하단에 있었던 아이템 인벤토리도 이제 쓸데가 없으니 제거해주었다

     

    사실 플레이어가 아닌 총알들(빨강공)끼리 부딫힐때는 데미지가 서로 없게 해야하는거 아닌가라는 생각도 들었지만

    연습모드라고 자꾸 원래 게임과 룰이 달라지만 혼란만 야기할 것 같아 기존룰과 똑같이 가기로 했다

     

    지금은 난이도 밸런스가 시간이 지날수록 점점 총알 생성 속도주기가 짧아지는 형태지만

    이게 과연 어려울까 싶어 시간이 지날수록 총알의 내구도도 단단하게 만들어줄까 생각했었는데..

     

    직접해보니 생각보다 난이도가 이대로도 쉽지 않아 그냥 그대로 두는걸로 하겠다..

    using UnityEngine;
    
    public class BulletSpawn : MonoBehaviour
    {
        public GameObject[] bullets; 
        public float spawnInterval = 10f; 
        public float minimumSpawnInterval = 1f; 
        public float minForce = 1.7f; 
        public float maxForce = 7f;
    
        private BoxCollider2D backgroundCollider;
        private float timer;
    
        void Start()
        {
            GameObject background = GameObject.Find("BackGround");
            if (background != null)
            {
                backgroundCollider = background.GetComponent<BoxCollider2D>();
            }
    
            timer = spawnInterval;
        }
    
        void Update()
        {
            timer -= Time.deltaTime;
    
            if (timer <= 0f)
            {
                SpawnBullet();
                spawnInterval = Mathf.Max(minimumSpawnInterval, spawnInterval - 0.2f);
                timer = spawnInterval; 
            }
        }
    
        void SpawnBullet()
        {
            float x = Random.Range(backgroundCollider.bounds.min.x, backgroundCollider.bounds.max.x);
            float y = Random.Range(backgroundCollider.bounds.min.y, backgroundCollider.bounds.max.y);
            Vector2 spawnPosition = new Vector2(x, y);
    
            int randomIndex = Random.Range(0, bullets.Length);
            GameObject bulletPrefab = bullets[randomIndex];
    
            GameObject bullet = Instantiate(bulletPrefab, spawnPosition, Quaternion.identity);
    
            Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
            if (rb != null)
            {
                Vector2 forceDirection = Random.insideUnitCircle.normalized;
                float forceMagnitude = Random.Range(minForce, maxForce);
                rb.AddForce(forceDirection * forceMagnitude, ForceMode2D.Impulse);
            }
        }
    }

     

    'Galaxy Ball > 3. 싱글플레이 - 챌린지모드' 카테고리의 다른 글

    (1) 챌린지 모드 제작  (0) 2024.06.24
Designed by Tistory.