상세 컨텐츠

본문 제목

[C#, Unity] 등록된 함수 순차 자동 호출 : Delegate, event, UnityEvent

유니티

by simstealer 2022. 9. 28. 17:51

본문

Delegate : 메서드를 보관하는 통을 만들고 그 통안에 메서드들을 필요할 떄 가져와 사용할 수 있다.

 

// Chain
// 하나의 델리게이트에 여러 함수를 참조시켜 
// 델리게이트 객체를 한번의 실행으로 등록된 모든 함수들을 순차적으로 실행할 수 있습니다.

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

public class DelegateMain : MonoBehaviour
{
    // Delegate 선언
    public delegate void MyDelegate();
    
    // Delegate 객체 만들기
    MyDelegate myDelegate;

    private void Start()
    {
    	// Delegate 객체에 하나의 메서드 등록
        myDelegate = new MyDelegate(Print1);
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.S))
        {
        	// 아래와 같은 방식으로 등록된 모든 메서드를 호출할 수 있다.
            myDelegate.Invoke();
        }

        if (Input.GetKeyDown(KeyCode.A))
        {
        	// 여러개의 메서드를 추가 하고 삭제할 수 있다
            myDelegate += new MyDelegate(Print2);
            myDelegate += new MyDelegate(Print3);
        }

    }

    // 테스트 호출 함수
    public void Print1()
    {
        Debug.Log("호출 1");
    }
    public void Print2()
    {
        Debug.Log("호출 2");
    }
    public void Print3()
    {
        Debug.Log("호출 3");
    }

}

 

Delegate Event : 느슨한 커플링을 위해서 사용된다. 선언한 클래스 외부에서는 호출이 불가능하고 Delegate 선언부가 public이면 외부에서도 사용가능하다 다만, = (대입) 연산자는 불가능한다.

// delegate Event를 선언할 스크립트

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

public class Character : MonoBehaviour
{
    public static Character instance;

    private void Awake()
    {
        instance = this;
    }

    // 부스터 관련된 함수가 저장될 Delegate
    public delegate void Boost(Character target);
    
    // 생성한 delegate 타입으로 이벤트 객체를 생성한다.
    public event Boost boost;

    public string playerName = "Player";
    public float hp = 1000;
    public float defense = 500;
    public float damage = 10;

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.T))
        {
            boost.Invoke(this);
        }
    }
}
// Charactor에 선언된 Delegate Event에 메서드를 등록할 스크립트

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

public class Booster : MonoBehaviour
{
    public void HealthBoost(Character target)
    {
        Debug.Log(target.playerName + "의 체력을 강화");
        target.hp += 10;
    }

    public void ShieldBoost(Character target)
    {
        Debug.Log(target.playerName + "의 방어력을 강화");
        target.defense += 10;
    }

    public void DamageBoost(Character target)
    {
        Debug.Log(target.playerName + "의 공격력을 강화");
        target.damage += 10;
    }

    private void Start()
    {
    	메서드 등록 과정
        Character.instance.boost += HealthBoost;
        Character.instance.boost += ShieldBoost;
        Character.instance.boost += DamageBoost;
    }
}

UnityEvent : delegate과 동일하지만 다른 내용의 메서드도 등록가능하다.

// UnityEngine를 활용

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

public class Character : MonoBehaviour
{
    public static Character instance;

    private void Awake()
    {
        instance = this;
    }

	public string playerName = "Na";
    public float hp = 100;
    public float defense = 50;
    public float damage = 30;
    
    // UnityEvent 선언과 동시에 객체 생성, 메서드가 등록될 통이다.
    public UnityEvent playerBuf = new UnityEvent();

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.T))
        {
            playerBuf.Invoke();
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Booster : MonoBehaviour
{
    public void HealthBuf(int a)
    {
        Debug.Log(a);
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Y))
        {
            // UnityEvent를 활용한 메서드 등록
            Character.instance.playerDead.AddListener(() => HealthBoost(1));
            // 메서드 삭제
            //Character.instance.playerDead.RemoveListener(() => HealthBoost(1));
        }
    }
}

'유니티' 카테고리의 다른 글

[C#] Action, Func  (0) 2022.09.29
[Unity] 유니티 - JSON 데이터 저장, 불러오기  (0) 2022.09.29
[Unity] Player, Camera 회전  (0) 2022.09.21
[Unity] Player 이동하기  (0) 2022.09.21
[Unity] Target 지정해서 이동하기  (0) 2022.09.21

관련글 더보기

댓글 영역