프로젝트/알부수기

2023. 08. 27 x Reflection

화릿불 2023. 10. 10. 16:31
// Data Script
// 강화 데이터
public bool EnhanceClickPower = false;
public bool ActivateStack = false;
public bool FirstEnhanceStack = false;
public bool SecondEnhanceStack = false;
public bool ThirdEnhanceStack = false;


// 업적 데이터
public bool FirstCharacter = false;
public bool AcquireFirstCharacter = false;
public bool GetFirstPerson = false;
public bool AcquireGetFirstPerson = false;
public bool FirstEnhance = false;
public bool AcquireFirstEnhance = false;
public bool UseGold1000 =false;
public bool AcquireUseGold1000 = false;
public bool UseTimeStack = false;
public bool AcquireUseTimeStack = false;
public bool GetCharacter10 = false;
public bool AcquireGetCharacter10 = false;

 

업적 시스템을 추가하는 데 있어서 조금 더 유연하게 데이터를 관리하고 싶었는데

이는 강화에서도 동일하게 작용하는 부분이었다.

스트링을 통해 함수 하나만으로 모든 강화, 업적 데이터에 접근하고 싶었다.

 

각각의 데이터들은 bool 타입으로 관리되는데

해당 변수명만 가지고 값을 가지고 오거나 변경시키는 방법이 없을까 찾아보았다.

 

컴파일 시 알 수 없었던 타입이나 멤버들을 찾아내는 데 사용하는 Reflection이라는 개념이 있었는데

프로그램의 안정성을 해치며 전반적으로 느려 성능에 있어서 좋지 않다고 한다.

우선 이 기능을 사용하되 차후 수정할 필요가 있어 보인다.

 

// ButtonController Script
GameDataType = GameData.GetType();
ScriptType = GameController.GetComponent<EnhanceAchievement>().GetType();

// 데이터에서 업적 변수를 리플렉션
if (GameDataType.GetField(transform.parent.name) != null)
{
    bool Clear = Convert.ToBoolean(GameDataType.GetField(transform.parent.name).GetValue(GameData));
    bool Acquire = Convert.ToBoolean(GameDataType.GetField("Acquire" + transform.parent.name).GetValue(GameData));

    if (Clear)
    {
        if (Acquire)
        {
            transform.parent.transform.Find("Complete").gameObject.SetActive(Clear);
            GetComponent<Button>().interactable = !Clear;
        }
        else
        {
            transform.parent.transform.Find("Complete").gameObject.SetActive(!Clear);
            GetComponent<Button>().interactable = Clear;
        }
    }
    else
    {
        bool result = false;

        if (ScriptType.GetMethod(transform.parent.name) != null)
        {
            // 스크립트에서 해당 변수와 동일한 이름의 함수를 리플렉션으로 실행
            // 값을 리턴 받아서 업적 데이터 갱신
            result = Convert.ToBoolean(ScriptType.GetMethod(transform.parent.name).Invoke(GameController.GetComponent<EnhanceAchievement>(), null));
            GameDataType.GetField(transform.parent.name).SetValue(GameData, result);
        }

        GetComponent<Button>().interactable = (result);
    }
}