Unity Chapter 4-5. 소코반 게임 만들기 : 충돌 처리

Date:     Updated:

카테고리:

태그:

인프런에 있는 이제민님의 레트로의 유니티 C# 게임 프로그래밍 에센스 강의를 듣고 정리한 필기입니다. 😀
🌜 [레트로의 유니티 C# 게임 프로그래밍 에센스] 강의 들으러 가기!


Chapter 4. 소코반 게임 만들기 : 충돌 처리

물리적으로 부딪치진 않았어도 어떤 이벤트가 발생하도록.

ItemBox 오브젝트가 EndPoint 오브젝트에 물리적으로 닿으면 점수가 올라간다던지 등등 어떤 이벤트가 발생하도록 해줄 것이다. 현재 EndPoint 오브젝트의 Collider 컴포넌터의 Is Trigger 속성 값이 True이기 때문에 EndPoint와 물리적으로 부딪치지는 않지만 그래도 EndPoint에 도달하면 어떤 이벤트가 발생할 수 있도록 할 것이다.

EndPoint 오브젝트에 Tag 붙이기

게임 오브젝트를 분류하는 방법 중 하나. 오브젝트에 태그를 붙이면 특정 태그를 가진 오브젝트와 부딪쳤을 때 어떤 이벤트를 발생시키게끔 이런 식으로 연출할 수 있다.

  • EndPoint 오브젝트에 Tag를 붙여주자.
    1. EndPoint의 InsPector창에서 오브젝트 이름 바로 아래 있는 Tag를 눌러준다.
    2. Add Tag...를 눌러 나만의 태그를 붙여줄 것이다.
    3. +을 눌러서 추가해준다. 이름은 “EndPoint”로.
    4. 다시 Inspector 창으로 돌아와서 EndPoint 오브젝트의 Tag를 “EndPoint”로 바꿔준다.
    5. Apply all을 해주어 모든 EndPoint에 적용시킨다.


ItemBox 가 EndPoint와의 충돌을 처리할 수 있도록

  • “ItemBox” 라는 이름의 C#스크립트를 만들어 ItemBox 오브젝트에 붙인다.
    • cf) 그냥 ItemBox에다가 Add Component해서 이걸로 스크립트를 생성 후 붙여주는 방식도 있다. 스크립트도 컴포넌트니까!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemBox : MonoBehaviour
{
    void Start()
    {
        
    }

    void Update()
    {
        
    }

    void OnTriggerEnter(Collider other)
    {
        if(other.tag == "EndPoint")
        {
            Debug.Log("엔드 포인트에 도달");
        }
    }
}

  • void OnTriggerEnter(Collider other)
    • OnTriggerEnter : Trigger인 Collider와 충돌할 때 자동으로 실행된다.
      • Is Trigger체크된 Collider와 충돌하는 경우 발생되는 메세지
        • 즉 물리적 충돌은 일어나지 않고 뚫고 지나가지만 그래도 이벤트 발생은 시켜야 하는 경우.
    • 오브젝트끼리 충돌하면 유니티에서 OnTriggerEnter 메세지를 충돌한 오브젝트들 에게 브로드캐스팅 한다.
      • 충돌한 두 오브젝트끼리는 서로 독립적이고 연관이 없으니 서로 충돌한 사실을 모르지만
      • 두 오브젝트가 충돌하면 유니티에서 두 오브젝트에게 OnTriggerEnter 메세지를 뿌리므로 두 오브젝트는 OnTriggerEnter 함수 안에 구현한 내용대로 충돌 처리를 한다.
    • 유니티는 충돌한 상대 오브젝트의 정보를Collider타입의 other가 참조하도록 넘겨준다.
      • 충돌한 상대 오브젝트에 붙어있는 Collider 컴포넌트의 정보가 매개변수로 들어온다.
        • Collider 컴포넌트 -> 물리적 표면
    • EndPoint 오브젝트는 Is Trigger가 체크된 오브젝트이니 이 오브젝트와의 충돌을 처리하려면 이 함수를 써야한다.
      • Collider other는 충돌한 EndPoint 오브젝트에 붙어 있는 Collider 컴포넌트 정보를 참조하게 된다.
        • 유니티가 알아서 자동으로 이렇게 해줌
          void OnTriggerEnter(Collider other)
          {
          if(other.tag == "EndPoint")
          {
              Debug.Log("엔드 포인트에 도달");
          }
          }
          
    • if(other.tag == "EndPoint")
      • 충돌한 그 Collider의 오브젝트 Tag가 “EndPoint”라면
      • 즉 “EndPoint” 오브젝트와 충돌 했다면.
      • Trigger인 다른 오브젝트들과 차별화 하여 딱 특정 오브젝트와의 충돌을 처리할 때 태그로 구별하면 좋다.
    • 이 스크립트가 ItemBox 오브젝트에 붙어있으니, ItemBox 오브젝트와 Trigger Collider를 갖고 있는 EndPoint 오브젝트가 충돌하면 “엔드 포인트에 도달” 메세지를 출력할 것.


EndPoint와 충돌시 ItemBox의 색깔이 바뀌도록

  • Mesh Renderer
    • 오브젝트에게 그림을 그려주는 컴포넌트
    • 마치 물감 같은 컴포넌트
    • Material을 다룬다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemBox : MonoBehaviour
{
    private Renderer myRenderer; // 이 ItemBox에 붙어있는 Renderer 컴포넌트를 참조할 변수.

    void Start()
    {
        // 이 ItemBox에 붙어있는 Renderer 컴포넌트를 찾아 가져온다. private이라 유니티 슬롯이 안 열리니 GetComponent를 사용해야함.
        myRenderer = GetComponent<Renderer>(); 
    }

    void Update()
    {
        
    }

    void OnTriggerEnter(Collider other)  // Trigger를 가진 오브젝트(other)와 충돌시 
    {
        if(other.tag == "EndPoint")  // 충돌한 그 오브젝트의 태그가 "EndPoint"일시
        {
            myRenderer.material.color = Color.red; // ItemBox의 material(물감)의 색깔을 빨간색으로 바꿔준다.
            Debug.Log("엔드 포인트에 도달");
        }
    }
}


원래 ItemBox의 색깔 보존하기

  • EndPoint와의 충돌 상태가 풀리면 원래 색깔로 돌아가게 할 것이기 때문에 ItemBox의 원래 색을 보존해야 한다.
  • 그 충돌 상태가 풀릴 때는 유니티가 OnTriggerExit 메세지를 뿌린다.
    • void OnTriggerExit(Collider other): Trigger인 오브젝트와 붙어있다가 떼어지는 순간 실행되는 함수
      • 이 함수 안에 ItemBox가 EndPoint를 벗어나면 원래 색으로 돌아가게끔 구현 할 것이다.
  • Enter : 충돌 하는 순간
  • Exit : 떼어지는 순간
  • Stay : 충돌하는 동안, 붙어있는 동안
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ItemBox : MonoBehaviour
{
    private Renderer myRenderer; 

    public Color touchColor; // 충돌시 바뀔 색을 참조할 변수. public이라 유니티에서 언제든지 수정 가능
    private Color originalColor; // 원래 색을 참조할 변수. private이라 유니티에서 수정 불가능

    void Start()
    {
        myRenderer = GetComponent<Renderer>(); 
        originalColor = myRenderer.material.color; // Start()안에 해주므로써 게임 시작하자마자 원래색을 가져와 보존
    }

    void Update()
    {
        
    }

    void OnTriggerEnter(Collider other)  // Enter는 충돌을 한 순간
    {
        if(other.tag == "EndPoint")  
        {
            myRenderer.material.color = touchColor; 
        }
    }

    void OnTriggerExit(Collider other)  // Exit는 떼어지는 순간
    {
        if(other.tag == "EndPoint")  
        {
            myRenderer.material.color = originalColor; // 원래 색깔로 돌리기 
        }
    }

    void OnTriggerStay(Collider other)  // Stay는 붙어있는 동안
    {
        if(other.tag == "EndPoint")  
        {
            myRenderer.material.color = touchColor; 
        }
    }
}


기타 등등

  • ItemBox 너무 쉽게 밀려서 게임이 어려우니까 ItemBox의 Rigidbody에서 Drag를 10으로 높이자. 즉 마찰력을 높여 좀 뻑뻑하게 밀리게끔.
  • ✨ 같은 종류의 Prefab인 모든 오브젝트들에게도 적용하려면 항상 뭐 변경할 때마다 “Apply all” 꼭 해주는 습관 들이기 ✨


🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄

맨 위로 이동하기

Unity Lesson 1 카테고리 내 다른 글 보러가기

댓글 남기기