사용한 방식에 대한 자세한 설명은 이 글을 참고하면 될 것 같다.
간단하게 요약하자면, 이전 글에서 string을 하나씩 파싱하며 키워드를 찾았던 방식을
데이터에 함수명을 저장한 후 호출하는 형태로 변경했다.
[System.Serializable]
public class Line
{
public int lineId;
public string func;
public List<int> funcArg;
public List<string> funcArg2;
public string text;
}
func
은 대체로 funArg
와 함께 DialogueManager의 함수를 사용하는데,
예외적으로 funArg2
를 사용할 경우 특정 객체의 함수를 호출하도록 틀을 잡았다.
public void SetLineInfo(int _idx)
{
if (DialogueManager.Inst.m_scene == null) return;
DialogueManager.Inst.SetLineIdx(new List<int>() {_idx});
m_line = DialogueManager.Inst.Line;
// ⭐🖋️ 함수명(m_line.func)을 전달하여 callback 함수로 지정
// ⭐🖋️ funcArg2 값이 존재할 경우 호출한 객체를 타겟으로 넘김
DialogueManager.Inst.SetCallBackFunc(m_line.func, (m_line.funcArg2.Count > 0) ? this : null);
}
private MethodInfo m_callBackFuncInfo;
private MonoBehaviour m_target;
...
public void SetCallBackFunc(string func, MonoBehaviour mono = null)
{
if (string.IsNullOrEmpty(func)) return;
m_target = mono == null ? this : mono;
m_callBackFuncInfo = m_target.GetType().GetMethod(func, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
}
위와 같이 m_callBackFuncInfo
에 함수의 정보를 저장해둔다.
타겟 객체에서 작업을 모두 완료하고 callback을 호출할 타이밍이 되면,
public void GetCallBackFunc(List<int> vals)
{
if (m_callBackFuncInfo.GetParameters().Length > 0)
{
List<object> objs = new List<object> { vals };
m_callBackFuncInfo?.Invoke(m_target, objs.ToArray(<));
}
else
m_callBackFuncInfo?.Invoke(m_target, null);
}
fungArg2
를 사용할 경우 타겟 객체에서 처리하기 때문에
Invoke()
할 때에는 매개변수를 넘기지 않는다.
구조 변경 후에도 별 문제 없이 잘 실행 된다.
훨씬 깔끔해져서 마음에 든다.
+변경된 데이터 구조도 첨부한다.
{
"lineId":0,
"func": "SetSelectInfo",
"funcArg":[1, 4],
"funcArg2":["예","아니오"],
"text": "서언태애애액지이이입니다"
},