[Unity] 2D 물리와 충돌

남이섬·2023년 3월 7일
0

Rigidbody 2D

오브젝트에 물리를 적용하고 중력을 받을 수 있도록 한다

물리관련 컴포넌트
2D : Component - Physics 2D
3D : component - Physics

Rigidbody 2D를 적용하면 중력은 바로 적용되지만 무리력에의한 이동, 회전, 마찰력과 같이 다른 오브젝트와의 상호작용이 필요한 경우 오브젝트에 충돌범위를 나타내는 Collider2D가 필요하다

Collider 2D

오브젝트의 충돌 범위를 나타낸다

Collider 종류

Box Collier 2D

사각형 범위 충돌 범위

  • Offset : 충돌 범위 중심점
  • Size : 충돌 범위 크기

Cicle Collider 2D

원 볌위의 충돌 범위, 연산 속도가 가장 빠름

  • Offset : 출돌 범위 줌심점
  • Radius : 충돌 범위 반지름 크기

Edge collider 2D

점의 개수, 각 점의 위치를 설정할 수 있기 때문에 다양한 곡선 형태로 충돌 범위 표현 가능 (주로 2D 게임의 바닥 충돌에 사용)

  • Offset : 충돌 범위 중심점
  • Edge Radius : 충돌 선의 두께
  • Points : 선을 이루는 점의 개수와 각 점의 위치

Polygon Collider 2D

텍스처의 모양과 비슷한 형태로 충돌 범위 생성 (Edge와 마찬가지로 Points 수정 가능)

  • Offset : 충돌 범위 중심점
  • Points : 선을 이루는 점의 개수와 각 점의 위치

Capsule Collider 2D

캡슐 모양의 충돌 범위 생성 (사람 형태의 캐릭터에 주로 사용)

  • Offset : 충돌 범위 중심점
  • Size : 충돌 범위 크기
  • Direction : 둥근 캡술이 표현되는 방향 (Vertical: 위/아래, Horizontal: 좌/우)

Composite Collider 2D

다른 게임오브젝트의 Collider 2D들을 하나로 묶어주는 역할 (Box Collider 2D, Polygon collider 2D만 사용가능)

Composite Collider 2D 사용법

  1. 빈 게임오브젝트 생성
  2. 생성한 게임오브젝트에 Composite Collider 2D 컴포넌트 추가 (Rigidbody2D 컴포넌트가 함께 추가)
  3. 하나로 묶고 싶은 Collider 2D 컴포넌트를 가지고 있는 게임 오브젝트들을 Composite Collider 2D 컴포넌트를 가지고 있는 게임오브젝트의 자식 오브젝트로 설정
  4. 자식 오브젝트들의 Collider 2D 컴포넌트에 있는 "Used By Composite" 변수 활성화

두 오브젝트가 충돌하려면

  • 두 오브젝트 모두 충돌 범위인 Collider2D 컴포넌트를 가지고 있어야 한다
  • 둘 중 하나 이상의 오브젝트가 물리 처리를 담당하는 Rigidbody2D 컴포넌트를 가지고 있어야 한다

Rigidbody2D는 오브젝트에 물리를 적용, 처리하는 클래스로 클래스 내무에 이동 관련 함수가 작도하고 있다
단지 이동 방향과 속도를 나타내는 속력(velocity)의 초기 값이 (0,0)이어서 움직이지 않는 것이다

코드와 같이 기존의 transform.position += 이동코드
Rigidbody2D에 있는 속력(velocity) 변수만 설정해주면 Rigidbody2D에 의해서 이동이 가능하다

모든 이동의 마지막에는 transform.position += 으로 위치를 변경하게 된다
다만 Rigidbody2D와 같이 "장애물을 만나게 되면 이동을 하지말고 그대로 멈춰라"와 같이 다양한 물리적 처리가 기반된 이동이 가능할 것이다

유니티에서 제공하는 물리 처리가 추가된 이동에는 Rigidbody2D, Rigidbody, CharacterController, NavMeshAgent와 같은 컴포넌트들이 있으며, 우리가 직접 작성하거나 에셋 스토어에서 다른 개발자가 만든 것을 사용할 수도 있다

게임 내에선 오브젝트가 단순히 충돌했다로 끝나는 것이 아닌, 충돌에 의해 함수가 호출되고, 함수에서 다양한 역할을 하게 된다 (아이템획득, 적 공격 등)

유니티에는 두 오브젝트가 충돌했을때 호출되는 함수가 있다

충돌관련 이벤트 함수

물리적 충돌이 일어나고나서 이벤트 함수 호출

OnCollisionEnter2D()

두 오브젝트가 출돌하는 순간 1회 호출

private void OnCollisionEnter2D(Collision2D collision)

OnCollisionStay2D()

충돌 직후 맞닿아 있는 동안 매 프레임 호출

private void OnCollisionStay2D(Collision2D collision)

OnCollisionExit2D()

두 오브젝트가 떨어져서 충돌이 종료되는 순간 1회 호출

private void OnCollisionExit2D(Collision2D collision)

매개변수 Collision2D collision

현재 컴포넌트를 가지고 있는 오프젝트에 부딪힌 오브젝트 정보

이벤트 함수 적용 코드

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CollisionEvent : MonoBehaviour
{
    [SerializeField]
    private Color             color;  
    private SpriteRenderer spriteRenderer;

    private void Awake()
    {
        spriteRenderer = GetComponent<SpriteRenderer>();
    }

    // <summary> 충돌이 일어나는 순간 1회 호출
    private void OnCollisionEnter2D(Collision2D collision)
    {
        spriteRenderer.color = color;
    }

    // <summary> 충돌이 유지되는 동안 매 프레임 호출
    private void OnCollisionStay2D(Collision2D collision)
    {
        Debug.Log(gameObject.name + " : OnCollisionStay2D() 메소드 실행");
    }

    // <summary> 충돌이 동료되는 순간 1회 호출
    private void OnCollisionExit2D(Collision2D collision)
    {
        spriteRenderer.color = Color.white;
    }

}

물리적 충돌이 없이 이벤트 함수 호출

OnTriggerEnter2D()

두 오브젝트가 충돌하는 순간 1회 호출

private void OnTriggerEnter2D(Collider2D collision)

OnTriggerStay2D()

충돌 직후 맞닿아 있는 동안 매 프레임 호출

private void OnTriggerStay2D(Collider2D collision)

OnTriggerExit2D()

두 오브젝트가 떨어져서 충돌이 종료되는 순간 1회 호출

private void OnTriggerExit2D(Collider2D collision)

매개변수 Collider2D collision

현재 컴포넌트를 가지고 있는 오프젝트에 부딪힌 오브젝트 정보

이벤트 함수 적용 코드

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TriggerEvent : MonoBehaviour
{
    [SerializeField]
    private GameObject moveObject;
    [SerializeField]
    private Vector3    moveDirection;
    // private float moveSpeed = 5.0f;
    private float      moveSpeed;

    private void Awake()
    {
        moveSpeed = 5.0f;
    }

    // <summary> 충돌이 일어나는 순간 1회 호출
    private void OnTriggerEnter2D(Collider2D collision)
    {
        // moveObject 오브젝트의 색상을 검은색(Color.black)으로 설정한다
        moveObject.GetComponent<SpriteRenderer>().color = Color.black;
    }

    // <summary> 충돌이 유지되는 동안 매 프레임 호출
    private void OnTriggerStay2D(Collider2D collision)
    {
        // moveObject 오브젝트를 moveDirection 방향으로 이동한다
        Debug.Log(moveDirection);
        moveObject.transform.position += Vector3.right * moveSpeed * Time.deltaTime;
        Debug.Log(moveObject.transform.position += moveDirection * moveSpeed * Time.deltaTime);
    }

    // <summary> 충돌이 종료되는 순간 1회 호출
    private void OnTriggerExit2D(Collider2D collision)
    {
        // moveObject 오브젝트의 색상을 휜색(Color.white)으로 설정한다
        moveObject.GetComponent<SpriteRenderer>().color = Color.white;

        // moveObject 오브젝트의 위치를 (0, 4, 0)으로 설정한다
        moveObject.transform.position = new Vector3(-0.04f, -7.6f, -0.15f);
    }
}

내가 소속된 게임오브젝트의 컴포넌트 정보
GetComponent<컴포넌트>()

내가 아닌 다른 게임오브젝트의 컴포넌트 정보
게임오브젝트.GetComponent<컴포넌트>()

다른 게임오브젝트의 정보는 코드와 같이 미리 변수를 만들어서 게임오브젝트 정보를 저장해두고 사용할 수도 있고, 유니티에서 제공하는 함수를 이용해 탐색할 수도 있다

profile
즐겁게 살자

0개의 댓글