새소식

C#,Unity Programming

게임개발 학습. Rise Up 카피 게임 만들기

  • -
728x90

 

// 게임개발종합반 2추자(스파르타코딩클럽)

// Rise Up 카피 게임 만들기

만들 게임에서 필요한 목표

  1. 다양한 크기의 상자가 떨어지도록 구현
  2. 마우스를 따라다니는 오브젝트가 상자들과 충돌하도록 구현
  3. 타이머 구현
  4. 지켜야 하는 풍선 구현( 색깔 변화, 터지는 애니메이션)

만들 순서

  1. 기본 씬 구성하기 - 배경, 풍선, 마우스, 네모, 시간
  2. 풍선 애니메이션 더하기
  3. 마우스 움직임 더하기
  4. 시간 가게 하기
  5. 네모 내려오게 하기 + 충돌 구현
  6. 게임 끝내기(1): 판넬 만들기
  7. 게임 끝내기(2): 베스트 스코어 기록하기
  8. 풍선 애니메이션 전환하기

  • 스프라이트 배치하다 layer 순서에서 막힘...
  • 레이어 order는 다 0 인데 왜 차별이지.. 답변오면 아래에 달아놓겠다

  • 답변 안와서 그냥 습관대로 작업 시작
    • sorting layers를 설정해두면 아래쪽레이어가 무조건 앞으로 배치된다.

풍선 애니메이션 추가하기

  • Animations 폴더 생성 - Balloon_idle 애니메이션 만들기
  • Balloon에 idle 애니메이션 할당하기
  • Animation Record 활용하여 색깔변화를 애니메이션으로 만들기
    • 키프레임 찍어서 스프라이트 컬러 조절 (255,255,255,255) / (200,200,255,255)
    • Inspector에서 Loop pose체크

마우스로 오브젝트(shield)의 위치를 조정하기

  • 오브젝트 위치에 마우스 위치를 넣어주기
public class Shield : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        transform.position = new Vector3(mousePos.x, mousePos.y, 0);
    }
}

박스 떨어지게 하기, 충돌 속성 넣기(복습)

  • 생성한 오브젝트에 Rigidbody 2d, box collider 2d 컴포넌트 추가

박스가 임의의 위치에 생성되도록

  • Random.Range사용
  • start 안에서 변수 선언하는걸 안좋아해서 x, y 범위 선언을 start  밖으로 빼봤는데, Error.
  • Range 는 Awake, Start 안에서 사용하는 걸로. 그래도 변수 선언은 밖에서 하고 싶으니 할당만 안에서. 
    • UnityException: Range is not allowed to be called from a MonoBehaviour constructor (or instance field initializer), call it in Awake or Start instead. Called from MonoBehaviour 'square'. See "Script Serialization" page in the Unity Manual for further details. square..ctor () (at Assets/Scripts/square.cs:7)
public class square : MonoBehaviour
{
    // square 위치 변수
    float x;
    float y;
    float size;

    // Start is called before the first frame update
    void Start()
    {
        x = Random.Range(-3.0f, 3.0f);
        y = Random.Range(3.0f, 5.0f);
        transform.position = new Vector3(x, y, 0);
        
        size = Random.Range(0.5f, 1.5f);
        transform.localScale = new Vector3(size, size, 0);
    }
}

박스 생성을 반복하도록

  • InvokeRepeating( method, 시간, 반복간격); Instantiate(gameObject); 기억하자
public class gameManager : MonoBehaviour
{
    public GameObject square;
    // Start is called before the first frame update
    void Start()
    {
        InvokeRepeating("makeSquare", 0.0f, 0.5f);
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    void makeSquare()
    {
        Instantiate(square);
    }
}

타이머 만들기

  • UI에서 텍스트 받기
  • 시간 변수 문자로 변환하여 N2로 전달
using UnityEngine.UI;
 // Timer 변수
    public Text timeTxt;
    private float alive = 0.0f;

    void Update()
    {
        // 시간이 흐르고 텍스트로 출력
        alive += Time.deltaTime;
        timeTxt.text = alive.ToString("N2");
    }

 

종료 판넬 만들기

  • 추가로 배운것
    • shadow 컴포넌트 - 그림자를 만들어줌
    • Button - Target Graphic 이미지 클릭 효과를 만들어줌

gameManager 싱글톤 처리(새로 인스턴스 안만들고 this를 부름)

public class gameManager : MonoBehaviour
{
    // 싱글톤 처리
    public static gameManager GM;

    private void Awake()
    {
        GM = this;
    }
}

 

종료 판넬 나타내기

  • 게임오버 함수 만들기
    // endPanel 변수
    public GameObject endPanel;
    
        public void gameOver()
    {
        Time.timeScale = 0.0f;
        endPanel.SetActive(true);
    }
  • square.cs 에서 충돌시 gameOver() 실행시키기
    • OnCollision2D임을 꼭 확인하자
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.tag == "balloon")
        {
            gameManager.GM.gameOver();
        }
    }

점수 나타내기

    // thisScoreTxt 변수
    public Text thisScoreTxt;
    
	public void gameOver()
    {
        Time.timeScale = 0.0f;
        endPanel.SetActive(true);

        // 현재점수넣기
        thisScoreTxt.text = alive.ToString("N2");
    }
  • Update 가 함수 호출보다 늦는 관계로 isRunning 불린을 넣어 타이밍을 맞춰준다
    // 실행 확인 함수
    bool isRunning = true;

    void Update()
    {
        if (isRunning)
        {
            // 시간이 흐르고 텍스트로 출력
            alive += Time.deltaTime;
            timeTxt.text = alive.ToString("N2");
        }
        
        
    }

    public void gameOver()
    {
        isRunning = false;
        Time.timeScale = 0.0f;
        endPanel.SetActive(true);

        // 현재점수넣기
        thisScoreTxt.text = alive.ToString("N2");
    }

다시하기 구현

  • 메인씬 새로고침 retry()
  • Start함수에서 timeScale 리셋하기(1.0f)
using UnityEngine.SceneManagement;

void retry()
    {
        SceneManager.LoadScene("MainScene");
    }
  • 버튼에 gameManager를 직접 할당하지 말고, retryBtn 스크립트에 함수 만들어서 간접적으로 가져온다
public class retryBtn : MonoBehaviour
{
    public void retry()
    {
        gameManager.GM.retry();
    }
}

최고점수 나타내기

  • playerPref 을 다시 떠올려보자
  • playerPref 에는 Key, Value 세트로 값을 저장
// 데이터 저장
PlayerPrefs.SetFloat("bestScore", 어떤숫자값);
PlayerPrefs.SetString("bestScore", 어떤문자열);

// 데이터 부르기
어떤숫자값 = PlayerPrefs.getFloat("bestScore");
어떤문자열 = PlayerPrefs.getString("bestScore");

// 데이터 있는지 확인(t/f)
PlayerPrefs.HasKey("bestScore")

// 데이터 삭제
PlayerPrefs.DeleteAll();
  • PlayerPref 에 최고점수 넣고 UI 에나타내기 구현
 // maxScoreTxt 변수
    public Text maxScoreTxt;
 
 public void gameOver()
    {
        isRunning = false;
        Time.timeScale = 0.0f;
        endPanel.SetActive(true);

        // 현재점수넣기
        thisScoreTxt.text = alive.ToString("N2");

        // bestScore 를 playerPref에 넣기
        if (PlayerPrefs.HasKey("bestScore") == false)
        {
            PlayerPrefs.SetFloat("bestScore", alive);
        }

        else
        {
            if (alive > PlayerPrefs.GetFloat("bestScore"))
            {
                PlayerPrefs.SetFloat("bestScore", alive);
            }
            
        }
        float maxScore = PlayerPrefs.GetFloat("bestScore");
        maxScoreTxt.text = maxScore.ToString("N2");
    }

풍선 애니메이션 전환하기

  • Balloon_die 애니메이션 레코딩 후
  • Animator에 추가
  • isDie 파라미터 추가 후, 트랜지션 Condition 에 할당
  • 죽음 애니메이션도 gameManager에서 실행
    • TimeScale이 0 이어서 애니메이션 실행 안됨.
    • 0.5.초 애니메이션 실행 후 죽을 수 있도록 수정
        // 애니메이터 실행
        anim.SetBool("isDie", true);
public void gameOver()
    {
        isRunning = false;

        // 애니메이터 실행
        anim.SetBool("isDie", true);

        Invoke("timeStop", 0.5f);
        ...생략
    }
    
public void timeStop()
    {
        Time.timeScale = 0.0f;

    }
Contents
  • -

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.