본문 바로가기

취미로 하는 게임코딩_gameCodingAsHobby/유니티unity로 게임 만들기

유니티20_게임 제작 과정 04_적 만들기

지금까지 익힌 내용으로 게임 제작에 적용해 본다.

유니티 허브를 실행한 후 게임 제작 과정1~3까지 만들었던 Project Practice Shooting 프로젝트를 실행한다.

 

 

적을 만들기 전에 우선 총알(Bullet)색을 바꾸어보자.

적 색깔을 빨간색으로 바꾸기 위해서다.

여기서는 노란색으로 바꿀 것이다.

 

Prefabs폴더에 만든 Bullet을 선택한다.

 

 

Inspector창에서 Sprite Renderer의 Color 를 선택한다.

 

 

원하는 색 선택한다.

정확한 색을 선택하기 위해서는 RGB 숫자를 입력한다.

A는 투명도를 조절하는 부분이다.

 

 

게임 실행 후 Bullet을 발사했을 때 화면에 나타나는 것은 Prefabs 폴더에 Prefab(프리팹)과 호출 메서드가 담당하기 때문에 Bullet 게임오브젝트는 보이지 않게 해야 게임 시작할 때 화면에 나타나지 않는다.

 

Hierarchy창에서 Bullet을 선택한 후

Inspector창의 Bullet을 해제한다.

 

게임오브젝트 적(Enemy) 만들기

 

적을 만드는 과정도 Ship만드는 과정과 비슷하다.

먼저 Create Empty(빈 게임 오브젝트) 만들고 이름을 Enymy1으로 한다.

 

Hierarchy창의 + 버튼을 클릭하거나 빈 곳에서 마우스 오른쪽 버튼을 클릭해서 Create Empty를 선택한다.

 

 

만들어진 GameObject 이름을 Enemy로 수정한다.

 

적 이미지를 구현하기 위해 Enemy을 선택한 후 Inspector창에서 Add Component를 클릭하여 Sprite Renderer 컴퍼넌트를 추가한다.

 

 

Sprite는 Knob를 선택한다.

Color는 빨간색을 선택한다.

 

Transform컴퍼넌트의 Position Y값을 3으로 한다.

크기는 X, Y를 2로 조정한다.

 

 

실행해서 총알을 발사하면 적을 그냥 통과하고 아무 일이 일어나지 않는다.

적과 총알 사이에 일어나는 상황에 어떻게 작용할 지 명령 코드를 작성하지 않았기 때문이다.

 

Enemy 스크립트 작성

 

Scripts폴더에 Enemy 라는 스크립트를 만든다.

 

 

Scripts폴더에서 마우스 오른쪽 클릭 후 Create > C#Script를 클릭한다.

스크립트명을 Enemy로 바꾼 후 더블클릭하면 편집할 수 있다.

 

 

5번줄에 스크립트명과 같은 이름(Enemy)으로 class가 만들어져 있다.

이 클래스는 UnityEngine에 이미 만들어져 있는 MonoBehaviour 클래스를 상속받는다.

 

MonoBehaviour클래스에는 스크립트를 컴퍼넌트로 인식할 수 있게 해서 게임오브젝트에 연결할 수 있도록 하는 메서드가 포함되어 있다. 그래스 스크립트를 게임오브젝트에 컴퍼넌트로 추가할 수 있는 것이다.

 

MonoBehaviour클래스에는 객체를 만들어 주는 '생성자'를 자동으로 처리하는 메서드를 가지고 있다.

그래서 스크립트를 게임오브젝트에 연결하면 스크립트 내에서 생성자를 따로 만들지 않아도 객체를 만들 수 있다.

만약 스크립트에서 생성자 코드를 작성하면 에러가 나도록 MonoBehaviour클래스에 정의되어 있다.

 

그러므로 스크립트에서 생성자를 사용하여 객체를 생성하려면 MonoBehaviour 클래스 상속을 해제해야 한다. 이것은 결국 스크립트를 게임오브젝트에 연결할 수 없다는 뜻이다.

 

그리고 MonoBehaviour클래스를 상속받는 스크립트를 게임오브젝트에 연결하여 객체를 생성할 때는 객체 생성 시 필요한 초기화 코드Awake( ) 메서드 또는 Start( ) 에 적어준다.

 

Awake ( )메서드는 프로그램이 시작하기 전에 변수 또는 상태를 초기화하는데 사용한다.

*awake : 깨우다

 

Enemy 스크립트 편집

 

적의 특성과 행동을 표현하기 위해서 멤버(필드와 메서드)를 정의해야 한다.

적에게 필요한 필드와 메서드로 생각해 볼 만한 기본적인 것은 다음과 같다.

 

처음에 생명(건강)을 100만큼 가진다. (필드 health)

손상을 입을 경우 일정한 값(value) 만큼 생명이 줄어든다. (메서드 TakeDamage)

 

Start()메서드 이전 7번줄에 필드를 정의하고 초기값을 int타입 100으로 정한다.

 

14번줄에 TakeDamage(손상을 입다) 메서드를 만든다.

이 메서드는 총알을 맞거나 Ship과 접촉하면 health값이 줄어들게 한다.

 

매개변수로 int 타입 value를 만든다.

TakeDamage메서드가 호출되면 health 변수에서 매개변수로 전달받은 value값을 뺀 값을 다시 저장한다.

 

Enemy 게임오브젝트에 스크립트 연결

 

 

Add Component 버튼으로 Enemy 스크립트를 컴퍼넌트로 추가한다.

 

충돌체(Collider) 컴퍼넌트 추가

 

이제 Bullet과 충돌하면 처리할 컴퍼넌트를 추가한다.

게임오브젝트의 충돌 설정을 위한 컴퍼넌트는 Collider(콜라이더)이다.

여기서는 Circle Collider 2D (원형 충돌 2D) 컴퍼넌트를 추가한다.

 

Scene뷰 탭을 눌러보면 Enemy 테두리에 녹색 원이 나타난다.

녹색 원이 Collider 컴퍼넌트가 적용되었다는 표시이며 충돌의 기준선이 된다.

 

Bullet컴퍼넌트도 충돌체를 적용해야 한다.

Bullet 프리팹 모드에서 Collider컴퍼넌트를 추가한다.

 

 

Prefabs 폴더에 있는 Bullet을 더블클릭한 후 Circle Collider 2D컴퍼넌트를 추가하면 다음과 같은 모양이 된다.

 

 

이제 게임을 실행하면 다음과 같이 적과 총알이 부딪히는 모양이 나타난다.

 

 

충돌 감지 메서드

화면상으로는 두 객체의 충돌을 표현했지만 충돌이 일어났을 때 어떤 조치를 하려면 스크립트에서 충돌을 감지할 수 있는 메서드가 필요하다.

 

OnCollisionEnter2D ( )

 

*on : ~위에, ~상태에 있다

*collision : 충돌

*enter : 들어가다

 

그래서 OnCollisionEnter은 '충돌 상태에 들어가다' 즉, '충돌이 일어났다'라는 뜻이다.

 

Enemy 스크립트에 이 메서드를 추가하면 충돌이 일어났을 때 Collider2D컴퍼넌트가 이 메서드를 실행하도록 설정되어 있다.

 

 

19번줄

이 메서드의 매개변수는 Collision2D 타입으로 정해져 있다.

매개변수명은 collision(충돌) 으로 해도 되고, 여기서는 처음 3글자만 따서 만들었다.

다른 게임오브젝트와 충돌하면 Collider컴퍼넌트는 이 메서드를 호출하면서 매개변수로 충돌한 객체를 전달한다.

 

21번줄

호출이 되는지 확인하기 위해 '충돌함'이라는 문자열을 출력한다.

 

실행하면 아래와 같이 메서드가 호출되는 것을 확인할 수 있다.

 

Collider2D 클래스에는 OnCollisionEnter2D메서드 이외에도 다음과 같은 메서드가 있다.

 

OnCollisionStay2D ( ) 

OnCollisionExit2D ( )

 

*stay : 계속 있다, 머무르다.

*exit : 밖으로 나가다, 출구

 

OnCollisionStay2D 메서드는 두 객체가 접촉해 있는 동안 실행하는 메서드이며,

OnCollisionExit2D 메서드는 두 객체가 충돌 후 떨어질 때 실행하는 메서드이다.

 

 

충돌 후 health 감소

충돌이 일어났을 때 health 값이 줄어들게 하려면 다음과 같이 작성한다.

 

 

11번줄

게임이 시작하면 실행되는 Start메서드에 health 초기값을 출력한다.

괄호 안에 초기값 표시는 다음과 같이 작성해도 된다.

 

"health값 : " + health

 

21번줄

Collider2D컴퍼넌트가 충돌을 감지해서 OnCollisionEnter2D메서드를 호출하면

위에서 만든 TakeDamage메서드를 호출해서 인수 값 20을 매개변수에 전달한다.

 

22번줄

TakeDamage메서드가 실행한 후 다시 health값을 확인한다.

 

실행 후 출력하면 다음과 같이 20 만큼 줄어든 health값을 확인할 수 있다.

 

 

충돌 후 총알 사라짐

현재까지 실행에서 나타나는 문제가 있다.

앞에서 총알이 만들어지면 2초 후에 사라지도록 코드가 작성되어 있다.

그래서 1번 총알과 2번 총알이 충돌한 상태에서 그대로 사라지므로 2번째 총알은 적과 충돌하지 않는다.

 

이것을 해결하려면 1번 총알이 적과 충돌한 직후 사라지도록 해야 한다.

 

위에서 OnCollisionEnter2D 메서드는 다른 게임오브젝트와 충돌하면 Collider컴퍼넌트는 이 메서드를 호출하면서 매개변수로 충돌한 객체를 전달한다고 했다.

그러므로 1번 총알이 충돌하면 매개변수에 전달되는 인수는 1번 총알 객체가 될 것이다. 

이 매개변수를 이용하면 전달된 충돌 객체에 접근할 수 있다.

여기서는 충돌한 총알 객체를 비활성화 해서 화면에서 보이지 않도록 한다.

 

23번줄

코드의 뜻은 다음과 같다.

col 의 게임오브젝트의 SetActive메서드를 호출하여 false값을 전달한다.

 

SetActive( ) 메서드는 게임오브젝트의 활성 또는 비활성을 설정할 수 있다.

충돌했을 때 전달받은 인수(게임오브젝트)가 저장된 매개변수로 게임오브젝트에 접근해서 SetActive메서드 인수로 false 값을 전달해서 비활성화 한다.

 

스크립트를 저장한 후 다시 실행하면 총알이 충돌한 직후 사라지고 두번째 총알도 충돌하는 것을 확인할 수 있다.

health값도 아래와 같이 변한다.

 

그런데 적(Enemy)은 총알을 계속 맞으면 아래와 같이 0이 된 후에 마이너스 값으로 표시된다.

 

다음 글에서 이 문제를 해결하자.

 

끝.

Wraven...