delegate란 함수에 대한 참조
하나의 델리게이트로 여러개의 함수를 접근하여 실행을 할수있습니다. 함수를 파라미터로 전달할 수 있고 여러개의 함수를 한번에 실행하는 체인기능, 어떠한 상황에 대한 이벤트를 발생 할수도 있습니다.
쉽게 말해 대리자(일을 대신해줄 비서를 만듬)
하지만 이 비서는 정해준 일 밖에 하지 못한다.
ex) delegate 리턴타입 델리게이트명(매개변수..)
delegate int Calculator(int numA, int numB);
int Add(int numA, int numB)
{
return numA + numB;
}
int Sub(int numA, int numB)
{
return numA - numB;
}
void Start()
{
Calculator calculator = new Calculator(Add);
Debug.Log(calculator(15,30));
}
델리게이트는 리턴타입과 매개변수가 모두 일치해야한다 ,
Add , Sub 함수의 형태와 같습니다. 참조변수와 같기 때문에 객체를 생성하고 , 괄호 안에는 참조할 함수를 넣는게 델리게이트의 기본 사용법 입니다.
delegate int Calculator(int numA, int numB);
int Add(int numA, int numB)
{
return numA + numB;
}
int Sub(int numA, int numB)
{
return numA - numB;
}
int Action(int numA, int numB, Calculator calculator)
{
return calculator(numA, numB);
}
void Start()
{
int Num = Action (10, 20, Add)
Debug.Log(Num);
}
Action이라는 함수에 파라미터에 델리게이터를 통해 함수를 참조로 넘기게 된다!
Add로 함수의 참조 객체를 전달해 출력된 값은 더하기 연산이 나온다.
델리게이트체인은 하나의 델리게이트 안에 여러개의 함수를 연결하여 연쇄적으로 호출하는 방식이다.
+= 연산자를 이용해 인스턴스를 추가를 할수있고 ,
-= 연산자를 이용해 인스턴스를 삭제할 수있다.
delegate void Calculator(int numA, int numB);
Calculator calculator;
void Add(int numA, int numB)
{
Debug.Log(numA + numB);
}
void Sub(int numA, int numB)
{
Debug.Log(numA - numB);
}
void Mul(int numA, int numB)
{
Debug.Log(numA * numB);
}
void Div(int numA, int numB)
{
Debug.Log(numA / numB);
}
void Start()
{
calculator = Add;
calculator += Sub; // 추가
calculator += Mul;
calculator += Div;
// calculator -= Sub; // 삭제
calculator(5, 5);
}
주석 처리를 해놓은 calculator -= Sub 를 삭제한다면 다음과 같은 결과가 나온다.
플레이어가 몬스터와 충돌시 몬스터의 hp 바가 깎이고 , 점수가 오르고
플레이어의 버서커게이지가 올라간다고 가정을 하고 스크립트를 작성해보았다.
그중 몬스터의 Hp가 변할 때마다 생기는 다양한 처리들을 델리게이트로 묶어줄 수 있다.
public class Monster : MonoBehaviour
{
public delegate void OnReduceHp();
public OnReduceHp onReduceHp;
public int hp = 100;
public Slider hpSlider;
public int Hp
{
get { return hp; }
set {
hp = value;
onReduceHp(); // 델리게이트를 사용한다.
if(hp <= 0)
{
Die();
}
}
}
public void Start()
{
onReduceHp += SetHpSlider;
onReduceHp += GameManager.instance.ScoreUp;
}
public void Die()
{
Destroy(gameObject);
}
private void OnTriggerEnter(Collider other)
{
if(other.GetComponent<Player>() != null)
{
Hp -= 10; // 플레이에게 충돌시 체력이 깎인다.
}
}
private void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
{
Hp -= 5;
}
}
}
start()에서 onReduceHp 델리게이트에 두가지 기능을 추가시켜놨다.
hp가 변할때마다 저 기능들이 수행되는 것.
1. hp 슬라이더 바
2. score 오르기!일단은 스페이스바를 입력시 모든 몬스터가 데미지를 입도록 스크립트를 해준다.
public class Player : MonoBehaviour
{
public int berserkerGage = 0;
public void BerserkerGageUp()
{
berserkerGage += 1;
}
}
public class GameManager : MonoBehaviour
{
public static GameManager instance;
public int score=0;
public int Score
{
get { return score; }
set {
score = value;
scoreText.text = score + "점";
}
}
public void ScoreUp()
{
score += 10;
}
public Text scoreText;
private void Awake()
{
if(instance == null)
{
instance = this;
}
}
}
그리고 특정상황 (여기서는 besekerzone안에 들어와있을 때)에서 델리게이트를 사용해
특정기능을 추가시켜주거나 제외시켜줄 수 있다.
public class BerserkerZone : MonoBehaviour
{
private void OnTriggerEnter(Collider other)
{
if(other.GetComponent<Monster>() != null)
{
other.GetComponent<Monster>().onReduceHp += transform.parent.GetComponent<Player>().BerserkerGageUp;
} // onReduceHp 델리게이트에 간편하게 추가할수있다.
}
private void OnTriggerExit(Collider other)
{
if (other.GetComponent<Monster>() != null)
{
other.GetComponent<Monster>().onReduceHp -= transform.parent.GetComponent<Player>().BerserkerGageUp;
}
}
}
이러한 예제를 통하여 캐릭터가 몬스터와 전투시 주변에 몬스터 수에 따라 게이지를 상승하는 시스템을 만들어
델리게이트 사용시 장점은 각각 클래스의 의존성(결합성)이 줄어들고 , 기능을 추가해주거나 수정해줄 경우 의존성이 낮게 간편하게 할수있다.