delegate는 특정 반환값과 인자를 받는 함수의 형을 선언해서 함수를 변수처럼 전달받을 수 있게한다. 다음은 예시를 위해 간단히 체력을 담당하는 스크립트를 만들었다. OnHealthSliderChange는 UI의 슬라이더가 움직일 때 마다 호출된다.
public class Health : MonoBehaviour
{
public delegate void HealthCallback(float health);
public HealthCallback healthCallback;
public void HealthChange(float health)
{
Debug.Log("Method " + health);
}
void Start()
{
healthCallback += HealthChange;
healthCallback += (float health) => { Debug.Log("Lamda " + health); };
}
public void OnHealthSliderChange(float value)
{
healthCallback.Invoke(value);
}
}
public delegate void HealthCallback(float health);
public HealthCallback healthCallback;
먼저 public delegate void DelegateName (float) 형식으로 원하는 delegate형을 만든다. 다음으로 DelegateName delegate 형식으로 변수를 만든다. 쉽게 말해 윗 줄은 클래스 내부에 클래스를 선언하는 것과 비슷하게 자료형을 만들고, 아래에서 그 자료형의 변수를 선언하는 식이다.
만약 delegate를 private으로 선언할 경우 해당 delegate와 연관된 것들을 외부에서 접근할 수 없다. 만약 private delegate를 public으로 만들면 delegate형보다 delegate변수에 더 접근하기 쉬워져 컴파일 에러가 발생한다.
healthCallback += HealthChange;
healthCallback += (float health) => { Debug.Log("Lamda " + health); };
이렇게 만든 delegate에는 = 또는 += 로 함수 또는 람다를 대입할 수 있다. C/C++의 함수 포인터에 함수를 넣는 것과 비슷하다. 다른점은 한 변수에 +=로 여러개의 함수를 동시에 집어넣을 수 있다는 점이다.
healthCallback.Invoke(value);
대입된 함수를 실행할 때는 Invoke뒤에 파라미터를 전달해서 호출한다. 만약 여러 개의 함수를 넣었으면 모두 동일한 인자로 호출된다.
delegate는 리스너 패턴을 만들 때 자주 사용된다. 만약 플레이어의 HP가 변화하고 그에 맞추어 HP게이지의 이미지를 수정해야할 때, HP게이지의 Update에서 플레이어의 HP를 계속 확인하고 갱신할 수 있다. 하지만 이는 HP가 변하지 않아도 불필요한 갱신을 하는 단점이 있다. 이 때 delegate를 사용해 HP게이지가 HP에게 콜백 함수를 넘겨줘 HP가 갱신될 때 호출되게 하면 해결할 수 있다.
public class BarType : MonoBehaviour
{
public Health health;
private Image image;
public void Start()
{
image = GetComponent<Image>();
health.healthCallback += OnHealthChange;
}
private void OnHealthChange(float health)
{
image.fillAmount = health;
}
}
HP게이지를 담당하는 BarType에서 위의 Health를 전달받고 health.healthCallback에 자신의 함수 OnHealthChange를 넣었다. 이 함수는 OnHealthSliderChange가 호출될 때 healthCallback.Invoke에서 호출될 것이다.
이 방식을 사용하면 나중에 Health변수에 의존하는 오브젝트가 늘어나더라도 다른 부분의 수정 없이 해당 오브젝트가 콜백 함수를 더하기만 하면 된다는 장점이 있다.
'유니티와 놀기' 카테고리의 다른 글
간단한 단색 그래픽 만들기 (0) | 2023.03.05 |
---|---|
코루틴 뒤에 코루틴을 실행시키기 (0) | 2022.11.10 |
체스말을 잡기 (0) | 2022.11.04 |
체스말을 움직이기 (0) | 2022.11.01 |