09강) 충돌 처리 |
오랜만에 쓰네요. 그간 많이 바빠서 말이죠...
지난 시간에는 미사일을 발사하였습니다.
오늘은 이 미사일들이 적 기체에 충돌하는 것을 처리해보겠습니다.
지금 당장 적기체까지 만드는것은 아니고 간단한 Sprite에 충돌 처리구현까지만 하도록 해보겠습니다.
유니티에서 충돌 인식) Collider |
유니티에서 충돌을 인식하는 방법은 "Collider"를 이용합니다.
간단하게 2D가 아닌 3D로 입체적이게 확인하여 봅시다.
일단 2D를 해제해서 3D 모드로 바꿉니다.
그리고 "3D Object - Cube"를 하나 만들어줍시다.
그렇게 생성된 큐브를 선택하면 주위에 "초록색 선"이 그려진것을 볼수 있습니다.
이것이 바로 "Collider" 인데요.
큐브의 "Inspector"로 가서 보면
이렇게 "XXX Collider"라는 것이 있는것을 볼 수 있죠.
골격을 뜻하는 "Collider"는 인간으로 보면 "뼈"를 뜻합니다.
뭔가에 충돌을 할 때 인식하고 밀리지 않게끔 해줍니다.
Collider가 있을 때 충돌 |
Collider가 없을 때 충돌 |
(하지만 Collider만으로는 위와같은 충돌처리를 할 수 없습니다. Rigidbody필요)
우리는 3D 객체를 통해서 봤지만 2D도 똑같습니다.
다만 Sprite 객체에 직접 Collider를 씌워야하는 번거로움이 있긴하지만 말이죠.
적을 만들어서 Collider 씌우기 |
임시적으로 적을 만들어서 Collider를 씌워보겠습니다.
"2D Sprite"를 하나 생성해줍니다.
그리고 아무 이미지나 씌워줍니다.
(우리는 충돌 테스트만 할 것이기 때문이죠.)
sprite를 원하는 크기만큼 키워주고 "Z좌표를 0으로" 해줍니다.
이렇게 생성한 sprite에 Collider를 넣기위해 "Add Component - Physics 2D - Box Collider 2D"를 해줍니다.
그렇게 하면 대충 이미지 크기에 맞게 Collider를 생성해주는데 살짝 큰감이 있으므로
"Edit Collider" 버튼을 눌러서 알맞게 조정합니다.
이렇게 임시의 적이 만들어졌습니다.
유니티에서 충돌 인식) Tag |
그런데 생각을 해봅시다.
어떤 미사일이 날라가서 어떤 객체의 Collider에 부딛힙니다.
이게 항상 적이라면 문제가 되지 않지만 "적의 기체와 아군의 기체가 똑같은 오브젝트를 사용"한다면 어떻게 적을 구분할까요?
이러한 문제들을 해결하는데 가장 보편적으로 사용하는 것이 "태그(Tag)"입니다.
적 기체는 "Enemy 태그"를 붙여주고, 아군 기체는 "Friendly 태그"를 붙여줌으로써 해결할 수 있죠.
유니티에서 객체를 만들게 되면 기본적으로 "Untagged"라는 태그가 붙게됩니다.
이제 새로 만든 적 기체에 붙일 태그를 만들고, 그 태그를 적 기체에 적용시켜봅시다.
여기서 적 기체를 선택해도 상관없고, 플레이어를 선택해도 상관은 없습니다.
객체를 선택하고 "Tag - Add Tag"를 누릅니다.
"Tags - Add(+) - 알맞는 이름 - Save" 를 합니다.
그렇게 하면
이렇게 새로운 태그가 만들어진 것을 볼 수 있습니다.
이제 이 태그를 적기체에 적용시켜봅시다.
이렇게 하면 태그는 적용된 것입니다.
유니티에서 충돌 인식) RigidBody |
그런데 이렇게 Collider만 있다고 해서 충돌이 완벽히 인식하는 것은 아닙니다.
뼈와 뼈가 부딛혔지만 그걸 인식하는 "뇌"가 없다면 인식할 수 없죠.
그렇기 때문에 양쪽의 뼈를 가진 사람중 한사람만 "뇌"가 있어도 충돌을 했는지 인지가 가능합니다.
이렇게 충돌을 감지해주는 "뇌"를 유니티에선 "Rigidbody"가 해줍니다.
※여기서 설명하는 Rigidbody는 유니티 5.5.x 버전 이상의 Rigidbody를 설명합니다.
동적인 객체에 적용하는 Rigidbody와
스크립트로만 반응하는 객체에 적용하는 Rigidbody와
정적인 객체에 적용하는 Rigidbody로 크게 구분됩니다.
우리는 여기서 "Kinematic"을 사용할겁니다.
※만약 자신의 유니티가 5.5이하라면 그냥 사용하시면됩니다.
(단, Gravity Scale을 0으로 만들어주셔야합니다.)
(5.5이상 부터는 Rigidbody가 필요없는 부분을 계산안하도록 최적화기능을 추가하였습니다.)
이 Rigidbody는 모든 객체에 심을 필요는 없습니다.
"부딛히게 하는 주체"에 심으시면 됩니다.
(주로 움직이는 객체에 심습니다.)
그래서 우리의 경우에는 2가지중 하나를 선택하면 됩니다.
"미사일" 또는 "적 기체"에 설치하면 되죠.
저는 "미사일"에 설치하도록 하겠습니다.
유니티에서 충돌 인식) 함수 |
이제 충돌 인식의 꽃인 "함수"에 대해서 알아보겠습니다.
크게 2가지로 구분이 되는데 "Trigger"와 "Collision" 입니다.
Trigger | 부딛히는 객체와의 물리적 연산없이 충돌을 감지한다. (Collider의 "Is Trigger"를 사용한다.) |
Collision | 부딛히는 객체와의 물리적 연산을 통해 충돌을 감지한다. (Rigidbody의 Kinematic 속성을 꺼야한다 - 즉, Dynamic 이용) |
관련된 함수로는
종류 | 함수 | 설명 |
Trigger | void OnTriggerEnter(Collider collision) | 충돌을 할 때 |
void OnTriggerStay(Collider collision) | 충돌을 하는 동안 | |
void OnTriggerExit(Collider collision) | 충돌이 끝났을 때 | |
Collision | void OnCollisionEnter(Collision collision) | 충돌을 할 때 |
void OnCollisionStay(Collision collision) | 충돌을 하는 동안 | |
void OnCollisionExit(Collision collision) | 충돌이 끝났을 때 |
(2D의 경우에는 Collider와 Collision은 각각 Collider2D, Collision2D를 사용합니다.)
우리는 Rigidbody를 "Kinematic"으로 사용하기 때문에 "Trigger" 방식을 사용할 것입니다.
그리고 충돌을 할 때 처리를 할 것이기 때문에 "OnTriggerEnter"를 할것입니다.
그 전에!! 함수를 만들기 전에!!
적 기체의 "Collider - Is Trigger 체크" 를 우선적으로 해줍니다.
이제 이 "Collider"는 스크립트에 의해서 제어가 됩니다.
지난번에 만들었던 "미사일이 혼자서 날라가는 스크립트"를 열어줍니다.
using UnityEngine; public class Player_Missile_Move : MonoBehaviour { public float MoveSpeed; // 미사일이 날라가는 속도 public float DestroyYPos; // 미사일이 사라지는 지점 // Use this for initialization void Start () { } // Update is called once per frame void Update () { // 매 프레임마다 미사일이 MoveSpeed 만큼 up방향(Y축 +방향)으로 날라갑니다. transform.Translate(Vector2.up * MoveSpeed * Time.deltaTime); // 만약에 미사일의 위치가 DestroyYPos를 넘어서면 if(transform.position.y >= DestroyYPos) { // 미사일을 제거 GetComponent().enabled = false; } } }
여기서 미사일이 제거되는 조건을 보시면
GetComponent().enabled = false;
이렇게 되어있습니다.
우리가 적 기체와 닿게되면 똑같이 이것을 이용해서 미사일을 메모리풀로 돌려보내게끔 할것입니다.
이제 OnTriggerEnter를 이용해서 코딩하여봅시다.
private void OnTriggerEnter2D(Collider2D collision) { }
(2D이기 때문에 2D가 붙습니다.)
함수는 위와 같이 생겼습니다.
이제 여기에 아까 생성한 태그를 이용하여 코딩하여봅시다.
private void OnTriggerEnter2D(Collider2D collision) { // 부딛히는 collision을 가진 객체의 태그가 "Enemy"일 경우 if (collision.CompareTag("Enemy")) { Debug.Log("적 기체와 충돌"); GetComponent().enabled = false; } }
미사일이 날라가다가 어떤 "Collider2D" 형태의 collision에 부딛히게 될때 발생하는 이벤트인데요.
그 collision의 객체가 가진 태그가 "Enemy"인 경우에 "적 기체와 충돌"이라는 로그를 남기면서 미사일을 제거하도록 하였습니다.
using UnityEngine; public class Player_Missile_Move : MonoBehaviour { public float MoveSpeed; // 미사일이 날라가는 속도 public float DestroyYPos; // 미사일이 사라지는 지점 // Use this for initialization void Start () { } // Update is called once per frame void Update () { // 매 프레임마다 미사일이 MoveSpeed 만큼 up방향(Y축 +방향)으로 날라갑니다. transform.Translate(Vector2.up * MoveSpeed * Time.deltaTime); // 만약에 미사일의 위치가 DestroyYPos를 넘어서면 if(transform.position.y >= DestroyYPos) { // 미사일을 제거 GetComponent().enabled = false; } } private void OnTriggerEnter2D(Collider2D collision) { // 부딛히는 collision을 가진 객체의 태그가 "Enemy"일 경우 if (collision.CompareTag("Enemy")) { Debug.Log("적 기체와 충돌"); GetComponent ().enabled = false; } } }
풀코드는 위와 같습니다.
이제 이 코드를 저장하고 지난번에 만든 "미사일 객체"로 갑시다.
이렇게 하여 함수 작업이 끝났습니다.
그런데 왜 "Kinematic"? 미사일은 움직이지 않나? |
움직이지만 우리는 스크립트 파일을 통해서 충돌의 순간만 감지할 것이기 때문입니다. |
확인하기 |
이제 게임을 시작해봅시다.
콘솔창은 "Ctrl + Shift + c"를 누르면 나옵니다.
충돌이 잘 처리되나요?
위의 링크에서 지금까지의 강의 진행상태 파일을 다운받을 수 있습니다.
다음 시간에는 |
미사일과 충돌된 적 기체를 제거하고, 에너지시스템에 대해서 알아보도록 하겠습니다.
'Study > Unity 5(유니티5)' 카테고리의 다른 글
유니티 5(Unity 5) 왕초보를 위한 간단한 비행기 슈팅게임 만들기(C#) - 10 [적 기체 제거] (4) | 2017.07.10 |
---|---|
유니티 5(Unity 5) 왕초보를 위한 간단한 비행기 슈팅게임 만들기(C#) - 08 [미사일 발사2] (9) | 2017.04.01 |
유니티 5(Unity 5) 왕초보를 위한 간단한 비행기 슈팅게임 만들기(C#) - 07 [미사일 발사1] (7) | 2017.03.12 |
유니티 5(Unity 5) 왕초보를 위한 간단한 비행기 슈팅게임 만들기(C#) - 06 [비행기 생성 및 움직이기] (1) | 2017.02.24 |
유니티 5(Unity 5) 왕초보를 위한 간단한 비행기 슈팅게임 만들기(C#) - 05 [게임의 요소 결정 및 구상] (0) | 2017.02.10 |