LoginSignup
0
0

More than 1 year has passed since last update.

【Unity】UnityでAndroidのネイティブGUIを出したい

Posted at

はじめに

どうも、Unity DOTSの記事を上げまくっていた人です。
今日はどちらかというと、本来主としてやっていたスマホアプリ開発のお話です。

動機

最近、小学校から愛用していた目覚ましが壊れたので目覚ましアプリを作ろうと思いました。
ただ、Androidのネイティブの時刻設定はすごく好きだったのでそれを使いたいということで、Unityからネイティブを呼び出してみました。

Flutterだろ!とかネイティブで書けよ!っていうのはその通りです。
Unityが好きだしUnityの勉強がてらなんです許して

今回すること

これです。

環境

Unity 2021.3.20.f1
Android Studio Dolphin 2021.3.1 Patch1

最初にaarを作る

aarとは

アンドロイドのライブラリの形式らしいです。Androidは詳しくないのでわかんないです。

aarの作り方

詳しくは下記のQiitaをご覧ください。私も参考にさせていただきました。ありがとうございます。

今回のソースコード

さて、時刻設定を出すソースコードはこちらです。
また、KotlinだとUnity上で動かすことができなかったです。大人しくJavaを使う運命かもしれません。
Kotlinの記法好きなんですけどね。少ししか触ってませんが。

package com.prashalt.education.mathunialarm;

import static java.lang.String.valueOf;

import android.app.AlertDialog;
import android.app.TimePickerDialog;
import android.content.Context;
import android.widget.TimePicker;

import com.unity3d.player.UnityPlayer;

public class AndroidNativeDialog{
    static public void showNativeDialog(Context context, String title, String message) {
        new AlertDialog.Builder(context)
                .setTitle(title)
                .setMessage(message)
                .setPositiveButton("はい", null)
                .setNegativeButton("いいえ", null)
                .show();
    }

    public static void showTimerDialog(Context context) {
        TimePickerDialog dialog = new TimePickerDialog(context, TimerDialogCallback(), 0, 0, true);
        dialog.show();
    }
    public static TimePickerDialog.OnTimeSetListener TimerDialogCallback() {
        return new TimePickerDialog.OnTimeSetListener() {
            @Override
            public void onTimeSet(TimePicker timePicker, int hour, int min) {
                UnityPlayer.UnitySendMessage("listenerObj", "TimeSetCallback", valueOf(hour) + ":" +  valueOf(min));
            }
        };
    }
}

このコードは、先ほど紹介したプログラムに少し手を加えたものになります。
メソッドであるTimerDialogCallbackは中身を別ファイルにしたり少し工夫をしたほうがきれいになりますが、まぁいいでしょう。
ひとつひとつ説明していきます(オリジナル部分のみ)

TimePickerDialog

これはAndroidのAPIです。

AndroidのDialogについて

※この部分は雰囲気で書いてます。間違っていたらごめんなさい。
AndroidのDialogは時刻設定であってもほかのテキストの入力であっても通常はAlertDialogクラスを使って作成するようです。
ただ、今回のTimePickerDialogクラスはGoogleが親切に用意してくれた時刻設定のDialog専用のクラスです。(たぶん)

引数

1 Context

これはUnityから指定します。詳しくは先述のQiitaをご覧ください。

2 Callback関数

"OK"ボタン(PositiveButton)が押された時の関数です。今回はUnityに結果を送信する関数を指定しています。

3, 4 時間 / 分の初期値

5 24時間表示かどうか

dialog.show()

これで表示することができます。変数宣言にvarを使ってないのは使ってるJavaのバージョンが古いからです。
深い意味はありません。

Callback関数「TimerDialogCallback」

ここはもっときれいな書き方があります。ただ、めんどくさかったので許してください。
戻り値である、OnTimeSetメソッドは戻り値のTimePickerDialog.OnTimeSetListenerにインターフェースとして実装されておりユーザーが入力した時間が取得できます。

UnityPlayer.UnitySendMessage

これがUnity独自の部分ですね。UnityのC#に値を返すメソッドになります。

引数

1 オブジェクト名

Unityにおける結果を受け取るオブジェクトの名前です。
唯一の名前である必要があるらしいです。

2 メソッド名

オブジェクトにアタッチしてあるMonoBehaviourを継承するクラスに定義されているメソッドの名前です。
これが呼ばれます。

3 メッセージ

これが結果になります。基本的にstringでしか返せません。シリアライズなどをすることでそれ以外も返せるらしいです。

C#のスクリプト

解説するまでもないですが、一応おいておきます。
ほぼ、先述のQiita通りです。

NativeTest.cs
ShowNativeDialog()をボタンから呼んでいます。

using UnityEngine;

public class NativeTest : MonoBehaviour
{
    public void ShowNativeDialog()
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        AndroidJavaClass nativeDialog = new AndroidJavaClass ("com.prashalt.education.mathunialarm.AndroidNativeDialog");
        AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject context  = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");

        context.Call ("runOnUiThread", new AndroidJavaRunnable(() => {
            nativeDialog.CallStatic (
                "showTimerDialog",
                context
            );
        }));
#elif UNITY_EDITOR
        UnityEngine.Debug.Log("On Click!");
#endif
    }
}

ListenerTest.cs
TimeSetCallback()をUnityPlayer.UnitySendMessageで呼んでいます。

using UnityEngine;

public class ListenerTest : MonoBehaviour
{
    public void TimeSetCallback(string message)
    {
        Debug.Log(message);
    }
}

おわりに

いかがでしたでしょうか。
時刻設定のダイアログ以外を出したいとなると、もはやAndroidの世界です。
今回はUnityとの連携という側面で記事を書いていたのでそれは誰かに任せましょう。

もしかしたら、結果をシリアライズする方法の記事も上げるかもしれません。
ただ、今はシリアライズってなんだよ!カタカナ使うな!ぐらいの知識ですけどね笑
SerializeFieldぐらいでしかシリアライズ使ったことないです。

それではまたっ!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0