본문 바로가기
C#/Unity

유니티 MonoBehaviour 클래스 활용법 : 생명주기, 이벤트, 컴포넌트 접근 등

by GangDev 2024. 4. 19.

MonoBehaviour 클래스는 유니티에서 스크립팅을 위한 기본 클래스이다.

이 클래스는 게임 오브젝트에 스크립트를 추가하여 게임의 다양한 기능을 구현하는 데 사용된다.

MonoBehaviour는 유니티 엔진의 코어 기능을 확장하고, 게임 오브젝트의 생명주기를 관리하며, 게임 오브젝트와 상호작용하는 데 필요한 많은 메서드와 속성을 제공한다.

 

주요 특징으로는 다음과 같은 것들이 있다:

* 생명주기 메서드:

MonoBehaviour는 게임 오브젝트의 생명주기를 관리하는 데 사용되는 여러 메서드를 제공한다.

예를 들어, Start, Update, FixedUpdate, OnEnable, OnDisable 등의 메서드는 게임 오브젝트가 씬에 추가되거나, 활성화/비활성화될 때, 또는 프레임마다 호출된다.

이러한 메서드를 오버라이드하여 게임 오브젝트의 동작을 제어할 수 있다.

 

* 이벤트 함수:

MonoBehaviour는 다양한 이벤트에 대응하는 데 사용되는 메서드를 제공한다.

예를 들어, OnCollisionEnter, OnTriggerEnter, OnMouseDown 등의 메서드는 게임 오브젝트가 다른 오브젝트와 충돌하거나, 트리거 영역에 들어가거나, 마우스 클릭 이벤트가 발생할 때 호출된다.

이를 통해 게임 오브젝트의 상호작용을 구현할 수 있다.

 

* 컴포넌트 접근:

MonoBehaviour를 상속받는 스크립트 내에서는 GetComponent, GetComponents, GetComponentInChildren, GetComponentsInChildren e응의 메서드를 사용하여 게임 오브젝트에 연결된 컴포넌트에 접근할 수 있다.

이를 통해 게임 오브젝트의 다양한 기능을 제어하고 확장할 수 있다.

 

* 메시지 전달:

MonoBehaviour는 SendMessage, BroadcastMessage 등의 메서드를 통해 게임 오브젝트 간에 메시지를 전달할 수 있다.

이를 통해 게임 오브젝트 간의 상호작용을 구현하고, 특정 이벤트가 발생했을 때 다른 게임 오브젝트에 알림을 보낼 수 있다.

 

* 코루틴:

MonoBehaviour는 StartCoroutine, StopCoroutine, StopAllCoroutines 등의 메서드를 제공하여 코루틴을 관리할 수 있다.

코루틴은 시간에 따라 실행되는 코드 블록으로, 게임의 다양한 비동기 작업을 구현하는 데 사용된다.

 

SendMessage

SendMessage 메서드는 유니티에서 게임 오브젝트 간의 통신을 위해 사용되는 메서드다.

이 메서드를 사용하면 특정 게임 오브젝트에 연결된 스크립트 중 하나 이상에서 메서드를 호출할 수 있다.

그러나 이 메서드는 유연성과 편의성을 제공하는 대신, 코드의 가독성과 유지보수성을 저해할 수 있으므로, 가능한 한 명시적인 참조를 사용하는 것이 좋다.

 

SendMessage는 게임 오브젝트에 연결된 모든 MonoBehaviour 컴포넌트에서 지정된 메서드 이름을 가진 메서드를 호출한다.

호출되는 메서드는 인자를 무시하고 0개의 파라미터를 가질 수 있다.

또한, SendMessageOptions.RequireReceiver 옵션을 설정하면, 메시지가 어떤 컴포넌트에도 의뢰되지 않았을 때 오류 메시지가 출력된다.

 

 

예시 >>

다음은SendMessage를 사용하여 게임 오브젝트에 연결된 스크립트에서 메서드를 호출하는 예시다.

이 예시에서는 Example 스크립트에서 ApplyDamage 메서드를 호출하고, 이 메서드는 Example2 스크립트에 정의되어 있다.

using UnityEngine;

public class Example : MonoBehaviour
{
    void Start()
    {
        // 게임 오브젝트에 연결된 모든 스크립트 중에서
        // "ApplyDamage" 메서드를 호출하고, 인자로 5.0을 전달
        gameObject.SendMessage("ApplyDamage", 5.0f);
    }
}

public class Example2 : MonoBehaviour
{
    public void ApplyDamage(float damage)
    {
        // 데미지 값을 출력
        Debug.Log(damage);
    }
}

 

주의점 >>

* 비활성화된 오브젝트에 메시지 전송: SendMessage는 비활성화된 게임 오브젝트에 메시지를 전송하지 않는다. 즉, 게임 오브젝트가 편집기에서 비활성화되었거나 SetActive 함수를 통해 비활성화된 경우, 해당 오브젝트에 연결된 스크립트는 SendMessage를 통해 호출되지 않는다.

 

* 메서드 이름의 대소문자 구분: SendMessage는 메서드 이름의 대소문자를 구분하지 않는다. 따라서, 메서드 이름을 정확히 입력해야 한다.

 

* 메서드 존재 여부: SendMessageOptions.RequireReceiver 옵션을 사용하면, 호출하려는 메서드가 대상 게임 오브젝트에 존재하지 않을 경우 오류 메시지가 출력된다. 이는 메시지가 의도치 않게 무시되는 것을 방지하기 위한 방법이다.

 

SendMessage 대안

SendMessage 메서드 외에도 유니티에서 게임 오브젝트 간의 통신을 구현하는 데 사용할 수 있는 여러 대안이 있다.

이러한 방법들은 코드의 구조화, 유지보수성, 성능 등을 고려하여 선택할 수 있다.

 

이벤트 매니저 사용하기 >>

이벤트 매니저는 게임 오브젝트 간의 통신을 중앙에서 관리하는 방법이다.

이벤트 매니저를 사용하면, 게임 오브젝트는 특정 이벤트를 듣고, 다른 게임 오브젝트는 해당 이벤트를 발생시킬 수 있다.

이 방법은 게임 오브젝트 간의 직접적인 참조를 줄이고, 코드의 유연성을 높인다.

// 이벤트 매니저 사용 예시
EventManager.StartListening("jump", someFunction);
EventManager.TriggerEvent("jump");

 

직접적인 참조 전달 >>

게임 오브젝트  A가 게임 오브젝트 B를 생성하고, 게임 오브젝트 C의 참조를 B에게 전달하는 방법이다.

이 방법은 게임 오브젝트 간의 직접적인 통신을 가능하게 하며, 코드의 구조화를 높인다.

// 직접적인 참조 전달 예시
public class ScriptA : MonoBehaviour {
    public ScriptC c;

    void SpawnB() {
        B.setC(c); // 스크립트 C에 대한 B의 변수는 A에서 전달됨
    }
}

public class ScriptB : MonoBehaviour {
    ScriptC c;

    void setC(ScriptC v) {
        c = v;
    }
}

 

델리게이트와 이벤트 사용하기 >>

델리게이트와 이벤트를 사용하여 게임 오브젝트 간의 통신을  구현할 수 있다.

이 방법은 유연성과 확장성을 높이며, 게임 오브젝트 간의 직접적인 참조를 줄일 수 있다.

// 델리게이트와 이벤트 사용 예시
public delegate void MyEventHandler(string message);
public static event MyEventHandler OnMyEvent;

void TriggerEvent() {
    if (OnMyEvent != null) {
        OnMyEvent("Hello, world!");
    }
}

 

스크립팅 오브젝트 사용하기 >>

유니티의 스크립팅 오브젝트를 사용하여 게임 오브젝트 간의 통신을 구현할 수 있다.

이 방법은 게임 오브젝트 간의 직접적인 참조를 줄이고, 코드의 모듈화를 높인다.

이 방법은 특히 게임의 다양한 부분에서 공통적으로 사용되는 이벤트나 데이터를 관리하는 데 유용하다.

스크립팅 오브젝트를 사용하면, 게임 오브젝트는 이 오브젝트를 통해 필요한 정보를 얻거나, 필요한 작업을 수행할 수 있다.

 

예시 :

 

스크립트 오브젝트를 생성한다.

이를 위해 새로운 스크립트를 작성하고, 이 스크립트를 게임 오브젝트에 연결한다.

이 스크립트는 게임 오브젝트 간의 통신을 관리하는 역할을 한다.

using UnityEngine;

public class ScriptingObject : MonoBehaviour
{
    // 이 스크립트는 게임 오브젝트 간의 통신을 관리한다
}

 

스크립팅 오브젝트를 통해 게임 오브젝트 간의 통신을 구현하기 위해, 스크립팅 오브젝트에 필요한 메서드나 데이터를 정의한다.

예를 들어, 게임 오브젝트가 특정 이벤트를 발생시키고, 다른 게임 오브젝트가 이 이벤트를 받아서 처리하는 방식을 구현할 수 있다.

using UnityEngine;

public class ScriptingObject : MonoBehaviour
{
    // 이벤트를 발생시키는 메서드
    public void TriggerEvent()
    {
        Debug.Log("이벤트가 발생했습니다.");
    }
}

 

게임 오브젝트에서 스크립팅 오브젝트를 사용하기 위해, 스크립팅 오브젝트에 대한 참조를 가져와야 한다.

이를 위해 GameObject.Find 메서드를 사용하여 스크립팅 오브젝트를 찾거나, 스크립팅 오브젝트를 인스펙터에서 직접 할당할 수 있다.

using UnityEngine;

public class Example : MonoBehaviour
{
    public ScriptingObject scriptingObject; // 인스펙터에서 설정

    void Start()
    {
        // 스크립팅 오브젝트를 통해 이벤트를 발생시킨다.
        scriptingObject.TriggerEvent();
    }
}