Posts 유니티 안드로이드 토스트 메시지 표시하기
Post
Cancel

유니티 안드로이드 토스트 메시지 표시하기

AndroidToast Singleton


Usage

1
AndroidToast.I.ShowToastMessage(string message, ToastLength length);


Option

  • ToastLength.Short : 약 2.5초 동안 메시지 표시
  • ToastLength.Long : 약 4초 동안 메시지 표시


Source Code

AndroidToast.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary> 안드로이드 토스트 메시지 표시 싱글톤 </summary>
public class AndroidToast : MonoBehaviour
{
    #region Singleton

    /// <summary> 싱글톤 인스턴스 Getter </summary>
    public static AndroidToast I
    {
        get
        {
            if (instance == null)    // 체크 1 : 인스턴스가 없는 경우
                CheckExsistence();

            return instance;
        }
    }

    // 싱글톤 인스턴스
    private static AndroidToast instance;

    // 싱글톤 인스턴스 존재 여부 확인 (체크 2)
    private static void CheckExsistence()
    {
        // 싱글톤 검색
        instance = FindObjectOfType<AndroidToast>();

        // 인스턴스 가진 오브젝트가 존재하지 않을 경우, 빈 오브젝트를 임의로 생성하여 인스턴스 할당
        if (instance == null)
        {
            // 빈 게임 오브젝트 생성
            GameObject container = new GameObject("AndroidToast Singleton Container");

            // 게임 오브젝트에 클래스 컴포넌트 추가 후 인스턴스 할당
            instance = container.AddComponent<AndroidToast>();
        }
    }

    private void CheckInstance()
    {
        // 싱글톤 인스턴스가 존재하지 않았을 경우, 본인으로 초기화
        if (instance == null)
            instance = this;

        // 싱글톤 인스턴스가 존재하는데, 본인이 아닐 경우, 스스로(컴포넌트)를 파괴
        if (instance != null && instance != this)
        {
            Debug.Log("이미 AndroidToast 싱글톤이 존재하므로 오브젝트를 파괴합니다.");
            Destroy(this);

            // 만약 게임 오브젝트에 컴포넌트가 자신만 있었다면, 게임 오브젝트도 파괴
            var components = gameObject.GetComponents<Component>();

            if (components.Length <= 2)
                Destroy(gameObject);
        }
    }

    private void Awake()
    {
        CheckInstance();
    }

    #endregion // ==================================================================

    public enum ToastLength
    {
        /// <summary> 약 2.5초 </summary>
        Short,
        /// <summary> 약 4초 </summary>
        Long
    };

#if UNITY_EDITOR
    private float __editorGuiTime = 0f;
    private string __editorGuiMessage;

#elif UNITY_ANDROID

    private AndroidJavaClass _unityPlayer;
    private AndroidJavaObject _unityActivity;
    private AndroidJavaClass _toastClass;

    private void Start()
    {
        _unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        _unityActivity = _unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
        _toastClass = new AndroidJavaClass("android.widget.Toast");
    }
#endif

    /// <summary> 안드로이드 토스트 메시지 표시하기 </summary>
    [System.Diagnostics.Conditional("UNITY_ANDROID")]
    public void ShowToastMessage(string message, ToastLength length = ToastLength.Short)
    {
#if UNITY_EDITOR
        __editorGuiTime = length == ToastLength.Short ? 2.5f : 4f;
        __editorGuiMessage = message;

#elif UNITY_ANDROID
        if (_unityActivity != null)
        {
            _unityActivity.Call("runOnUiThread", new AndroidJavaRunnable(() =>
            {
                AndroidJavaObject toastObject = _toastClass.CallStatic<AndroidJavaObject>("makeText", _unityActivity, message, (int)length);
                toastObject.Call("show");
            }));
        }
#endif
    }

#if UNITY_EDITOR
    /* 유니티 에디터 IMGUI를 통해 토스트 메시지 표시 모방하기 */

    private GUIStyle toastStyle;
    private void OnGUI()
    {
        if (__editorGuiTime <= 0f) return;

        float width = Screen.width * 0.5f;
        float height = Screen.height * 0.08f;
        Rect rect = new Rect((Screen.width - width) * 0.5f, Screen.height * 0.8f, width, height);

        if (toastStyle == null)
        {
            toastStyle = new GUIStyle(GUI.skin.box);
            toastStyle.fontSize = 36;
            toastStyle.fontStyle = FontStyle.Bold;
            toastStyle.alignment = TextAnchor.MiddleCenter;
            toastStyle.normal.textColor = Color.white;
        }

        GUI.Box(rect, __editorGuiMessage, toastStyle);
    }
    private void Update()
    {
        if (__editorGuiTime > 0f)
            __editorGuiTime -= Time.unscaledDeltaTime;
    }
#endif
}


두 번 연속 눌러 종료하는 기능 구현하기


image

  • 유니티 에디터 환경에서도 동일하게 동작한다.

image

AndroidInputManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AndroidInputManager : MonoBehaviour
{
#if UNITY_ANDROID
    private bool _preparedToQuit = false;

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            if (_preparedToQuit == false)
            {
                AndroidToast.I.ShowToastMessage("뒤로가기 버튼을 한 번 더 누르시면 종료됩니다.");
                PrepareToQuit();
            }
            else
            {
                Debug.Log("Quit");
#if UNITY_EDITOR
                UnityEditor.EditorApplication.isPlaying = false;
#else
                Application.Quit();
#endif
            }
        }
    }

    private void PrepareToQuit()
    {
        StartCoroutine(PrepareToQuitRoutine());
    }

    private IEnumerator PrepareToQuitRoutine()
    {
        _preparedToQuit = true;
        yield return new WaitForSecondsRealtime(2.5f);
        _preparedToQuit = false;
    }
#endif
}


References


This post is licensed under CC BY 4.0 by the author.