Machineboy空
충돌 처리 - RayCast, Collider, Rigidbody, OnCollisionEnter, OnTriggerEnter 본문
Game/Unity
충돌 처리 - RayCast, Collider, Rigidbody, OnCollisionEnter, OnTriggerEnter
안녕도라 2024. 10. 30. 12:38유니티 물리 엔진은 크게 2D용과 좀 더 복잡한 3D용으로 나뉜다. 물리 엔진은 게임에 생명을 불어넣고, 게임을 좀 더 자연스럽게 만든다. 개발자는 물리 엔진을 사용해 빠르고 쉽게 자연스러운 반응을 하는 새 오브젝트를 추가할 수 있다.

충돌 감지 과정에 쓰이는 함수
Ray
Ray ray = new Ray(Camera.main.transform.position, Camera.main.transform.forward);
- 방향을 가진 빛의 광선
- 쏘아지는 선이나 직선을 의미하며, 충돌을 테스트하기 위하여 사용
RayCastHit
RaycastHit hitInfo;
bombFX.transform.position = hitInfo.point;
- ray가 닿은 곳을 의미하며, 충돌에 관련한 정보들을 담고 있다.
Physics.Raycast
RaycastHit hitInfo;
if(Physics.Raycast(ray, out hitInfo, float.MaxValue, layer)){
GameObject bulletImpact = Instantiate(bulletImpactFactories);
bulletImpact.transform.position = hitInfo.point;
bulletImpact.transform.forward = hitInfo.normal;
}
- Ray: 터치에 의해 선을 쏜다.
- RaycastHit: 충돌 관련한 오브젝트를 레퍼런스한다.
- Distance: 충돌 검색을 실행할 최대한의 범위를 의미한다.
- Mask: 마스크는 충돌을 체크해야 하는 레이어를 결정한다.
public bool RegisterHitGameObject(PointerEventData data){
int mask = BuildLayerMask();
Ray ray = Camera.main.ScreenPointToRay(data.position);
RaycastHit hitInfo;
if(Physics.Raycast(ray, out hitInfo, Mathf.Infinity, mask)){
print("Object Hit" +
hitInfo.collider.gameObject.name);
var go = hitInfo.collider.gameObject;
HandleHitGameObject(go);
return true;
}
return false;
}
raycast함수는 콜라이더(collider)를 가진 오브젝트와 충돌을 체크한다.
*out에 관하여
Call by Reference | Call by Value |
원본 복사 | 복사본 복사 |
사물함에 넣어두고 사물함 번호를 알려주는 방법 | |
ref, out을 활용 |
//01. 보통 함수
int num = 5;
static void ChangeNum(int a)
{
a = 10;
}
ChangeNum(num);
ConSole.WriteLine(num);
// num = 5; <<값이 변경되지 않았다.
// 이유: 함수 바깥 scope != 함수 내 scope 다른 공간으로 인식
//02. ref 이용 함수
int num = 5; // 5를 할당해주지 않으면 문제가 생긴다.
static void RefNum(ref int a)
{
a=10;
}
RefNum(ref num);
Console.WriteLine(num);
// num = 10;
// ref 사용하여 함수 내 scope에 접근
//03. out 이용 함수
int num =5; // 5를 굳이 할당해줄 필요가 없다!
static void OutNum(out int num)
{
num = 10;
}
OutNum(out num);
Console.WriteLine(Num);
// num = 10;
// out 이용하여 함수 내에서 함수 외부 scope로 접근
https://yeko90.tistory.com/entry/c-%EA%B8%B0%EC%B4%88-ref-vs-out-%EC%B0%A8%EC%9D%B4
[c# 기초] ref vs out 차이
이번 포스팅에서는 비슷한듯 다르게 보이는 ref와 out차이를 알아보도록 하겠습니다. 그 전에 이를 제대로 이해하기 위해선 ref를 이용한 함수와 이용하지 않은 보통 함수에 대한 이해가 선행 되
yeko90.tistory.com
충돌 감지를 위해 필요한 컴포넌트
오브젝트의 물리를 판단하기 위해 리지드바디와 콜라이더 컴포넌트는 꼭 필요하다. 다음은 각 컴포넌트가 무엇을 담당하고 서로 어떻게 연관돼 있는지 간략히 요약한 내용이다.
RigidBody
- 오브젝트의 질량과 관련된 속성을 정의한다고 이해하면 된다.
- 중력에 반응하는지, 질량은 얼마인지, 얼마나 쉽게 회전하는지
Collider
- 일반적으로 오브젝트의 경계를 정의하는 단순한 도형이다.
- 빠르게 충돌을 감지하기 위해 박스, 구체, 캡슐과 같은 단순한 도형이 사용된다.
- 좀 더 복잡한 메시(mesh) 혹은 실제 캐릭터 메시와 같이 복잡한 형태를 사용하는 경우 충돌을 체크할 때마다 물리 엔진이 부하를 줘서 멈춰버릴 수도 있다.
- 물리 엔진은 매 프레임마다 오브젝트들이 서로 충돌했는지를 체크한다.
- 오브젝트들끼리 충돌한 경우에는 뉴턴의 운동 법칙을 사용해서 충돌의 영향을 판단한다.
- 좀 더 복잡한 게임의 경우 몸통과 신체 여러 부분에 여러 개의 캡슐 콜라이더를 사용하여, 각 신체 부분에 대한 충돌을 감지하기도 한다.
충돌 체크
유니티 물리 엔진에 오브젝트끼리 충돌할 때 사용할 수 있는 기본 메소드들
OnCollisionEnter
- 오브젝트에 콜라이더가 있고, 콜라이더를 가진 또 다른 오브젝트와 충돌하는 경우
- 두 오브젝트는 접촉한 후, 한 개나 두 개의 오브젝트 모두 리지드바디를 가지고 있으면 충돌의 힘에 따라 서로를 밀어낸다.
- 충돌을 위해 리지드바디가 필요하지 않지만 콜라이더는 필요하다.
OnTriggerEnter
- 오브젝트에 콜라이더가 있지만 콜라이더가 트리거로 설정돼 있는 경우
- 트리거로 설정돼 있는 콜라이더는 충돌을 감지하지만 두 오브젝트가 서로 지나치게 한다.
- 문이나 포털처럼 오브젝트가 들어오는 순간을 감지하고 싶을 때 유용하다.
충돌 오브젝트간 스크립트 구성 팁

- CollisionAction
- 다른 오브젝트와 부딪히는 볼이나 총알같은 오브젝트에 첨부한다.
- 스크립트는 충돌을 감지하고 CollisionReaction을 가진 오브젝트에 충돌을 알려준다.
- CollisionReaction
- 오브젝트와 충돌할 떄 일어나는 여러 가지 일들을 처리한다.
//CollisionAction
void OnCollisionEnter(Collision collision){
if(disarmed == false){
reactions = collision.gameObject.GetComponents<CollisionReaction>();
if(reactions != null && reactions.Length() >0){
foreach(var reaction in reactions){
if(gameObject.name.StartWith(reaction.collisionObjectName)){
reaction.OnCollisionReaction(gameObject, collision);
}
}
}
}
}
//CollisionReaction
public void OnCollisionReaction(GameObject go, Collision collision){
ContactPoint contact = collision.contacts[0];
Quaternion rot = Quaternion.FromToRatation(Vector3.up, contact.normal);
Vector3 pos = contact.point;
if(particlePrefab != null){
var particle = (Transform)Instantiate(particlePrefab, pos, rot);
Destroy(particle.gameObject, destroyParticleDelaySeconds);
}
if(destroyObject){
Destroy(go, destroyObjectDelaySeconds);
}
collisionEvent.Invoke(gameObject, collision);
}
'Game > Unity' 카테고리의 다른 글
아트관련 자료 모음집 (셰이더, 애니메이션, 오디오, 텍스쳐링 등) (1) | 2024.10.30 |
---|---|
인벤토리(inventory)시스템, SQLite4Unity3D (0) | 2024.10.30 |
싱글톤 패턴(Singleton Pattern) (1) | 2024.10.30 |
Unity 콘솔, OOP에 관련하여 (1) | 2024.09.27 |
Unity 최적화 관련 (1) | 2024.09.27 |