TIL

2024 08 30 TIL

noc777 2024. 8. 30. 17:59

3-5 고양이 만들기

고양이는 일반 고양이와 뚱뚱한 고양이 두 가지 종류를 만들것이다.

 

Hirerachy 창에서 create empty 후 이름을 NormalCat으로 이름을 붙여준다.

그리고 NormalCat 안에 sprite square 를 두개 만들어주고 Hungry, Full 이라 

이름을 붙여준다.

 

Normalcat_1  NormalCat_full 이미지 파일을 Hungry Full에 넣어준다.

 

Full 오브젝트는 꺼주도록 한다 ( 필요할 때만  옵션을 키는 것)

 

이제 Hp 바를 만들차례다.

Hungry 밑에 UI -> Image를 만들어준다. 

 

Canvas의

Render Mode를 World Space 로 바꿔준다(게임 화면이 아닌 게임월드로 가져와야 하기 때문에)

Rect Transform Postion 값을 x y  0 0  width  4  height 0.5 로 설정

 

image의

Rect Transform의 center 와 middle이 존재하는 아이콘을 클릭

키보드의 shift 외 alt를 누르고 오른쪽 대각선 하단 버튼을 클릭

(캔버스 사이즈에 맞춰 이미지의 크기 조절)

그리고 나서 이름을 Back 으로 지어준다.

 

캔버스의 y값을 -4 더해준다. Back 이미지 파일을 ctrl + D를 눌러 복사하고

이름을 Front라고 지어준다. 

 

Front의 

Anchors -> Pivot x 값을 0으로 설정 

컬러 색을 생선가게 지붕색으로 추출하여 사용한다.

 

animation 폴더를 만들고 안에 애니메이션 파일 'NormalCat'을 생성하고

Loop Time 까지 체크해준다.

NormalCat 애니메이션 파일을 Hungry 오브젝트에 끌어서 놔준다.

 

NormalCat을 더블클릭후 Hungry 오브젝트 클릭하고 녹화버튼을 눌러준다.

 

0초엔 normalcat_1    10초엔 normalcat_2    20초엔 normalcat_1을 넣어주고 녹화버튼 종료

를 하면 고양이가 움직이는 애니메이션이 완성된다.

 

이제 NormalCat 오브젝트를 통째로 ctrl +D를 하여 복사하고 원본은 프리팹으로 만들어준다.

 

이제 남은 NormalCat(1)을 FatCat으로 이름을 바꿔주고 밑의 Hungry,Full의 이미지파일을

FatCat_1  ,Full로 교체해준다.

 

FatCat의 캔버스 파일의 POS X 값을 -0.5로 바꿔줌( 고양이 크기가 더 커서 HP바의 위치 조절) 

FatCat_Hungry 오브젝트의 기존에 있던 애니메이션 파일을 삭제해주고 새로 FatCat애니메이션 파일을

만들어 준후 다시 Hungry에 끌어옴 

 

위에서 과정처럼  녹화버튼을 누르고 0 10 20 에 이미지파일을 넣어주고

프리팹으로 만들어주는 작업을 한다.

 

3-6 중력 HP바

 

고양이가 내려오는 기능과 HP 바의 구현을 하는 강의다.

 

먼저 Cat 스크립트를 생성하고 실행해준다. 

 

고양이가 내려오는 것을 구현해줘야하기 때문에 Update 안에 

transform.position += Vector3.down;    //y값만 -1씩 더해준다.

 

예상한대로 매우 빠른속도로 횡단하는 고양이를 볼 수 있다. 따라서 0.05배를 해준다.

transform.position += Vector3.down*0.05f;

 

그럼에도 고양이의 속도가 주체되지 않는다면 Application.tagetFrameRate = 60; 을 start에 써준다.

 

고양이에 스크립트를 적용하려면 프리팹을 Hirerachy 창에 끌어오고 add component Cat 스크립트를 찾아주면된다.

스크립트를 적용한 김에 충돌효과(Box Collider 2D)도 적용시켜주고 프리팹 폴더에 있는 프리팹에 변경된

내용을 저장시켜주기 위해 Inspector 창의 Overides를 클릭 apply all 을 눌러주면 해당 프리팹에 적용까지

완료된다.

 

이제 Food에도 Circle Collider2d rigidbody2d를 적용해주고 실행해보면 음식에 중력이 설정되어있어

위로 올라가다 말것이다. Food 프리팹의 Rigidbody2d의 Body Type을 Dynamic이 아닌 Kinematic으로

바꿔주면 중력효과를 받지 않게된다. 그리고 프리팹들의 collider의 is trigger까지 눌러준다.

 

Food 프리팹에 태그를 새로 Food 라고 만들 붙여준다.

 

이제 Food가 고양이에 부딪혔는지 여부를 판별하는 코드를 Cat 스크립트에 짜볼것이다.

 

pivate void OnTriggerEnter2D(Collider2D collision) 함수를 생성하고

안에 if(collision.gameObject.CompareTag("Food")) // 푸드라는 태그를 가진 오브젝트와 부딪혔을 때

조건문 안에 디버그 코드를 작성하고 실행이 잘되는지 확인한다.

 

실행이 잘된다면 이제 음식이 고양이와 충돌했을때 밑에 있는 Hp바가 동작하도록 설정할 것이다.

Front 오브젝트의 Scale 값을 움직여줘야하기 때문에(게이지 바가 차는 것을 구현)

Front의 RectTransform을 가져와야한다.

 

다시 스크립트로 돌아와서 public RectTransform front; 변수를 생성

float full = 5.0f; //Hp바의 최대치

float energy = 0.0f;  //충돌된 값의 축적치

 

if(collision.gameObject.CompareTag("Food"))

{

    energy += 1.0f;  //충돌했을때 에너지를 1씩더해줌

    front.localScale = new Vector3(energy/full,1.0f, 1.0f);   

// front의 x값을 변경해주기 위해 0에서 energy를 full로 나눈 값이 되도록

    Destroy(collision.gameObject);    // 충돌한 음식이 삭제되도록 

}

 

이제 코드를 작성했으면 다시 NormalCat 프리팹으로 돌아와서 Cat스크립트의 Front 변수 안에

front오브젝트를 넣어준다.

 

실행해보면 게이지바가 다찼는데도 계속늘어나서 

 

스크립트로 돌아가서

if(energy<full) { // 에너지가 풀보다 작을 때 조건

energy += 1.0f;  

front.localScale = new Vector3(energy/full,1.0f, 1.0f);   

Destroy(collision.gameObject);   

}

else

{

 debug.log("");

}

실행이 잘된다면 이제 게이지가 다 찼을때 fullcat 이미지로 바뀌도록해야한다.

 

스크립트로 돌아가서 public GameObject hungryCat;    , public GameObject  fullCat; 변수를 생성

else문의 debug 로그 대신

hungryCat.SetActive(false); 

fullCat.SetActive(true);

//energy가 full보다 클때 헝그리 오브젝트를 끄고 풀오브젝트를 킴

 

 고양이가 배가부를때 옆으로 이동하는 로직을 작성해야한다.

 

update문에 

if(energy <full)

{

  transform.position += Vector3.down*0.05f; //아까 만들었던 밑으로 가는 코드를 조건문 안에 

}

else

{

   if(transform.position.x >0) // 기준점에서 오른쪽에 있다면

      {

        transform.position += Vector3.right*0.05f;   //오른쪽으로 이동

      }

    else   //그게 아니라면

      {

        transform.position += Vector3.left*0.05f;   //쪽으로 이동

      }

}

 

이제 고양이가 랜덤한 위치에서 생성되도록 로직을 작성한다.

 

y값은 고정하고 x값만 랜덤으로 하기 위해

 

start 안에 float x=Random.Range(-9.0f,9.0f);  //-9에서 9의 범위를 가지는 변수x

float y = 30.0f;   //y값은 30으로 고정

transform.position = new Vector2(x,y); // 오브젝트 시작위치

를 작성

 

실행했을때 고양이 게이지가 가득차고 바뀌어야하는데 약간의 지연시간이 있는것을 확인

따라서

오브젝트의 외형이 바뀌는 타이밍을 if(energy = 5.0f ) //에너지가 5가 될때로 바꿔준다.

if(energy<full) 안에 넣어 바로 실행되도록 해주면 일단은 고양이의 기본 로직은 완성되었다.

 

3-7 고양이의 반복생성

 

고양이의 반복생성을 위해 GameManager 오브젝트 스크립트를 만들고 

스크립트를 실행해준다.

void MakeCat()

{

   Instantiate(gameObject) // 오브젝트를 생성

}

먼저 고양이만들기 라는 함수를 만들어주었다.

그리고 public GameObject normalCat; 변수를 만들어주고

 

Start 안에 InvokeRepeating("MakeCat",0f,1f);을 작성

 

GameManager 오브젝트의 normalcat 변수에 normalcat 프리팹을 넣어주면 반복생성이 된다.

 

고양이가 생선가게에 닿았을때 재시작버튼을 만들기위해 create->UI->legacy->button 으로 버튼 생성

pos x y 를 0 0 width 300 height 100   이미지는 미리 다운받은 retryBtn 삽입 하여 기본 설정은 했다.

 

이미 startbutton에 메인 신을 불러오는 기능을 만들어놓았기에  stratbutton 스크립트를 연결해주고

onclick() +버튼을 눌러주고 none 자리에 retrybtn의 오브젝트 파일을  no function에 stratgame() 기능을 

넣어주면 된다.

 

canvas를 꺼주고 게임이 끝났을때 버튼을 보이게 하기위해 로직을 작성한다.

 

게임매니저 스크립트로 돌아가서

public GameObject retryBtn;  //재시작버튼 변수 선언

 

public void GameOver()

{

   retryBtn.SetActive(true);     //게임이 끝났을때 활성화 

}

 

게임매니저를 외부에서 접근할 수있도록 싱글톤으로 만드는 코드 작성

public static GameManager Instance; //싱글톤 변수 작성

 

awake 함수를 생성하고

안에

if(Instance == null) // Instance 변수가 비어있을때

{

   Instance = this;   //변수에 자기자신을 넣음 

}

 

cat 스크립트로 돌아가 

if(energy <full)

{

  transform.position += Vector3.down*0.05f; 

  if(transform.position.y<-16.0f)  //고양이가 -16까지 내려왔다면

  {

    GameManager.Instance.GameOver();  //게임오버를 켜준다 

   }

}

로 수정하고 Application.tagetFrameRate = 60;를 잘라내 GameManager의 awake 함수에 붙여준다.

 

Unity로 돌아가 GameManager의  스크립트에 RetryBtn 변수에 RetryBtn 오브젝트를 붙여넣는다.

 

실행했을때 재시작버튼이 나온다면 재시작버튼이 나왔을때 고양이와 음식이 나오지않게 추가해주도록

한다.

 

GameManager 스크립트의 GameOver() 안에 Time.timeScale =0f;  //게임이 끝났을때 시간을 정지

awake 안에 Time.timeScale = 1.0f;  //다시 시작했을때 실행

 

하면 이제 더이상 게임이 끝났을때 오브젝트가 움직이지 않는다.

 

마지막으로 고양이가 배부를때 잠시후에 사라지게 하기위해 

처럼 Destroy 함수로 3초후에 사라지게 만들어주면 고양이의 핵심적인 부분은 끝난다.

 

3-8 레벨 구성하기 레벨업 표기하기

 

지난시간에는 재시작버튼을 구현하기 위해 Canvas를 꺼주었는데 Canvas를 켜주고 대신 RetryBtn을

꺼준다.

 

그리고 canvas에 새 create empty 로 빈 오브젝트를 생성 x 250 y 500 으로 맞춰주고 

다시 밑에 image를 추가해주고 cat_level 리소스를 넣어준다.

그리고 다시 image를 추가해주고 width 100 height 15 로 맞춰주고 y -70으로 하며 이름을 back으로 수정

ctrl +d하여 front로 생성 색은 생선가게 색을 추출한다. (레벨 게이지)

 

pivot을 왼쪽으로 잡기위해 x값을 0으로 맞춰주고 scale x을 0으로 한다.

 

level의 image 밑에 text 오브젝트를 추가하고 width 20 height 100  폰트 사이즈는 40에 배민주아체 style을 bold까지

설텍스트에도 0을 넣어준다.

 

경험치가 오르고 오른 경험치만큼 레벨이 오르도록 코딩을 한다.

 

먼저 레벨과 점수를 담을 변수를 만들고

int level = 0;

int score = 0;

 

점수를 추가하는 함수를 만든다.

public void AddScore()

{

  score ++; //스코어가 1씩 증가

  level = score / 5;  //스코어가 5가 될때마다 레벨이 1 오름

}

 

이제 고양이가 한마리마다 배가 부를때 경험치가 1씩 오르도록 작성해본다.

Cat 스크립트로 가서

if(energy == 5.0f) {

  hungryCat.SetActive(false);

  fullCat.SetActive(true);

  Destory(gameObject, 3.0f);

  GameManager.Instance.AddScore();

}

고양이가 배가부를때의 조건문에 GameManager.Instance.AddScore(); 를 작성

//게임매니저의 AddScore 함수를 실행 

 

하지만 이런식으로 코드를 짜면 고양이가 옆으로 가는 도중에 맞아도 점수가 오르는 상황이 발생할 수 있다

그래서 

 

위에 bool isfull = false; // bool 변수를 생성

if(energy == 5.0f)

{

    if(!isfull)   //!결과를 반대로  false면true true 면 false  //만약 isfull이 false라면이라는 조건문이됨

    {

     isfull = true;    //isfull을 true로 바꿔서 조건문에 부합하지 않게 

     hungryCat.SetActive(false);

     fullCat.SetActive(true);

     Destory(gameObject, 3.0f);

     GameManager.Instance.AddScore();

    }

}

로 수정함으로서 중복해서 점수가 올라가지 않도록한다.

이제 레벨값을 창에 반영할 코드를 작성할 것이다.

먼저  GameManager의 using문들 밑에 using UnityEngine.UI; 를 적어주고

public Text levelTxt; // levelTxt 텍스트 변수를 생성

AddScore에

levelTxt.text = level.Tostring();   //레벨값만큼 텍스트로 출력

 

GameManager 스크립트에 levelTxt 변수에 level오브젝트 안의 텍스트를 넣어준다.

 

실행하기전에 게이지가 올라가는것을 연출해야하기 때문에 front의 scale.x 값이 0인지 확인하고

GameManager 스크립트로 돌아가 

public GameObject levelFront; //게임오브젝트 변수를 생성

AddScore() 안에

levelFront.localScale = new Vector3((score - level * 5) / 5.0f, 1f, 1f);

//Front의 Scale.x 값을 (score - level*5)/5 한 값으로 설정한다.

 

level front 변수 값에 front 오브젝트를 넣어주고 실행해보면

 

게이지와 레벨이 정상작동하는 것을 확인할 수 있다.

 

3-9 레벨 반영하기

 

3-9에선 3-8 강의에서 진행했던 레벨을 반영하여 난이도를 조절해본다.

GameManager 스크립트에서 makeCat()함수를만들어 고양이를 생성하는 로직이 있었다.

이 로직을 레벨에 따라 난이도를 바꿀 것이다. 

 

void makeCat()

{

    Instantiate(normalCat);  

    if (level == 1)  //레벨 1일때의 조건

    {

       float p = Random.Range(0, 10);  //0에서 10까지 랜덤한 변수 p  

       if (p < 2) Instantiate(normalCat);  //p가 2보다 작을때 추가적으로 고양이를 더 생성한다.

     }

     else if (level >= 2)   //레벨 2일때의 조건

     {

        float p = Random.Range(0, 10);   //위와 동일하게 0에서 10까지의 난수

        if (p < 5) Instantiate(normalCat);   //p가 5보다 작을때 추가적으로 고양이를 생성

       }

}

원래 만들어졌던 생성문 이외에 조건문과 조건문에 따른 다른 확률로 고양이를 생성하는 로직이다.

 

그리고 레벨 3일땐 미리 만들어둔 FatCat 프리팹을 이용하여 살찐고양이가 나오는 로직을 만든다.

 

먼저 cat 스크립트에 public int type; 변수를 적는다.   

type에 따라 1은 일반 고양이가 2는 살찐 고양이가 나오게 할 생각이다.

 

고양이들의 프리팹은 앞전에 강의에서 미리 만들어 두었지만

front의 scale x 값이 0인지

box collider 2d가 제대로 있는지 확인해둔다.

또한 아까 만들어둔 type에 해당하는 칸이 cat script를 가지고 있는 프리팹들에 생겨있다.

이 type에 일반고양이는 1 살찐 고양이는 2를 적어준다.

 

 

cat 스크립트의 start에 type에 따른 조건문을 만들었다.

고양이마다 속도와 체력이 다르게 설정되었다.

speed를 고양이들이 아래로 내려가는 로직에 있던 0.05 대신 넣어준다.

 

그리고 레벨 3일때 뚱뚱한 고양이가 나오도록 조건문을 만들어준다.

위 사진에는 일반고양이와 살찐 고양이 외에 해적 고양이가 나오는데 이건 숙제 파트에서 해적고양이를

추가했었다. 그리고 레벨4를 넘어가면 일반고양이만 계속 나오는 문제가 있어 앞의 내용을 응용하여

일정확률로 살찐고양이나 해적고양이가 나오도록 수정해보았다.

 

어느정도 그럴듯한 게임을 만든 것 같아서 나름 만족스러운 강의였던 것 같다.  

'TIL' 카테고리의 다른 글

2024 09 03 TIL  (1) 2024.09.03
2024 09 02 TIL  (1) 2024.09.02
2024 08 29 TIL  (0) 2024.08.29
2024 08 28 TIL  (7) 2024.08.28
2024 08 27 TIL  (0) 2024.08.27