はじめに
本記事はUnityで手軽にローカルプッシュ通知を行いたい人向けの記事です。
なお本内容はUnity公式のUnity Mobile Notifications Packageを参考に書いております。こちらの記事をみてもうまくできない人に読んでもらえればと思います。
※記事の中には一部分公式と違う点がありますが、その点は公式でも本記事の通りに行ってもどちらでも動くと思います。
Unity Mobile Notifications Packageのインストール
まずはUnity Mobile Notifications Packageをインストールしましょう。

Unityの上部のメニューのWindow->Package Managerを開きます。

その後でMobile Notificationsをタップして右下のinstallをタップします。
※上記はインストール後の画像です。
注意
Mobile Notificationsが表示されない方は左上のパッケージ設定がIn ProjectsやMy Assetsになっていると表示されない場合があります。
その場合はAll Packegesに変更して探してください。
プロジェクト設定
上記のパッケージをインストールすれば使えますが、最低限の設定として以下を行います。

Edit -> Project Settings...を開きます。
Androidのアイコン設定
Androidでは通知を行うアイコンの設定ができます。
iOSも出来るよう(未確認)ですが、iOSではデフォルトでアプリアイコンが使用されるので僕はそのままにしました。

Mobile Notification Settingsを開きます。
そして、上のタブはAndroidを指定します。(はじめに開かれているはずです。)
ここで二つのアイコンを設定します。
アイコンはAndroidの上部に表示されるSmall Iconと通知本文に表示されるLarge Iconを複数設定できます。
Small Iconは48x48のサイズで設定する必要があり、透過部分がくり抜かれます。
(上記の画像のプレビューが白いのは透過部分が無いためです。)
Large Iconは192x192のアイコンを設定します。
ここで指定したIdentifierはあとでプログラムで使用します。
iOSの設定
iOSではプッシュ通知の許可が必要になります。
iOSのタブに変更します。

上記の丸が付いているチェックボックスにチェックを入れます。
iOSでは任意のタイミングで通知の許可を行えるのですが、Mobile Notificationsでは起動時のみの設定しかできないようです。
(この記事をみている人ならこの設定で十分だと思います。)
実装
以下のプログラムをプロジェクトに追加してください。
# if UNITY_ANDROID
using Unity.Notifications.Android;
# endif
# if UNITY_IOS
using Unity.Notifications.iOS;
# endif
using System;
/// <summary>
/// ローカルプッシュ通知送信クラス
/// </summary>
public static class LocalPushNotification
{
/// <summary>
/// Androidで使用するプッシュ通知用のチャンネルを登録する。
/// </summary>
public static void RegisterChannel(string cannelId, string title, string description)
{
# if UNITY_ANDROID
// チャンネルの登録
var c = new AndroidNotificationChannel()
{
Id = cannelId,
Name = title,
Importance = Importance.High,
Description = description,
};
AndroidNotificationCenter.RegisterNotificationChannel(c);
# endif
}
/// <summary>
/// 通知をすべてクリアーします。
/// </summary>
public static void AllClear()
{
# if UNITY_ANDROID
// Androidの通知をすべて削除します。
AndroidNotificationCenter.CancelAllScheduledNotifications();
AndroidNotificationCenter.CancelAllNotifications();
# endif
# if UNITY_IOS
// iOSの通知をすべて削除します。
iOSNotificationCenter.RemoveAllScheduledNotifications();
iOSNotificationCenter.RemoveAllDeliveredNotifications();
// バッジを消します。
iOSNotificationCenter.ApplicationBadge = 0;
# endif
}
/// <summary>
/// プッシュ通知を登録します。
/// </summary>
/// <param name="title">通知のタイトル</param>
/// <param name="message">通知メッセージ</param>
/// <param name="badgeCount">表示するバッジ数</param>
/// <param name="elapsedTime">何秒後に表示させるか?</param>
/// <param name="cannelId">Androidで使用するチャンネル</param>
public static void AddSchedule(string title, string message, int badgeCount, int elapsedTime, string cannelId)
{
# if UNITY_ANDROID
SetAndroidNotification(title, message, badgeCount, elapsedTime, cannelId);
# endif
# if UNITY_IOS
SetIOSNotification(title, message, badgeCount, elapsedTime);
# endif
}
# if UNITY_IOS
/// <summary>
/// 通知を登録します。(iOS)
/// </summary>
/// <param name="title"></param>
/// <param name="message"></param>
/// <param name="badgeCount"></param>
/// <param name="elapsedTime"></param>
static private void SetIOSNotification(string title, string message, int badgeCount, int elapsedTime)
{
// 通知を作成します。
iOSNotificationCenter.ScheduleNotification(new iOSNotification()
{
// ※プッシュ通知を個別に取り消しなどをする場合はこのIdentifierを使用します。
Identifier = $"_notification_{badgeCount}",
Title = title,
Body = message,
ShowInForeground = false,
Badge = badgeCount,
Trigger = new iOSNotificationTimeIntervalTrigger()
{
TimeInterval = new TimeSpan(0, 0, elapsedTime),
Repeats = false
}
});
}
# endif
# if UNITY_ANDROID
/// <summary>
/// 通知を登録する。(Android)
/// </summary>
/// <param name="title"></param>
/// <param name="message"></param>
/// <param name="badgeCount"></param>
/// <param name="elapsedTime"></param>
/// <param name="cannelId"></param>
static private void SetAndroidNotification(string title, string message, int badgeCount, int elapsedTime, string cannelId)
{
// 通知を作成します。
var notification = new AndroidNotification
{
Title = title,
Text = message,
Number = badgeCount,
// ※ここでAndroidのアイコンを設定します。
SmallIcon = "icon_small",
LargeIcon = "icon_large",
FireTime = DateTime.Now.AddSeconds(elapsedTime)
};
// 通知を送信します。
AndroidNotificationCenter.SendNotification(notification, cannelId);
// ※以下のコードを使うことで個別にプッシュ通知の制御ができます。
//var identifier = AndroidNotificationCenter.SendNotification(notification, cannelId);
//UnityEngine.Debug.Log($"TownSoftPush: プッシュ通知の登録完了 -> {DateTime.Now.AddSeconds(elapsedTime)}");
//if (AndroidNotificationCenter.CheckScheduledNotificationStatus(identifier) == NotificationStatus.Scheduled)
//{
// // Replace the currently scheduled notification with a new notification.
// UnityEngine.Debug.Log("プッシュ通知はすでに登録済み");
//}
//else if (AndroidNotificationCenter.CheckScheduledNotificationStatus(identifier) == NotificationStatus.Delivered)
//{
// //Remove the notification from the status bar
// //AndroidNotificationCenter.CancelNotification(identifier);
// UnityEngine.Debug.Log("プッシュ通知はすでに通知済み");
//}
//else if (AndroidNotificationCenter.CheckScheduledNotificationStatus(identifier) == NotificationStatus.Unknown)
//{
// //AndroidNotificationCenter.SendNotification(newNotification, "channel_id");
// UnityEngine.Debug.Log("プッシュ通知は不明な状況");
//}
}
# endif
}
上記のコード内に※で注釈している部分を必要に応じて変更してください。
使用方法
Androidでは事前に通知チャンネルを登録する必要があります。
なので、起動時に以下のコードを呼び出します。
※以下のコードはiOSで呼び出しても何も処理を行わないのでプラットフォームによって分ける必要はありません。
// チャンネルの登録
LocalPushNotification.RegisterChannel("channelId", "アプリ名(チャンネル名)", "説明");
その後、プッシュ通知を登録したい場合は以下のコードを呼び出してください。
// プッシュ通知の登録
LocalPushNotification.AddSchedule("プッシュ通知タイトル", "内容", 1, 60, "channelId");
左からプッシュ通知タイトル、プッシュ通知に表示する内容、バッチ番号、通知時間(指定秒後に通知します)、チャンネル登録したIDを指定します。
僕の端末のせいか、バッチ番号はAndroidでは表示されませんでした。
チャンネル登録したIDは上記コードでチャンネル登録したIDを指定します。上記の例ではchannelIdになります。
プッシュ通知を削除したい場合は以下のコードを呼び出してください。
バッチ番号も消えます。
LocalPushNotification.AllClear();
ハマった点
僕はiOSユーザーなので、Androidのことを知らずに上記を実装していました。
その時に通知が全く来なかったのでなんでだろう?と思って調べてたらマナーモードでは通知が来ないんですね・・・。
恥ずかしいことですが、これでしばらくハマってました。
上級者へ
上記コードはプッシュ通知を送信して消すことしかできません。
しかし、Mobile NotificationsにはIdentifierが用意されていますので上記コードを改修することで個別の通知削除や編集なども出来るようになります。
その際にはiOSとAndroidの差異を吸収する必要があるので注意してください。
iOSではIdentifierは文字列ですが、Androidでは数字になっています。
最後に
個人でアプリを作っている場合はプッシュ通知の敷居がとても高い(証明書の用意、通知サーバーやの用意など)です。
しかし、ローカルプッシュ通知の場合はあまり敷居が高くないので積極的に使っていくとユーザーの呼び戻しができます。
個人でアプリを作っている人のお役に立てればと思います。