Unity/Unity 이슈

UI(Canvas)코드가 먹히지 않는 경우

lipnus 2021. 12. 18. 14:55
반응형

UnityEngine.UnityException: get_isActiveAndEnabled can only be called from the main thread.

try~ catch문을 쓰지 않으면 오류로그도 안띄워주고 그냥 배째라 하고 코드 안먹힘.

 

Cause

Android 처럼 UI변경은 오직 Main Thread에서만 가능하다. 

(참고로 corutine은 동일 Thraed라서 신경 안써도 됨)

 

auth.SignInWithCredentialAsync(credential).ContinueWith(task => {
            if (task.IsCanceled) {
                Debug.LogError("#### [Firebase] SignInWithCredentialAsync was canceled.");
                OnFirebaseSignIn.Invoke(false);
                return;
            }
            if (task.IsFaulted) {
                Debug.LogError("#### [Firebase] SignInWithCredentialAsync encountered an error: " + task.Exception);
                OnFirebaseSignIn.Invoke(false);
                return;
            }

            RefreshBaseInfo(auth.CurrentUser.UserId, auth.CurrentUser.Email);
            OnFirebaseSignIn.Invoke(true);
        });

본인의 경우, 쓰레드 안에서 Event를 통해 호출한 매소드에서 UI를 변경해서 이슈가 발생. 다른 부분은 정상동작하는데, UI변경하는 것만 안됨.

 

Solution

Update문을 이용해서 MainThread로 떠넘겨주면 된다. 인터넷에서 나온 샘플코드는 특정 UI의 기능만 Queue에 넣어서 처리하는 방식이었는데, 난 그냥 함수 자체를 UnityAction으로 만들어서 처리.

 

    private Queue<UnityAction> actionBuffer = new Queue<UnityAction>();

    private void Update()
    {
        if(actionBuffer.Count > 0) {
            actionBuffer.Dequeue().Invoke();
        }
    }
    
    private void OnFirebaseSignIn(bool isSuccess)
    {   
        actionBuffer.Enqueue(delegate{ OnFirebaseSignInInMainThread(isSuccess); });
    }

    private void OnFirebaseSignInInMainThread(bool isSuccess)
    {
        if(isSuccess == false) {
            loginStateText.text = "Firebase 접근 과정에서 문제가 발생했습니다";
            OnRefreshLogin();
            return;
        }
        loginStateText.text = "유저 정보를 확인중입니다";
        fbDataMgr.GetUser();
    }
반응형