OnApplicationQuit 오류

devKyoun·2025년 3월 14일
0

Unity

목록 보기
27/27

사용 이유

오프라인 보상을 위해서 어플 종료 시 시간을 JSON 형태로 DateTime 자료형으로 저장을 하고 어플 실행시 저장했던 시간이 존재하는지 ( 초기화 상태인지도 확인 -> 첫 시작 ), 존재한다면 시간차이가 얼마나 나는지 확인하려고 했다.

다만 어플 종료 시 DateTime.Now가 저장 안되는 것이 확인 됐다.

GameManager

public void OnApplicationQuit()
{
    DataManager.Instance.SaveData();
    DataManager.Instance.SaveLastTime(DateTime.Now);
    Debug.Log("Save");
}

DataManager

private void Start()
{
    path = Application.persistentDataPath + fileName;
    Debug.Log(path);
    LoadData();


    if (playerData.lastPlayTime != DateTime.MinValue)
    {
        UpdateRewardMoney();
        Debug.Log(playerData.lastPlayTime.ToString());
    }
}

.....

 public void SaveLastTime(DateTime lastTime)
 {
     playerData.lastPlayTime = lastTime;
 }

어플을 재실행해도 DataManager의 if 자체가 실행이 안되는 상황이다

그래서 Unity Discussion으로 서치

이해하려다가 부족한 영어 실력으로 보자면
안드로이드 공식 문서에 따라서 onPause 이후에 안드로이드가 액티비티를 종료하면 OnApplicationQuit이 호출되지 않을 가능성이 있다.

인데 근데 OnPause를 한 적이 없는데.. ㅠ

다른 해답이 있을지 찾아봤는데 금방 다른 답변을 찾았다!

  • OnApplicationPause 를 통해 유동적인 앱 종료를 구현 할 것
    Quit은 어처피 사용을 안하기로 했기 때문에 게임 종료 버튼이라는 기능 자체를 삭제
    Pause를 사용해보고 저장이 우선 되는지부터 확인해보자!

OnApplicationPause()도 다른 반응이 없다..

 public void OnApplicationPause(bool pauseStatus)
 {
     if (pauseStatus)
     {
         DataManager.Instance.SaveData();
         DataManager.Instance.SaveLastTime(DateTime.Now);
         Debug.Log("Save");
     }

 }

근데 나와 같은 고민을 하다가 해결을 한 사람을 발견..!
OnApplicationFocus..? 뭘까 한번 찾아보자!

유니티 문서를 봤는데 무슨소리인지 모르겠다 가상 키보드..?
그래서 ChatGpt의 힘을 빌렸다

포커스를 잃는 경우 저장을 하면 가능해지는 것이 납득이 됐다.
Pause인 경우 앱 자체가 백그라운드로 완전히 이동이 됐을 때 불려지는 것이기 때문에
저장 작업을 하기 전에 앱이 중단이 될 수도 있기 때문이라고 한다.
어쨋거나 DataManager를 두번 거쳐야 하는 작업이기에 어찌보면 그 짧은 시간내에 저장이 불가능할 수도 있겠다.

그래서 Focus로 바꿔주고 테스트를 해봤다.
=> GameManager.cs에서 OnApplication 내장 함수들을 DataManager에서 사용하도록 바꿈
( 더 빠른 속도와 더 직관적 )

public void OnApplicationFocus(bool focusStatus)
{
    // 백그라운드행
    if (focusStatus == false)
    {
        playerData.lastPlayTime = DateTime.Now;
    }
    // 다시 복귀
    else
    {
    	// LoadData()
        UpdateRewardMoney();
    }
}

LoadData가 있었을때 UpdateRewardMoney() 메소드가 호출 되지 않았다.
찾아보니 LoadData작업이 오래 걸린다면 그 뒤에 함수는 메인스레드가 정상적으로 실행을 못한다는 것.

Chat GPT

LoadData()와 같은 시간이 걸리는 동기 작업을 Coroutine으로 처리하면, 메인 스레드가 차단되지 않고 UI가 멈추지 않고 이게임 내에서 다른 작업들도 동시에 진행할 수 있습니다.
UpdateRewardMoney()는 LoadData()가 완료된 후 실행되므로, 데이터가 제대로 로드된 후 보상 업데이트가 가능합니다.

LoadData르

메인스레드가 UpdateRewardMoney()를 수행하지 못해서 그런 것이였다.

그렇기에.....

계속되는 의문점이 들었다. 아니 이해도 되지 않았다. 논리적으로 말이 안되는게 많아서
여러가지 방법을 다 해도 안됐는데 문제점을 찾아냈다.

JsonUtility 직렬화를 이용해서 데이터를 저장하고 있었는데, DateTime은 지원되지 않는다는것.

그래서 DateTime을 String으로 변환해서 저장해줘야한다..

profile
Game Developer

0개의 댓글