Ad Block 한번만 꺼주시면 안될까요..?
게임 개발/유니티C#

유니티 C#) 휴대폰에서 작은 메시지, 경고 만들기(토스트 메시지)

UniCoti(유니코티) 2023. 3. 4.

이번엔 보통 토스트 메시지라고 부르는

작은 경고창을 띄우는 법에 대해 소개하겠다.

일단, 사용하는 건 간단할지 몰라도

코드만큼은 그렇게 쉽지 않다.

 

필자 또한 한 블로그에서 거의 복붙 한 것이기에

만약 이 글을 보는 사람이 있다면

링크를 타고 그 블로그 것도 한번 봐줬으면 한다.

 

https://rito15.github.io/posts/unity-android-toast-message/ (원본 링크)

 

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

AndroidToast Singleton

rito15.github.io


일단 코드부터 소개하겠다.

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
}

음... 매우 길다. 싱글턴을 통해 여러 개 생성을 방지했고,

나 또한 사실 잘 모르겠다.

public void ShowAndroidToastMessage(string message)
    {
        AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity2d.player.UnityPlayer");
        AndroidJavaObject unityActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");

        if (unityActivity != null)
        {
            AndroidJavaClass toastClass = new AndroidJavaClass("android.widget.Toast");
            unityActivity.Call("runOnUiThread", new AndroidJavaRunnable(() =>
            {
                AndroidJavaObject toastObject = toastClass.CallStatic<AndroidJavaObject>("makeText", unityActivity, message, 0);
                toastObject.Call("show");
            }));
        }
    }

 

어쨌든 사용법은, 위의 함수를 복붙해서 정의한 다음,

ShowToastMessage("할말");

으로 적어주면 실행된다. 

 

디자인이 조금 다르게 나오긴 하지만,

휴대폰뿐 아니라 pc, 유니티(에디터)에서도 잘 나온다.


이상으로 도움이 되었길 바라며,

 

끝.

댓글

💲 추천 글