김김김의 게임개발
  • Unity 게임 개발 #3 - 풍선 지키기 게임<myShield>
    2023년 07월 28일 20시 17분 56초에 업로드 된 글입니다.
    작성자: noun06

    유니티를 사용하여 개발한 풍선 지키기 게임입니다.


    1. 기본 씬 세팅

    • 배경, 풍선, 실드,시간 UI 생성 후 위치, 크기, 색상 설정.

     

    2. 애니메이션 세팅

    • balloon_idle 풍선 기본 모션, loop time 체크.
    • 레코드 후 초 마다 색상 변경하여 애니메이션 제작.

     

    3. 마우스 포인터 따라 이동

    • 플레이어인 shield의 마우스 포인터 이동 제어.
    • mousePos(마우스의 좌표계)를 Camera.main 함수를 사용하여 카메라 좌표계로 변경 후 shield의 위치 넣기.

    • ScreenToWorldPoint : 카메라가 비추고 있는 화면 내의 좌표값을 사용할 수 있게 해줌.

    //shield.cs
    
    void Update()
    {
        Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        transform.position = new Vector3(mousePos.x, mousePos.y, 0);
    }

     

    4. 낙하하는 적 생성

    • 적 오브젝트에 Rigidbody 2d, Collider를 적용하여 중력 및 충돌효과 주기.
    • 무작위 위치 및 사이즈로 오브젝트 생성.
    //square.cs
    
    void Start()
    {
        float x = Random.Range(-3f, 3f);
        float y = Random.Range(3f, 5f);
    
        transform.position = new Vector3(x, y, 0);
    
        float size = Random.Range(0.5f, 1.5f);
        transform.localScale = new Vector3(size, size, 0);
    }

     

    • InvokeRepeating 함수를 사용하여 0.5초 마다 적을 생성하는 makeSquare() 함수 실행.
    //gameManager.cs
    
    void Start()
    {
        InvokeRepeating("makeSquare", 0.0f, 0.5f);
    }
        
    void makeSquare()
    {
        Instantiate(square);
    }

     

    5. 시간 증가 타이머

    • 현재 시간을 나타내는 alive 변수 선언 후 deltatime를 증가시켜 타이머 생성.
     //gameManager.cs
     
    public Text timeTxt;
    float alive = 0f;
        
    void Update()
    {
    	alive += Time.deltaTime;
    	timeTxt.text = alive.ToString("N2"); //시간 UI와 연동
    }

     

    6. 게임 종료 및 재시작

    • 게임 종료 판넬 UI 제작 후 비활성화

     

    • gameManager 싱글톤 처리를 통해 하나뿐인 인스턴스가 전역 접근이 가능하게 세팅
    //gameManager.cs
    
    public static gameManager I;
    
    void Awake()
    {
        I = this;
    }

     

    • public 변수 endPanel이 gameOver()함수가 실행되었을 때 활성화.
    • gameOver() 함수가 실행되었을 때 timeScaled을 0.0f로 세팅.
    //gameManager.cs
    
    public GameObject endPanel;
    
    public void gameOver()
    {
    	Time.timeScale = 0.0f;
    	endPanel.SetActive(true);
    }

     

    • OncollisionEnter 함수를 사용하여 "balloon" 태그인 오브젝트와 충돌하였을 때 gameOver() 함수 실행.
    //square.cs
    
    private void OnCollisionEnter2D(Collision2D collision)
    {
    	if (collision.gameObject.tag == "balloon")
    	{
    		gameManager.I.gameOver();
    	}
    }

     

    • 현재 스코어 변수가 현재 시간인 alive 값과 동일하게 하고 함수 실행 시 나타나게 하기.
    //gameManager.cs
    
    public Text thisScoreText;
    
    public void gameOver()
    {
    	Time.timeScale = 0.0f;
    	thisScoreText.text = alive.ToString("N2");
    	endPanel.SetActive(true);
    }

     

    • Update()함수와 gameOver()함수 간의 시간차 제어.
    • bool 변수 isRunning이 true일 경우 시간 계속 증가.
    • gameOver()이 호출될 때 isRunning = false로 설정.
    //gameManager.cs
    
    bool is Running = true;
    
    void Update()
    {
    	if (isRunning)
    	{
    		alive +=Time.deltaTime;
    		timeText.text = alive.ToString("N2");
    	}
    }
    
    public void gameOver()
    {
    	isRunning = false;
    	//...
    }

     

    • Start() 에서의 시간값을 1.0f로 세팅.
    • 다시하기 버튼에 메인 씬을 로드하는 retry()함수 세팅.
    //gameManager.cs
    
    using UnityEngine.SceneManagement;
    
    void Start()
    {
    	Time.timeScale = 1.0f;
    	//...
    }
    
    public void retry()
    {
    	SceneManager.LoadScene("MainScene");
    }

     

    7. 최고 점수 나타내기

    • Haskey 확인 시 bestScore 값이 없을 때, bestScore 값을 현재 점수인 alive 값으로 설정.
    • bestScore 값이 존재하고 만약 alive 값이 기존 bestScore보다 크다면 alive 값을 bestScore로 설정.
    • UI 오브젝트 변수 bestScoreText를 bestScore값으로 나타내기.

    • PlayerPrefs 클래스는 데이터의 저장, 불러오기, 삭제 등에 사용됨. 간단하지만 보안이 취약하다는 단점 존재.
    • DeleteAll : 모든 키 값을 삭제
    • DeleteKey : 특정 키 값을 삭제
    • HasKey : 해당 키가 존재하는 여부를 반환(true/false)
    • Save : 변경된 모든 키 값을 물리적 저장공간에 저장
    • GetFloat : 지정한 float 타입 키 값 불러오기
    • GetInt : 지정한 int 타입 키 값 불러오기
    • GetString : 지정한 string 타입 키 값 불러오기
    • SetFloat : 지정한 float 타입 키 값 저장
    • SetInt : 지정한 int 타입 키 값 저장
    • SetString : 지정한 string 타입 키 값 저장

    //gameManager.cs
    
    public Text bestScoreText;
    
    public void gameOver()
        {
            //...
            if (PlayerPrefs.HasKey("bestscore") ==  false)
            {
                PlayerPrefs.SetFloat("bestscore", alive);
            }
            else
            {
                if(alive > PlayerPrefs.GetFloat("bestscore"))
                {
                    PlayerPrefs.SetFloat("bestscore", alive);
                }
            }
            float bestScore = PlayerPrefs.GetFloat("bestscore");
            bestScoreText.text = bestScore.ToString("N2");
    
        }

     

    8. 게임 오버 풍선 애니메이션

    • balloon_die 애니메이션 만들고 레코드하여 새 클립 생성.
    • balloon animator 에서 bool 형식의 isDie 파라미터 생성 후 balloon_idle 에서 balloon_die로 transition 만들기.
    • has exit time 체크 해제하여 애니메이션 즉시 전환.

     

    • public 변수 anim 선언 후  gameOver() 함수 실행 시 isDie 파라미터가 true로 되게 하기.
    • Invoke 함수를 사용하여 0.5초 후에 timeStop() 함수 실행(애니메이션이 실행되는 틈을 주기 위해 사용).
    //gameManager.cs
    
    public Animator anim;
    
    public void gameOver()
    {
    	anim.SetBool("isDie", true);
    	Invoke("timeStop", 0.5f);
    	//...
    }
    
    void timeStop()
    {
    	Time.timeScale = 0.0f;
    }

     

    9. 적이 화면 밖으로 나갔을 시 파괴

    • 적 오브젝트의 position 값이 -5.0f 보다 작아서 화면 밖으로 나갔을 시 사라지게 하기.
    //square.cs
    
    void Update()
    {
    	if (transform.position.y < -5.0f)
    	{
    		Destroy(gameObject);
    	}
    }

     

    10. 결과물

     

     

    댓글