1.新建Scene_MainMenu场景,在场景中新建一个空物体起名为MainMenuPanel,在MainMenuPanel下新建一个Canvas画布,设置画布分辨率。导入Mobile Notifications包。
2.在画布下新建一个开始按钮和记录最高分数的文本。
3.在MainMenuPanel下新建一个MainMenu脚本,代码如下:
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
/// <summary>
/// 主菜单管理类,负责处理主菜单相关的UI显示和游戏开始逻辑
/// </summary>
public class MainMenu : MonoBehaviour
{
// 高分显示的文本组件
[SerializeField] private TMP_Text highScoreText;
// 能量显示的文本组件
[SerializeField] private TMP_Text energyText;
// 开始游戏的按钮
[SerializeField] private Button playButton;
// 当前能量值
private int energy;
// 最大能量值
[SerializeField] private int maxEnergy;
// 能量恢复所需的时间(分钟)
[SerializeField] private int energyRechargeDuration;
// 安卓通知处理器
[SerializeField] private AndroidNotificationHandler androidNotificationHandler;
// 能量值的保存键名
public const string EnergyKey = "Energy";
// 能量恢复时间的保存键名
public const string EnergyReadyKey = "EnergyReady";
/// <summary>
/// 初始化主菜单,加载高分和能量信息
/// </summary>
void Start()
{
// 当应用获得焦点时,调用OnApplicationFocus
OnApplicationFocus(true);
}
/// <summary>
/// 当应用获得或失去焦点时调用,用于更新主菜单显示
/// </summary>
/// <param name="hasFocus">应用是否获得焦点</param>
void OnApplicationFocus(bool hasFocus)
{
// 如果应用没有获得焦点,则不执行任何操作
if (!hasFocus) { return; }
// 取消当前的Invoke调用
CancelInvoke();
// 更新高分显示
highScoreText.text = "High Score: " + PlayerPrefs.GetInt(ScoreSystem.HighScoreKey, 0);
// 加载或初始化能量值
energy = PlayerPrefs.GetInt(EnergyKey, maxEnergy);
// 如果能量值小于等于0,则尝试恢复能量
if (energy <= 0)
{
// 从PlayerPrefs中获取能量恢复时间字符串
string energyReadyString = PlayerPrefs.GetString(EnergyReadyKey, string.Empty);
// 如果字符串为空,则不执行任何操作
if (energyReadyString == string.Empty) { return; }
// 解析能量恢复时间
DateTime energyReady = DateTime.Parse(energyReadyString);
// 如果当前时间大于等于能量恢复时间,则恢复能量至最大值
if (DateTime.Now >= energyReady)
{
energy = maxEnergy;
// 保存更新后的能量值
PlayerPrefs.SetInt(EnergyKey, energy);
}
else
{
// 如果当前时间小于能量恢复时间,则禁用开始游戏按钮,并设置能量恢复的Invoke调用
playButton.interactable = false;
Invoke(nameof(EnergyRecharge), (energyReady - DateTime.Now).Seconds);
}
}
// 更新能量显示文本
energyText.text = $"Play({energy})";
}
/// <summary>
/// 能量恢复方法,当能量恢复时调用
/// </summary>
private void EnergyRecharge()
{
// 恢复开始游戏按钮的交互性,并将能量值恢复至最大
playButton.interactable = true;
energy = maxEnergy;
// 保存更新后的能量值
PlayerPrefs.SetInt(EnergyKey, energy);
// 更新能量显示文本
energyText.text = $"Play({energy})";
}
/// <summary>
/// 开始游戏方法,当玩家点击开始游戏按钮时调用
/// </summary>
public void StartGame()
{
// 如果当前能量值小于等于0,则不执行任何操作
if (energy <= 0) { return; }
// 减少能量值
energy--;
// 保存更新后的能量值
PlayerPrefs.SetInt(EnergyKey, energy);
// 如果能量值为0,则计算能量恢复时间并保存
if (energy == 0)
{
DateTime endDateTime = DateTime.Now.AddMinutes(energyRechargeDuration);
PlayerPrefs.SetString(EnergyReadyKey, endDateTime.ToString());
// 如果是安卓平台,调度通知
#if UNITY_ANDROID
androidNotificationHandler.ScheduleNotification(endDateTime);
#endif
}
// 加载游戏场景
SceneManager.LoadScene("Scene_Game");
}
}
4.在MainMenuPanel下新建一个AndroidNotificationHandler脚本,代码如下:
using System;
using System.Collections;
using System.Collections.Generic;
#if UNITY_ANDROID
using Unity.Notifications.Android;
#endif
using UnityEngine;
public class AndroidNotificationHandler : MonoBehaviour
{
#if UNITY_ANDROID
private const string ChannelID = "notification_channel";
public void ScheduleNotification(DateTime dateTime)
{
AndroidNotificationChannel notificationChannel = new AndroidNotificationChannel
{
Id = ChannelID,
Name = "Notification Channel",
Description = "Some random description",
Importance = Importance.Default
};
AndroidNotificationCenter.RegisterNotificationChannel(notificationChannel);
AndroidNotification notification = new AndroidNotification
{
Title = "游戏冷却通知",
Text = "冷却时间结束,点击进入游戏",
FireTime = dateTime,
SmallIcon = "48",
LargeIcon = "192"
};
AndroidNotificationCenter.SendNotification(notification, ChannelID);
}
#endif
}
将相应的UGUI拖入到脚本组件中
5.设置Mobile Notifications
若使用了Mobile Notifications插件,导出时需要根据使用的版本来设置Target API Level,否则会出现导出失败的情况.
6.导出设置