Unity - Rigidbody, Collider - 물리, 충돌 처리

2025. 10. 16. 18:28·Unity

Unity에서는 충돌 감지 시스템을 제공한다.

단순 감지 뿐 아니라 질량, 중력, 마찰, 탄성 등 물리적 특성까지 구현되어있다.

이러한 충돌 처리는 게임에서 수많은 상호작용에 사용되는 기능이므로 잘 이해하고 숙지해야 한다.

 

  • Rigidbody : 물리 연산의 주체. 질량, 중력, 속도, 회전력 등을 담당.
  • Collider : 물리적 충돌 영역을 정의. 모양에 따라 경계가 결정.

이 두 컴포넌트를 조합하여 물리 충돌 처리가 가능하다.

이번 글에서는 이 물리 충돌 처리에 관해 정리해볼 것이다.

 


 

Rigidbody

물리 시뮬레이션을 적용하기 위한 핵심 컴포넌트다.

게임 오브젝트가 중력에 영향을 받거나, 힘(충격)을 받아 움직이거나, 회전하는 모든 물리적 현상은 Rigidbody를 통해 계산된다.

 

주요 속성

Mass 질량 (기본 단위: kg). 무거울수록 동일한 힘에 덜 움직임. F=ma 계산에 사용. 기본값 1
Drag 선형 감속. 공기저항 등 외부 저항의 역할. 0이면 감속 없음.
Angular Drag 회전 감속. 회전 저항을 의미. 0이면 없음.
Use Gravity 체크 시 Unity의 전역 중력(Physics.gravity) 영향을 받음.
Is Kinematic 체크 시 외부 힘의 영향을 받지 않고, 스크립트로만 제어.
Interpolate 프레임 간 보간 처리. 물리 움직임의 부드러움을 결정. - None / Interpolate / Extrapolate
Collision Detection 충돌 검출 방식. (Discrete / Continuous 등 선택 가능)
Constraints 특정 축의 이동·회전 고정 (Freeze 옵션).

 

 

주요 메서드

AddForce(Vector3 force) 지정 방향으로 물리적 힘을 가함.
AddTorque(Vector3 torque) 회전력을 가함.
velocity 현재 물체의 선형 속도.
angularVelocity 현재 물체의 회전 속도.

 

주의 사항

Rigidbody는 프레임 단위가 아닌 "물리 연산 단위(Fixedupdate)"에서 계산된다.

Update()가 아닌 FixedUpdate() 내부에서 물리 제어 코드를 작성해야 한다.

 

 


 

Collider

오브젝트의 물리적 경계를 통해 충돌 범위를 정의하는 컴포넌트다.

실제 모델의 복잡한 메시에 관계없이, 단순한 형태의 Collider로 충돌 영역을 지정하는 게 일반적이지만

Mesh Collider를 통해 3D 모델의 실제 메시를 충돌체로 정의할 수 있다.

 

Box Collider 직육면체 형태. UI 버튼, 문, 벽 등에 사용.
Sphere Collider 구체 형태. 공, 폭탄, 구체형 오브젝트에 적합.
Capsule Collider 캡슐 형태. 사람형 캐릭터 충돌 범위에 자주 사용.
Mesh Collider 3D 모델의 실제 메시를 충돌체로 사용. (고비용)

 

IsTrigger : 체크시 실제 물리 충돌은 발생하지 않고 트리거 아벤트만 감지.

 

 


 

충돌 이벤트 : Collsion & Trigger

 

Collision (일반 충돌)

Collider + Rigidbody 가 물리적으로 맞닿았을 때 발생한다.

최소 한쪽은 IsKinematic이 비활성화되어 있어야 정상적으로 작동한다.

 

OnCollisionEnter(Collision col) 충돌 시작 시 1회 호출
OnCollisionStay(Collision col) 충돌 유지 중 매 프레임 호출
OnCollisionExit(Collision col) 충돌 종료 시 1회 호출

 

Collision 객체를 통해 충돌 지점, 법선, 충돌 대상 등 세부 정보를 얻을 수 있다.

 

예시 : 탄환과 부딪히면 대미지 입는 메서드 호출

void OnCollisionEnter(Collision collision)
{
    if(collision.gameObject.tag == "PlayerBullet")
    {
        TakeDamage();
    }
}

 

 

Trigger (감지 전용 충돌)

Collider의 IsTrigger가 활성화된 경우 발생한다.

실제 물리 충돌은 없지만, 오브젝트가 영역을 통과하는 것을 감지한다.

충돌로 인한 물리 이벤트가 포함되지 않는 대부분의 공격, 스킬, 아이템 상호작용 등은 이것을 통해 이루어진다.

 

OnTriggerEnter(Collider other) 트리거 영역 진입 시 1회 호출
OnTriggerStay(Collider other) 트리거 내부에 있는 동안 지속 호출
OnTriggerExit(Collider other) 트리거 영역을 벗어날 때 호출

 

예시 : 탄환의 Collider 영역에 Enemy 태그 보유 오브젝트가 들어오면 작동.

void OnTriggerEnter(Collider other)
{
    if (other.CompareTag("Enemy"))
    {
        Enemy enemy = other.GetComponent<Enemy>();
        if (enemy != null) enemy.TakeDamage(dmg);
        gameObject.SetActive(false);
    }
}

 

 

 

2D 물리

Unity는 3D물리와 별도로 완전 독립적인 2D 물리 엔진 (Box2D 기반)을 제공한다.

Rigidbody → Rigidbody2D Collider → Collider2D
BoxCollider → BoxCollider2D SphereCollider → CircleCollider2D
OnCollisionEnter → OnCollisionEnter2D OnTriggerEnter → OnTriggerEnter2D

 

 

+ 충돌 그룹을 관리하기 위해 Layer와 Tag를 활용할 수 있다.

 

 


 

문제 상황

 

오브젝트 풀링을 활용한 탄환 시스템에서, 단순히 전진하는 탄환이 아닌 AddForce 등 물리력을 구현하는 경우

void CountTime()
{
    _deactCount -= Time.deltaTime;
    if (_deactCount <= 0)
    {
        gameObject.SetActive(false);
    }
}

void ActivateAction()
{
    _deactCount = _deactiveTime;
    _rb.AddForce(transform.forward * _shotForce, ForceMode.Impulse);
}

 

이렇게 간단하게 카운트가 다 되면 비활성화 하는 메서드와 활성화 메서드를 정의할 수 있다.

활성화와 동시에 AddForce를 통해 rigidbody에 물리력을 가해서 포물선 운동처럼 발사하는 코드다.

 

문제는 이렇게 코드를 작성하면 비활성화 된 오브젝트에 여전히 이전 물리력이 남아있게 된다.

그래서 다시 활성화했을 때, 탄환이 Addforce와 이전 물리력을 합산받아 이상한 방향으로 발사되게 된다.

 

 

해결

해결법은 간단하다.

_rb.linearVelocity = Vector3.zero;

 

탄환이 활성화 혹은 비활성화 되는 순간에 rigidbody의 velocity를 초기화 해주면 해결된다.

혹은 탄환이 생성 될 때 Start 등을 통해 초기화 하는 방법도 있을 수 있다.

 

 


 

Tag 비교 팁

 

other.tag == "TagName"

 

이 방식은 런 타임 중string을 통해 비교하기 때문에 문자열 상수 검색과 비교가 일어나 약간의 오버헤드가 있고, 오타나 존재하지 않는 태그를 비교해도 에러 없이 통과된다.

other.CompareTag("TagName")

 

반면 이런식으로 CompareTag를 사용하면 내부적으로 태그 인덱스 기반 비교를 수행해 더 빠르고, 존재하지 않는 태그를 비교하면 에디터 경고를 발생시켜 안정성이 높다.

열거형처럼 존해자는 태그네임을 int값을 통해 탐색한다고 보면 된다.

 

즉 속도 + 안정성 면에서 후자가 훨씬 효율적이기에 IDE에서도 해당 코드 사용 권장 알림이 뜬다.

 

 

 

'Unity' 카테고리의 다른 글

Unity - EventSystem (이벤트 시스템)  (0) 2025.10.20
Unity - Coroutine, yield, Invoke, IEnumerator  (0) 2025.10.17
Unity - Transform, 위치 이동  (0) 2025.10.15
Unity - 오브젝트(Object), 컴포넌트(Component), 오브젝트 풀링(Object Pooling)  (0) 2025.10.14
Unity - 생명주기 (Life Cycle)  (1) 2025.10.13
'Unity' 카테고리의 다른 글
  • Unity - EventSystem (이벤트 시스템)
  • Unity - Coroutine, yield, Invoke, IEnumerator
  • Unity - Transform, 위치 이동
  • Unity - 오브젝트(Object), 컴포넌트(Component), 오브젝트 풀링(Object Pooling)
ellug
ellug
Web / App / Game Dev
  • ellug
    dev.ellug
    ellug
  • 전체
    오늘
    어제
    • 분류 전체보기 (95)
      • Javascript (React, Next) (1)
      • C# (66)
      • Graphics (1)
      • Unity (25)
      • 프로그래머스 (0)
        • Lv.0 (0)
        • Lv.1 (0)
        • Lv.2 (0)
        • Lv.3 (0)
      • AI Agent (0)
      • StableDiffusion (0)
      • ETC (1)
      • 잡담 (0)
      • 유머 (0)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    class
    알고리즘
    Queue
    네트워크
    Network
    Abstract
    게임
    큐
    Design Pattern
    콘솔
    스택
    inputsystem
    stack
    firebase
    delegate
    C#
    터미널
    interface
    console
    useState
    list
    최적화
    struct
    추상 클래스
    Photon
    unity
    클래스
    function
    유니티
    자료구조
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
ellug
Unity - Rigidbody, Collider - 물리, 충돌 처리
상단으로

티스토리툴바