본문 바로가기
개발/Unity

유니티 - Action으로 이벤트 등록하기 (Register Method with Action)

by 피로물든딸기 2022. 7. 29.
반응형

Unity 전체 링크

 

프로퍼티를 이용하면 변수가 변경될 때 이벤트를 발생할 수 있다.

 

Action은 반환값이 없는 메서드를 등록할 수 있는 델리게이트다.

 

Action을 사용하기 위해서는 System을 선언해야 한다.
큐브를 만들고 아래의 스크립트를 추가하자.

using System; /* for Action */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ActionCube : MonoBehaviour
{
    public Action gameOverEvent;
    public Action<string> stringEvent;
    
    void gameOver()
    {
        Debug.Log("Cube Game Over");
    }

    void gameOverMessage(string msg)
    {
        Debug.Log("Game Over : " + msg);
    }

    void Start()
    {
        // 함수의 이름만 추가, ()는 필요없음.
        gameOverEvent += gameOver; // void 함수만 추가 가능.
        gameOverEvent += gameOver; // 같은 함수 여러 번 등록 가능.
        gameOverEvent += gameOver;

        //gameOverEvent += gameOverMessage("msg"); // 파라미터가 있는 경우는 불가능.

        gameOverEvent += () => gameOverMessage("Message 1"); // 익명 함수를 이용하면 가능.
        gameOverEvent += () => gameOverMessage("Message 2");
        gameOverEvent += () => gameOverMessage("Message 3");

        // 또는 string을 받는 Action을 선언.
        stringEvent += (str) => gameOverMessage(str);

        gameOverEvent -= gameOver; //빼는 것도 가능.
        gameOverEvent -= () => gameOverMessage("Message 2"); // 익명 함수는 삭제 불가
    }

    void OnMouseDown()
    {
        gameOverEvent();
        stringEvent("Action<string>!!");
    }
}

 

그리고 Sphere를 만들어서 아래의 코드를 추가하자.

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

public class ActionSphere : MonoBehaviour
{
    public ActionCube ac;

    void gameOverSphere()
    {
        Debug.Log("GameOverSphere!!");
    }

    void Start()
    {
        ac.gameOverEvent += gameOverSphere;
    }
}

 

ac에는 아까 만든 큐브를 추가하면 된다.


Action에는 return 타입이 없는(void) 함수만 등록 가능하다.

ActionCube에는 두 개의 메서드가 있다.

    void gameOver()
    {
        Debug.Log("Cube Game Over");
    }

    void gameOverMessage(string msg)
    {
        Debug.Log("Game Over : " + msg);
    }

 

gameOver 메서드는 += 를 이용해서 gameOverEvent Action에 추가할 수 있다.

여러 번 추가하면 여러 번 실행된다.

    // 함수의 이름만 추가, ()는 필요없음.
    gameOverEvent += gameOver; // void 함수만 추가 가능.
    gameOverEvent += gameOver; // 같은 함수 여러 번 등록 가능.
    gameOverEvent += gameOver;

 

gameOverMessage는 string을 인자로 받는다. 따라서 Action에 추가할 수 없다.

하지만 익명 함수를 이용하면 제한된 범위로 메서드를 추가할 수 있다.

익명 함수는 람다식으로 등록할 수 있다.

    //gameOverEvent += gameOverMessage("msg"); // 파라미터가 있는 경우는 불가능.

    gameOverEvent += () => gameOverMessage("Message 1"); // 익명 함수를 이용하면 가능.
    gameOverEvent += () => gameOverMessage("Message 2");
    gameOverEvent += () => gameOverMessage("Message 3");

 

이렇게 등록하면 gameOverMessage에 "Message 4"를 넣지는 못하지만, 

Messge 1이라고 출력하는 gameOverMessage는 아래와 같은 함수가 되므로 등록이 가능하게 된다.

    void gameOverMessage()
    {
        Debug.Log("Game Over : " + "Message 1");
    }

 

또는 Action<string>으로 만들면 string을 받는 함수는 등록할 수 있다.

    public Action<string> stringEvent;
    
    // 또는 string을 받는 Action을 선언.
    stringEvent += (str) => gameOverMessage(str);

 

등록된 함수는 삭제할 수 있지만, 익명 함수는 불가능하다.

    gameOverEvent -= gameOver; //빼는 것도 가능.
    gameOverEvent -= () => gameOverMessage("Message 2"); // 익명 함수는 삭제 불가

 

외부 스크립트의 함수도 당연히 등록 가능하다. (ActionSphere.cs)

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

public class ActionSphere : MonoBehaviour
{
    public ActionCube ac;

    void gameOverSphere()
    {
        Debug.Log("GameOverSphere!!");
    }

    void Start()
    {
        ac.gameOverEvent += gameOverSphere;
    }
}

 

이제 큐브를 클릭하면 Action에 등록된 모든 함수가 실행된다.

    void OnMouseDown()
    {
        gameOverEvent();
        stringEvent("Action<string>!!");
    }

 

큐브를 클릭하면 아래의 로그가 나오게 된다.

 

외부에서 등록한 이벤트인 gameOverSphere가 실행되었다.

gameOver는 3번 등록 후, 1번 제거하여서 2번 실행되었다.

gameOverMessage("Message 2")는 삭제가 되지 않았다.

stringEvent에 등록된 함수는 string을 받은 후 정상 실행되었다.


event 키워드

 

gameOverEvent는 외부 클래스인 ActionSphere에서도 실행이 가능하다.

    void Start()
    {
        ac.gameOverEvent += gameOverSphere;
        ac.gameOverEvent();
    }

 

하지만 event 키워드를 추가하면 외부에서 접근이 불가능하다.

    public event Action gameOverEvent;

 

아래와 같이 등록은 가능하지만 실행은 오직 ActionCube에서만 가능하다. 

event 키워드로 인해 외부 클래스에서 사용할 경우 컴파일 에러를 발생시킨다.


Action에 등록할 함수 중복 방지

 

Action은 중복된 함수도 등록할 수 있다.

따라서 등록 전에 한 번 빼고 등록하면 간단히 중복을 방지할 수 있다.

gameOverEvent -= gameOver;
gameOverEvent += gameOver;

 

gameOverMessage("Message 2")를 삭제했을 때, 아무 문제가 발생하지 않은 것을 봤듯이, 

등록되지 않은 함수를 빼도 에러가 발생하지 않는다.

 

Unity Plus:

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Unity Pro:

 

Unity Pro

The complete solutions for professionals to create and operate.

unity.com

 

Unity 프리미엄 학습:

 

Unity Learn

Advance your Unity skills with live sessions and over 750 hours of on-demand learning content designed for creators at every skill level.

unity.com

반응형

댓글