TIL

2023/12/06 TIL

미역제자 2023. 12. 6. 21:00


내일이 프로젝트 발표일이기 때문에 쫒기듯 마무리를 했다.

 

우리 팀의 프로젝트는 벽돌깨기이다. 

또한 벽돌깨기는 한 스테이지로 끝나는게 아니라 여러 스테이지로 진행된다.

따라서 씬이 넘어가도 중요한 정보들을 가지고 갈 오브젝트를 만들고자 했다.

그래서 GameManager를 싱글톤으로 만든 뒤, DontDestroyOnLoad를 넣어서 다음 씬까지 연결되도록 만들었다.

using System.Collections;
using System.Collections.Generic;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;

public class GameManager : MonoBehaviour
{
    public static GameManager I;

    [Header("Ball")]
    public GameObject m_ball;
    public int ball_Damage;

    [Header("Paddle")]
    public Paddle m_playerPaddle;
    public GameObject Player1Paddle;
    public GameObject Player2Paddle;

    [Header("LimitTime")]
    public float limitTime_stage;

    [Header("Life")]
    public int playerLife;
    public int totalBrick;
    public int destroyBrickNum;

    [Header("Passive")]
    public GameObject getPassivePanel;
    public Button PassiveBtn1;
    public Button PassiveBtn2;
    public Button PassiveBtn3;
    public Text passiveText1;
    public Text passiveText2;
    public Text passiveText3;
    public int lv1 = 0;
    public int lv2 = 0;
    public int lv3 = 0;

    private StartBtn IsDuo = new StartBtn();

    [Header("Boss")]
    public GameObject boss01;
    public float bossHP;

    [Header("GameState")]
    public bool oneLifeLose;

    public int gameLevel = 1;
    public int gamePlayer = 1;
    public int ballCount;

    private void Awake() //싱글톤
    {
        if (I != null) 
        {
            Destroy(gameObject);
            return;
        }
        I = this; 
        DontDestroyOnLoad(gameObject); //Scene이 바뀌어도 파괴가 안되도록
    }

    private void Start() 
    {
        if(IsDuo.isDuo == true) //듀오일때
        { 
            Player2Paddle.SetActive(true); //player 2 액티브.
        }
        else
        {
            Player2Paddle.SetActive(false);
        }
        CreatBall();
    }

    public void CreatBall() //시작 시 패시브 레벨+1만큼 볼 생성.
    {
        for (int i = 0; i < lv1 + 1; i++) 
        {
            BallAdd();
        }
    }

    public void BallAdd() 
    {
        ballCount++;
        Instantiate(m_ball);
    }

    public void BallDead()
    {
        //라이프 포인트 -1
        ballCount--;
        if(ballCount < 1)
        {
            ResetLife();
        }
    }

    public void ResetLife()
    {
        oneLifeLose = true;
    }

    public void IsLevelOver()
    {
        Debug.Log("게임 매니저까지는 옴");
        if (destroyBrickNum == 10) // 아이템 획득 기준점을 10개로 잡음. 수정가능.
        {
            Debug.Log("아이템 획득");

            destroyBrickNum -= 10;
        }
    }
}

 

하지만 이렇게 만드니 씬이 넘어갈 때마다 GameManager에 넣어둔 오브젝트들이 초기화가 되는 오류가 발생했다.

거의 대부분의 오류가 이 부분에서 발생했다.

그래서 오류를 해결하고자 GameManager들에 넣어둔 오브젝트들 역시 DontDestroyOnLoad로 만들고 같이 이동하도록 만들었다. 하지만 이 역시 비효율적이라는 생각이 들었다.

그래서 팀원들과 상의해본 결과 스테이지를 난이도에 따라 블록 갯수만 달라지게 만들고 하나의 씬으로 만들기로 했다.

또한, 중요한 정보들은 PlayerPrefs를 이용해서 저장해두고 사용하기로 했다.

using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;

public class GameManager : MonoBehaviour
{
    public static GameManager I;

    [Header("Ball")]
    public GameObject m_ball;
    public int ball_Damage;

    [Header("Paddle")]
    public Paddle m_playerPaddle;
    public GameObject Player1Paddle;
    public GameObject Player2Paddle;


    [Header("LimitTime")]
    public float limitTime_stage;

    [Header("Life")]
    public int playerLife;
    public int totalBrick;
    public int destroyBrickNum;

    [Header("Passive")]
    public GameObject getPassivePanel;
    public Button PassiveBtn1;
    public Button PassiveBtn2;
    public Button PassiveBtn3;
    public Text passiveText1;
    public Text passiveText2;
    public Text passiveText3;
    public int lv1 = 0;
    public int lv2 = 0;
    public int lv3 = 0;
    //게임 시작 버튼에 초기화 필요

    public int Stage = 0;

    [Header("Boss")]
    public GameObject boss01;
    public float bossHP;
    public float bossDropItemPercent;

    [Header("GameState")]
    public bool oneLifeLose;

    public int gameLevel = 1;
    public int gamePlayer = 1;
    public int ballCount;

    private void Awake() //싱글톤
    {        
        I = this;   
    }

    private void Start() 
    {
        if (PlayerPrefs.HasKey("Stage"))
        {
            Stage = PlayerPrefs.GetInt("Stage");
        }
        CreatBall();
        SetBallSpeed();
    }

    private void SetBallSpeed()
    {
        Ball[] balls = FindObjectsOfType<Ball>();
        if (PlayerPrefs.HasKey("PassiveBallSpeed"))
        {
            foreach (Ball ball in balls)
            {
                if (ball != null)
                {   //레벨 업 하면 볼들의 스피드 5씩 증가.
                    ball.m_speed += (5 * PlayerPrefs.GetInt("PassiveBallSpeed")); 
                }
            }
        }
    }

    public void CreatBall() //시작 시 패시브 레벨+1만큼 볼 생성.
    {
        if(PlayerPrefs.HasKey("PassiveBall"))
        {
            for (int i = 0; i < PlayerPrefs.GetInt("PassiveBall") + 1; i++)
            {
                BallAdd();
            }
        }
        else
        {
            BallAdd();
        }
    }

    public void BallAdd() 
    {
        ballCount++;
        Instantiate(m_ball);
    }

    public void BallDead()
    {
        //라이프 포인트 -1
        ballCount--;
        if(ballCount < 1)
        {
            ResetLife();
        }
    }

    public void ResetLife()
    {
        oneLifeLose = true;
    }

    public void IsLevelOver()
    {
        Debug.Log("게임 매니저까지는 옴");
        if (destroyBrickNum == 10) // 아이템 획득 기준점을 10개로 잡음. 수정가능.
        {
            Debug.Log("아이템 획득");

            destroyBrickNum -= 10;
        }
    }
}

 

어찌저찌 수정하다 보니 느껴지는게 게임을 만들 때 초반에 설계를 잘 짜야지 게임 만들기 편해진다는 것이였다. 중간에 팀원들의 의견이 갈리는 부분들이 많아서 게임을 몇번 뜯어고쳤는데 그때마다 더 느껴진것 같다.