
유니티 모바일 게임에서 홈 버튼을 눌러 앱이 뒤로 갈 때 저장하려면 OnApplicationPause(bool paused) 를 씁니다. paused 가 true 로 들어오면 앱이 뒤로 가는 순간이므로 이때 PlayerPrefs.Save() 등으로 저장합니다.
void OnApplicationPause(bool paused)
{
if (paused)
PlayerPrefs.Save(); // 앱이 뒤로 갈 때 저장
}
게임을 하다가 전화를 받거나 메신저를 보고 돌아왔더니, 앱이 처음부터 다시 시작되면서 모은 코인이 사라져 있는 경우가 있습니다. 휴대폰은 뒤로 간 앱을 메모리가 모자랄 때 말없이 끄기도 하고, 사용자가 최근 앱 목록에서 밀어서 지우기도 합니다. Unity 문서도 모바일에서는 OnApplicationQuit 이 불리지 않을 수 있으니 여기에 저장을 맡기지 말라고 안내합니다. 그래서 앱이 뒤로 가는 순간을 알려 주는 OnApplicationPause 와 OnApplicationFocus 에서 저장합니다. 이번 예시에서는 코인을 모으는 동안에는 저장하지 않다가, 앱이 뒤로 가거나 종료될 때 바뀐 것이 있을 때만 한 번 저장하겠습니다.
C# (UNITY 3D)
+10 을 세 번 눌러 코인이 30 이 되어도 아직 저장하지 않습니다. 홈 버튼으로 앱이 뒤로 가는 순간 30 을 한 번 저장하고, 이어서 들어오는 다른 이벤트는 바뀐 것이 없어 건너뜁니다. 그 뒤 최근 앱 목록에서 앱을 지워도 다시 켜면 코인 30 에서 시작합니다.
1. 준비 — 버튼 하나와 글자 하나
Hierarchy 에서 UI (Canvas) > Button - TextMeshPro 로 「+10」 버튼을, UI (Canvas) > Text - TextMeshPro 로 코인 글자를 만듭니다. AutoSave 는 씬에 늘 있는 오브젝트에 붙이고 button_coin · text_coin 칸에 끌어다 넣습니다. OnApplicationPause 같은 함수는 씬의 모든 MonoBehaviour 에 불리므로 따로 연결할 것은 없습니다. TMP 기본 글꼴에는 한글이 없어서 「코인」 이 □ 로 보이면 한글 글꼴로 TMP 글꼴 에셋(Font Asset)을 만들어 넣습니다.
using UnityEngine;
using UnityEngine.UI;
using TMPro;
Button 을 쓰기 위해 UnityEngine.UI 를, TMP_Text 를 쓰기 위해 TMPro 를 사용합니다.
2. 자동 저장 코드
using UnityEngine;
using UnityEngine.UI;
using TMPro;
//CodeFinder 코드파인더
//From https://codefinder.janndk.com/
public class AutoSave : MonoBehaviour
{
public Button button_coin; // 누르면 코인 +10
public TMP_Text text_coin; // 지금 코인
const string KEY_COIN = "save.coin";
int coin; // 지금 코인
bool is_dirty; // 마지막 저장 뒤에 바뀐 게 있나
void Start()
{
coin = PlayerPrefs.GetInt(KEY_COIN, 0); // 지난번 값 불러오기
Show_Coin();
if (button_coin != null)
{
button_coin.onClick.RemoveAllListeners();
button_coin.onClick.AddListener(Add_Coin);
}
}
void Add_Coin()
{
coin += 10;
is_dirty = true; // 바로 저장하지 않고 표시만
Show_Coin();
}
void OnApplicationPause(bool paused)
{
if (paused)
Save_Game("OnApplicationPause"); // 홈 버튼 · 다른 앱으로 나갈 때
}
void OnApplicationFocus(bool has_focus)
{
if (!has_focus)
Save_Game("OnApplicationFocus"); // 포커스를 잃을 때(알림창 등)
}
void OnApplicationQuit()
{
Save_Game("OnApplicationQuit"); // 정상 종료(모바일은 안 불릴 수 있음)
}
void Save_Game(string reason)
{
if (!is_dirty)
return; // 바뀐 게 없으면 건너뜀
PlayerPrefs.SetInt(KEY_COIN, coin);
PlayerPrefs.Save();
is_dirty = false;
Debug.Log("저장 " + coin + " (" + reason + ")");
}
void Show_Coin()
{
if (text_coin != null)
text_coin.text = "코인 " + coin;
}
}
앱이 뒤로 갈 때는 포커스를 잃는 이벤트와 일시정지 이벤트가 함께 들어올 수 있습니다. 세 함수 모두 Save_Game 을 부르지만 is_dirty 가 false 이면 바로 돌아가므로, 바뀐 것이 있을 때 한 번만 저장됩니다. 코인을 누를 때마다 저장하지 않는 것은 Unity 문서가 게임 도중의 PlayerPrefs.Save 가 끊김을 만들 수 있다고 안내하기 때문입니다.
이 스크립트는 Unity 6000.6.3f1 에서 컴파일 오류 없이 들어갔고, 배치 모드에서 함수를 직접 불러 보니 바뀐 것 없이 Pause(true) 는 저장 0번, +10 세 번 뒤 Focus(false) → Pause(true) 는 저장 1번(30), +10 뒤 Quit 은 저장 1번(40)이었습니다. 휴대폰에서 홈 버튼을 눌러 본 것은 아니며, 이벤트가 불리는 때는 Unity 문서를 기준으로 적었습니다.
변수(variable)
button_coin(Button) : 누르면 코인 +10
text_coin(TMP_Text) : 지금 코인을 보여 줄 글자
KEY_COIN(string) : PlayerPrefs 에 저장할 이름
coin(int) : 지금 코인
is_dirty(bool) : 마지막 저장 뒤에 바뀐 것이 있는지
함수(function)
Add_Coin : 코인을 늘리고 바뀐 것이 있다고 표시합니다.
OnApplicationPause : 앱이 일시정지될 때(paused = true) 저장합니다.
OnApplicationFocus : 포커스를 잃을 때(has_focus = false) 저장합니다.
OnApplicationQuit : 정상 종료될 때 저장합니다.
Save_Game : 바뀐 것이 있을 때만 PlayerPrefs 에 쓰고 Save 합니다.
Show_Coin : 코인 글자를 고칩니다.
3. 언제 불리나 — Pause · Focus · Quit

OnApplicationPause 는 처음 시작할 때도 Awake 바로 뒤에 false 로 한 번 불립니다. 그래서 if (paused) 없이 저장 코드를 넣으면 시작하자마자 저장이 한 번 돕니다. Unity 문서는 모바일에서 포커스를 잃을 때(OnApplicationFocus) 저장하라고 권하는데, 안드로이드에서 화면 키보드가 떠 있는 채로 홈 버튼을 누르면 Focus 대신 Pause 만 불린다고 적고 있습니다. 그래서 2절은 둘 다 두었습니다. 또 키보드가 뜰 때도 OnApplicationFocus(false) 가 들어오므로, 바뀐 것이 있을 때만 저장하게 막아 둡니다. 두 이벤트가 어떤 순서로 오는지는 문서에 없어서, 어느 쪽이 먼저 와도 한 번만 저장되게 했습니다.
4. 돌아왔을 때 할 일
void OnApplicationFocus(bool has_focus)
{
if (has_focus)
Debug.Log("돌아옴 — 밝기 · 화면 꺼짐 설정을 다시 적용");
}
반대로 true 가 들어오면 앱으로 돌아온 순간입니다. 화면 밝기처럼 다른 앱에 다녀오면 풀릴 수 있는 설정은 여기서 다시 적용합니다.
5. 저장이 안 되어 있을 때 — 자주 하는 실수
OnApplicationQuit 에만 저장했다
PC 에서는 창을 닫으면 OnApplicationQuit 이 불리지만, iOS 앱은 종료되지 않고 일시정지되므로 불리지 않고, 모바일에서 OS 가 앱을 끄면 Unity 가 이 함수를 부르지 못할 수 있습니다. 배치 모드에서 저장 없이 AutoSave 를 새로 만들어 불러오니 마지막 저장 뒤에 모은 20 은 사라지고 저장된 40 에서 시작했습니다. 모바일은 앱이 뒤로 갈 때마다 종료될 수 있다고 보고 Pause · Focus 에서 저장합니다.
에디터에서 확인이 안 된다
에디터 위쪽의 일시정지 버튼은 OnApplicationPause 를 부르지 않습니다. 에디터에서는 Player Settings 의 Run In Background 가 꺼져 있을 때 Game 창 밖(다른 프로그램)을 누르면 포커스를 잃으면서 불립니다. 정확한 확인은 휴대폰에서 홈 버튼을 눌러 보는 것입니다.
함께 보기: PlayerPrefs 의 저장 · 불러오기와 키 이름 바꾸기는 이 블로그의 PlayerPrefs 글(10월 26일)에 정리했습니다.
이벤트가 불리는 때는 Unity 공식 문서 MonoBehaviour.OnApplicationPause · MonoBehaviour.OnApplicationQuit · PlayerPrefs.Save 를, 저장 횟수는 Unity 6000.6.3f1 에디터(Windows)에서 직접 불러 본 결과를 기준으로 적었습니다.
앱이 뒤로 갈 때(OnApplicationPause) 마지막 설정을 저장하는 처리는 제가 잰드케이로 낸 전광판 앱 BeamSay 에 실제로 들어 있습니다. 안드로이드가 뒤로 보낸 앱을 말없이 끄는 일이 흔해서 넣은 줄입니다(스토어 개발사 표시는 Jakadela Games).
'Unity3D > C#' 카테고리의 다른 글
| 유니티 진동 울리기 · 진동 끄기 설정 (Handheld.Vibrate) (0) | 2026.10.28 |
|---|---|
| 유니티 프레임 60fps 고정 (targetFrameRate) (0) | 2026.10.27 |
| 유니티 데이터 저장 · 불러오기 (PlayerPrefs, HasKey) (0) | 2026.10.26 |
| 유니티 Button onClick 코드로 연결 · interactable 로 잠금 · 연타 막기 (AddListener, 반복문 람다) (0) | 2026.10.25 |
| 유니티 TMP InputField Enter 로 보내기 · 입력 끝 처리 (onSubmit, onEndEdit, onValueChanged 차이) (0) | 2026.10.24 |