2024년 2월 18일 일요일

unity c# callback 함수

callback 함수

 콜백 함수(callback function)란 다른 코드의 인수로서 넘겨주는 실행 가능한 코드를 말합니다. 콜백 함수는 특정 이벤트가 발생하거나 특정 조건이 발생할때 실행될 수 있습니다. 


사용처

버튼을 클릭하면 콜백 함수가 호출되어 원하는 기능을 수행할 수 있습니다. 콜백 함수는 프로그래밍에서 비동기적인 작업을 처리하거나 코드의 재사용성을 높이는 데 유용합니다.


yes/no 를 선택하는 다이얼 로그 예제

다이얼 로그를 띄워주는 class를 만들었습니다. 그런데 해당 class가 닫힐때 특별한 처리를 원하는 경우가 있습니다. 즉 사용자가 yes, no를 선택했는가에 따라 다른 처리를 하고 싶은 경우 입니다. yes no dialog를 여러가지 용도로 사용을 하고자 한다면 그때마다 yes no를 선택할때 다른 코드를 넣어 줘야 합니다.

그런데 그때 호출되어야 하는 함수를 callback 함수 형태로 제작해서 dialog를 생성할때 인자를 넘겨주게 되면 코드 재사용성을 높일 수 있습니다.


unity c# 에서 사용방법

c 언어에서는 보통 함수 포인터라는 것이 있습니다. 함수의 포인터를 함수의 인자로 넘겨서 해당 함수를 호출하는 방식입니다. 그러나 c# 의 경우 포인터라는 개념이 없기 때문에 다른 방법을 이용하게 됩니다. interface라는 방법입니다. 

아래와 같은 형태로 만듭니다. OnYesNo 이름은 나중에 호출을 위한 함수가 됩니다.

public interface DialogYesNoCB
{
    public void OnYesNo(int yesNo);
}

그리고 아래와 같이 다이얼로그가 닫힐때 CloseDialog 함수가 호출되도록 연결해줍니다.  

init 에서는 cb 인자로 interface 함수를 연결합니다. 그리고 실제는 CloseDialog() 함수는 다이얼로가 닫힐때 호출되도록 작업은 따로 해주어야 합니다.

public class DialogYesNo : MonoBehaviour
{
    private DialogYesNoCB cb;
    public void Init(string text, DialogYesNoCB cb)
    {
        GetComponentsInChildren<TMP_Text>(true)[0].enabled = true;
        GetComponentsInChildren<TMP_Text>(true)[0].text = text;
        GetComponentsInChildren<TMP_Text>(true)[1].enabled = false;
        GetComponentsInChildren<Image>(true)[2].enabled = false;
        this.cb = cb;
    }
    public void CloseDialog(int yesNo)
    {
        cb.OnYesNo(yesNo);
    }
}


실제 호출은 아래와 같은 형태로 불리게 됩니다.

아래 코드는 예제 코드로 참고만 하시기 바랍니다. 작업중인 코드에서 가져왔기 때문에 실행 가능한 코드는 아닙니다.

ButtonLevelUp() 함수를 호출하면 YesNo dialog가 뜨고 Yes no 버튼을 누르면 만들어 놓은 OnYesNo 함수가 호출 되도록 되어 있습니다.

public class FieldLevelUp : MonoBehaviour, DialogYesNoCB
{
    public void ButtonLevelUp()
    {
        ShowDialogYesNo("필드를 레벨업 하시겠습니까?", this);
    }
    public void OnYesNo(int yesNo)
    {
        if(yesNo == 1) {
            GameManager.instance.quest.fieldClearCountAfterLUP[(int)fieldName] = 0;
            GameManager.instance.quest.fieldLevel[(int)fieldName]++;
            LeftListUpdate();
        }
    }
    ...
    public void ShowDialogYesNo(string text, DialogYesNoCB cb)
    {

        yesNoDialogPanel.GetComponent<DialogYesNo>().Init(text, cb);
        yesNoDialogPanel.GetComponent<PanelHandler>().Show();
    }
    public void CloseDialogYesNo(int yesNo)
    {
        yesNoDialogPanel.GetComponent<DialogYesNo>().CloseDialog(yesNo);
        yesNoDialogPanel.GetComponent<PanelHandler>().Hide();
    }
}

CloseDialogYesNo는 object yes, no 버튼의 button on click() 함수에 넣도록 합니다.




댓글 없음:

댓글 쓰기