8. 세 번째 연습 게임

이규성·2023년 10월 30일
0

TIL

목록 보기
10/106

10/30 예제 연습

목표 예제

고양이에게 밥을 줘서 생선가게를 지키는 게임 !

  • 기본 화면 구성
  • MainCamera - size 25로 수정 - 색 FFF0B2로 수정

  • 이번 예제는 디자이너가 만들어준 이미지를 사용한다.
  • 2D object - sprite - square 생성 후 sprite에 알맞은 이미지를 넣어준다.

  • Assets - Scenes - StartScene 생성 후 편집
  • 알맞은 이미지를 넣어준다.

using UnityEngine.SceneManagement;

public void GameStart()
{
    SceneManager.LoadScene("MainScene"); // MainScene을 로드한다.
}
  • startBtn.cs 생성 후 코드 작성
  • onclick 설정

작동이 된다 !

  • sprite - circle 추가 후 sprite 탭의 속성을 knob로 수정

void Update()
{                              // y 방향으로 0.5씩 상승
    transform.position += new Vector3(0.0f, 0.5f, 0.0f);
}
  • food.cs 생성 후 코드 추가
  • preFab화 !

public GameObject food;
public GameObject dog;

void Start()
{                 // makefood 함수를 0.2초 마다 실행
    InvokeRepeating("makeFood", 0.0f, 0.2f);
}

void makeFood()
{
    float x = dog.transform.position.x; // x의 위치는 dog와 같게
    float y = dog.transform.position.y + 2.0f; // y의 위치는 dog 위로 2 높은 곳에서
    Instantiate(food, new Vector3(x,y,0), Quaternion.identity);
}   // 반복하여 생성한다.                  // 3D에서 회전값을 정의, 지금은 2D이니 없음
  • gameManager 생성 후 코드 추가
  • food, dog를 연결시켜준다.
void Update()
{
    transform.position += new Vector3(0.0f, 0.05f, 0.0f); // food의 y 이동값을 느리게 조정
    if (transform.position.y > 26.0f) // food의 y값이 26을 넘어가면 삭제한다.
    {
        Destroy(gameObject);
    }
}
  • food.cs 코드를 수정
// 마우스의 움직임에 따라 dog 오브젝트를 움직이게 하기

void Update()
{
    Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    // 마우스의 움직임 값을 가져온다.
    float x = mousePos.x;
    if (x > 8.5f) // dog의 x값을 fishshop 안쪽으로 제한한다.
    {
        x = 8.5f;
    }
    if (x < -8.5f)
    {
        x = -8.5f;
    }
    transform.position = new Vector3(x, transform.position.y, 0);
    // y값은 dog의 y값 그대로 사용한다.
}
  • dog.cs 생성 후 코드 추가

결과물 !

  • hungry 하위에 UI - image 생성 후 Canvas의 내용을 수정
  • position은 hungry -4에 고정
  • Render Mode를 world Space로 설정해야 UI가 아닌 게임 오브젝트로 사용 가능함 !

  • 체력 게이지로 사용할 sprite를 적절히 위치시켜준다.
  • front - Pivot값이 초기엔 0.5인데 scale 조정 시 중간에서부터 작아지게 된다. 값을 0으로 하여 좌측을 기준으로 수정

  • Animation 생성 후 looptime 체크

  • Animation 더블 클릭 - 하이라키의 normalCat 선택 - 녹화 버튼 누른 후 10초에 hungry의 sprite 이미지 변경 - 20초에 원래 이미지로 변경

결과물 !

  • alt+d로 fatCat 생성 후 이미지를 알맞게 수정
  • energy를 새로운 이미지에 맞게 위치 수정
  • 기존의 Animation 삭제 후 새로 만들어서 적용

  • preFab화 !
void Start()
{
    float x = Random.Range(-8.5f, 8.5f); // -8.5~8.5 사이의 랜덤한 값
    float y = 30.0f;                    // y값는 30 고정
    transform.position = new Vector3(x, y, 0);
}

// Update is called once per frame
void Update()
{
    transform.position += new Vector3(0.0f, -0.05f, 0.0f); // y-0.05로 계속해서 내려간다.
}
  • cat.cs 생성 후 코드 추가

  • food에 tag 추가
  • rigidbody 2D 추가 후 중력의 영향을 받지 않기 위해 Kinematic으로 속성 수정
  • circle collider 2D 추가 후 isTrigger 체크하여 충돌감지 설정

  • normalCat에 box collider 2D 추가 후 size 알맞게 수정
void OnTriggerEnter2D(Collider2D coll) 
{
    if (coll.gameObject.tag == "food") // tag가 food인 오브젝트와 충돌 시 아래 함수 실행
    {
        Debug.Log("맞았다!");
    }
}
  • cat.cs에 코드를 추가하여 충돌 구현
float full = 5.0f;
float energy = 0.0f;

void OnTriggerEnter2D(Collider2D coll)
{
    if (coll.gameObject.tag == "food")
    {
        energy += 1.0f;
        Destroy(coll.gameObject);
    }
}
  • 충돌 시 에너지가 +1.0 만큼 채워지고 tag가 food인 오브젝트는 삭제한다.
void OnTriggerEnter2D(Collider2D coll)
{
    if (coll.gameObject.tag == "food")
    {
        if (energy < full)
		{
			 energy += 1.0f;
		     Destroy(coll.gameObject);
		}
        else
        {
            Debug.Log("배가 다 찼어요");
        }
    }
}
  • energy가 full 보다 작다면 +1.0 만큼 채워진다.
  • full 보다 커지면 "배가 다 찼어요" 출력
void OnTriggerEnter2D(Collider2D coll)
{
    if (coll.gameObject.tag == "food")
    {
        if (energy < full)
        {
            energy += 1.0f;
            Destroy(coll.gameObject);
            gameObject.transform.Find("hungry/Canvas/front").transform.localScale = new Vector3(energy / full, 1.0f, 1.0f);
        }
        else
        {
            Debug.Log("배가 다 찼어요");
        }
    }
}
  • normalCat - hungry - canvas - front의 Scale x값을 0으로 설정
  • Scale x값을 찾아서 energy/full 값으로 조절한다.
void OnTriggerEnter2D(Collider2D coll)
{
    if (coll.gameObject.tag == "food")
    {
        if (energy < full)
        {
            energy += 1.0f;
            Destroy(coll.gameObject);
            gameObject.transform.Find("hungry/Canvas/front").transform.localScale = new Vector3(energy / full, 1.0f, 1.0f);
        }
        else
        {
            gameObject.transform.Find("hungry").gameObject.SetActive(false);
            gameObject.transform.Find("full").gameObject.SetActive(true);
        }
    }
}
  • energy가 full 보다 커지면 hungry를 비활성화 후 full을 활성화한다.
void Update()
{
    if (energy < full)
    {
        transform.position += new Vector3(0.0f, -0.05f, 0.0f);
    }
    else
    {
        if (transform.position.x > 0) // 생성된 x값이 0보다 크면 오른쪽으로 사라진다.
        {
            transform.position += new Vector3(0.05f, 0.0f, 0.0f);
        }
        else                         // 생성된 x값이 0보다 작으면 왼쪽으로 사라진다.
        {
            transform.position += new Vector3(-0.05f, 0.0f, 0.0f);
        }
        Destroy(gameObject, 3.0f); // 3초 뒤 오브젝트 삭제
    }
}
  • energy가 full 보다 커졌을 때 화면의 옆 방향으로 사라지게 한다.

결과물 !

public GameObject normalCat;

void Start()
{
    InvokeRepeating("makeFood", 0.0f, 0.2f);
    InvokeRepeating("makeCat", 0.0f, 1.0f); // 1초에 한 번 makeCat 함수 불러오기
}

void makeCat()
{
    Instantiate(normalCat);
}
  • gameManager.cs에 코드 추가

  • UI - Image 추가 후 retryBtn으로 이름 변경
  • 이미지를 알맞게 씌우고 사이즈 조정
  • button component 추가, retryBtn.cs 추가
using UnityEngine.SceneManagement;

public void ReGame()
{
    SceneManager.LoadScene("MainScene"); // MainScene를 불러온다.
}
  • 코드 추가 후 onclick 설정
public static gameManager I;

void Awake()
{
    I = this;
}
  • gameManager를 싱글톤화 시켜서 내부의 기능을 다른 오브젝트에서도 사용할 수 있게 만든다.
public GameObject retryBtn;

public void gameOver()
{
    retryBtn.SetActive(true); // retryBtn을 활성화 시킨다.
    Time.timeScale = 0.0f;   // 시간 초기화
}
  • gameManager에 gameOver( ) 함수 추가
void Update()
{
    if (energy < full)
    {
        transform.position += new Vector3(0.0f, -0.05f, 0.0f);

        if (transform.position.y < -16.0f) // cat 오브젝트가 y값 -16 보다 작아지면 gameOver() 함수를 gameManager에서 불러온다.
        {
            gameManager.I.gameOver();
        }
    }
    else
    {
        if (transform.position.x > 0)
        {
            transform.position += new Vector3(0.05f, 0.0f, 0.0f);
        }
        else
        {
            transform.position += new Vector3(-0.05f, 0.0f, 0.0f);
        }
        Destroy(gameObject, 3.0f);
    }
}
  • cat.cs의 코드를 수정

결과물 !

Feedback

유니티 엔진은 게임 만들기에 최적화가 되어있음을 감탄하며 강의를 들었다. UI가 굉장히 직관적이고 C#에 사용되는 기본 기능 코드들도 어렵지 않게 느껴졌다. 얼른 많은 기능들을 배우고 복습하며 익숙해지고 싶다는 생각이 든다..!

0개의 댓글