Unity Study (3)

happykuma·2023년 4월 7일
0
post-thumbnail

2주차 실습의 주제는 "풍선을 지켜라" 이다.

  • 순서
    1. 기본 씬 구성 - 배경, 풍선, 마우스, 네모, 시간
    2. 풍선 애니메이션
    3. 마우스 움직임
    4. 시간 흐르게 하기
    5. 네모 내려오게 하기 + 충돌 구현
    6. 게임 끝내기(1) : 판넬 만들기
    7. 게임 끝내기(2) : 최고 점수 기록
    8. 풍선 애니메이션 전환



프로젝트 세팅

배경, 풍선, 쉴드 만들기

  • 1주차와 동일하게 2D Object -> Sprites -> Square / Circle
  • 배경 위에 올라오도록 다른 요소들의 Order in Layer 맞춰주기

타이머 만들기

  • Canvas 생성 -> Canvas 하위에 Text 생성



풍선 애니메이션 만들기

애니메이션 추가

  • balloon_idle 생성 -> 0.20에 색상 지정해주기



마우스 만들기

마우스가 움직이게 하기

  • shield script 생성
    • ScreenToWorldPoint로 마우스의 위치를 받아온다.
    void Update()
      {
          Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
          transform.position = new Vector3(mousePos.x, mousePos.y, 0);
      }



네모 만들기

하늘에서 내려오게 하기

  • square 생성 -> position x:0, y:3
  • rigidbody, collider 속성 추가

풍선, 마우스에도 충돌 효과 적용

  • 각각 collider 추가

랜덤한 위치에 네모 생성하기

  • GameManager 생성
  • square script 수정
    void Start()
     {
        float x = Random.Range(-3f, 3f);
        float y = Random.Range(3f, 5f);
        transform.position = new Vector3(x, y, 0);
     }

네모 사이즈 랜덤하게 생성하기

  • square script 수정
    void Start()
    {
    		float size = Random.Range(0.03f, 0.1f);        
        transform.localScale = new Vector3(size, size, 0); 
    }

GameManager에서 Square 생성하기

  • square 오브젝트 prefab으로 만들기

  • GameManager script로 가져오기

    public GameObject square;
    
     void Start()
     {
     	InvokeRepeating("makeSquare", 0.0f, 0.3f);  // ("함수 이름", 몇 초 후에 실행시켜라, 몇초마다)
     }
      
     void makeSquare()
     {
     	Instantiate(square);
     }



시간 흐르게 하기

시간 올라가게 하기

  • GameManager로 UI Text 받아와서 갱신하기

    using UnityEngine.UI;
    
    public Text timeText;
    float alive = 0f;
    
    void Update()
    {
    	alive += Time.deltaTime;
      	timeText.text = alive.ToString("N2");
    }



게임 끝내기

판넬 만들기

  • Canvas -> endPanel -> Image 생성
    • Image에 shadow Component 추가해서 그림자 효과 주기
    • Distance를 조절해야 그림자가 보인다!
  • endPanel 하위에 Text 1개, Canvas 3개 생성
  • retryBtn -> Image에 Button Component 추가
    • Target Graphic에 Image 드래그 해오기
      Target Graphic : 마우스를 가져갔을 때 색 변화를 줘서 clickable 한지 알 수 있도록 함
  • endPanel은 inactive하게 만들기

판넬 보여주기

  • GameManager Singleton 처리

    public static GameManager I;
    
     private void Awake()
     {
         I = this;   // 싱글톤 처리
     }
  • GameManager에 게임 종료 함수 만들기

     public GameObject endPanel;
     
     public void gameOver()
      {
      	Time.timeScale = 0.0f;
        endPanel.SetActive(true);
      }
  • balloon과 square 충돌 시 종료하게 만들기

    • balloon에 tab 추가
    • square script
      private void OnCollisionEnter2D(Collision2D collision)
       {
      		if (collision.gameObject.tag == "geguri")
      	  	{
      		  	GameManager.I.gameOver();
          	}
       }

점수 보여주기

  • GameManager에서 thisScoreText 갱신

    public Text thisScoreText;
    
    public void gameOver()
    {
    	...    
    	thisScoreText.text = alive.ToString("N2");    
      	...
    }
  • 경과한 시간과 기록이 다른 이유

    • balloon과 square가 만나는 순간, square는 GameManager를 호출

    • GameManager는 그 순간의 시간을 보고 thisScoreText에 적음 -> 이 순간에도 Update는 계속 실행되고 있다!

    • 해결 방법 : bool 변수로 게임 종료 시 update도 실행되지 않도록 한다

      bool isRunning = true;
      
       void Update()
       {
          if (isRunning)
          {
              alive += Time.deltaTime;
              timeText.text = alive.ToString("N2");
          }        
       }
       
       public void gameOver()
       {
          isRunning = false;       
          ...
       }



게임 재시작하기

재시작 함수 만들기

  • GameManager script에 retry() 추가

    using UnityEngine.SceneManagement;
    
     public void retry()
     {
         SceneManager.LoadScene("MainScene");
     }

시간 재설정하기

  • timeScale 값 조정
    void Start()
    {
    	Time.timeScale = 1f;
      	...
    }

버튼 클릭 시 재시작하게 만들기

  • retryBtn의 OnClick에 gameManager 가져오기



최고 점수 보여주기

데이터 보관하기

  • PlayerPrefs : 앱을 껐다 켜도 데이터가 유지되도록 한다. 유니티에서 데이터를 보관하는 방법!
  • 데이터 저장
    PlayerPrefs.SetFloat("bestScore", 숫자값);
    PlayerPrefs.SetString("bestScore", 문자열);
  • 데이터 불러오기
    숫자값 = PlayerPrefs.GetFloat("bestScore";
    문자열 = PlayerPrefs.GetString("bestScore");
  • 데이터 저장 여부 확인
    • 있으면 true, 없으면 false 반환
    PlayerPrefs.HasKey("bestScore");
  • 데이터 지우기
    PlayerPrefs.DeleteAll();

최고 점수 보여주기 구현

  • GameManager script

    public Text maxScoreText;
    
     public void gameOver()
     {
      	...
         if (PlayerPrefs.HasKey("bestScore") == false)
         {
             PlayerPrefs.SetFloat("bestScore", alive);
         } else
         {
             if (alive > PlayerPrefs.GetFloat("bestScore"))
             {
                 PlayerPrefs.SetFloat("bestScore", alive);
             }
         }
         float maxScore = PlayerPrefs.GetFloat("bestScore");
         maxScoreText.text = maxScore.ToString("N2");
     }



풍선 애니메이션 전환하기

풍선 애니메이션 추가

  • balloon_die 추가
    • 풍선이 커지면서 터지는 것처럼 만들기
  • balloon animation controller
    • balloon_idle 우클릭 -> Make Transition -> balloon_die로 연결
    • Parameters에서 bool 변수 isDie 추가
    • transition 화살표 클릭 -> Inspector의 Conditions에서 isDie - true로 설정

풍선이 터질 때 애니메이션 전환하기

  • GameManager에서 isDie 값 갱신해주기

    public Animator anim;
    
     public void gameOver()
     {
     	...
        anim.SetBool("isDie", true);
      	...
     }
  • 애니메이션이 실행할 시간을 줄 수 있도록 timeScale 값 변경 전에 지연 주기

    public void gameOver()
     {
     	...
      	Invoke("timeStop", 0.5f);   // 0.5초 후에 timeStop 함수를 실행시켜라
     }
     
     void timeStop()
     {
     	Time.timeScale = 0f;
     }



완성된 모습!

profile
난 행복한 고구마야 - ̗̀ෆ⎛˶'ᵕ'˶ ⎞ෆ ̖́-

0개의 댓글