使用unity在Android环境开发记录(第四部分)

1.将场景改名为Scene_Main,并复制场景改为Scene_Menu。

新建一个空物体MainMenu,在MainMenu下方创建Canvas画布,在画布下新建Text文本和开始游戏的按钮。

在MainMenu下新建并挂载MainMenu脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class MainMenu : MonoBehaviour
{
    public void StartGame()
    {
        SceneManager.LoadScene("Scene_Main");
    }
}

给PlayGameButton按钮绑定事件

2.在飞机消失,游戏结束的时候,出现面板

在GameOverHander下新建并挂载脚本GameOverHander,并将PlayAgain()和ReturnToMenu()方法绑定在响应按钮上。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class GameOverHander : MonoBehaviour
{
    [SerializeField] private GameObject gameOverPanel;
    [SerializeField] private Text gameOverText;
    [SerializeField] private ScoreSystem scoreSystem;
    [SerializeField] private AsteroidSpawner asteroidSpawner;

    public void EndGame()
    {
        gameOverText.text = "Your Score: " + scoreSystem.EndTimer();
        
        gameOverPanel.SetActive(true);

        asteroidSpawner.enabled = false;
    }
    public void PlayAgain()
    {
        SceneManager.LoadScene("Scene_Main");
    }

    public void ReturnToMenu()
    {
        SceneManager.LoadScene("Scene_Menu");
    }


}

修改PlayerHealth脚本为:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerHealth : MonoBehaviour
{
    [SerializeField] private GameOverHander gameOverHander;
    public void Crash()
    {
        gameObject.SetActive(false);

        gameOverHander.EndGame();
    }
}

3.在屏幕上方创建一个显示分数的文本

在ScoreSystem上创建并挂载ScoreSystem脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ScoreSystem : MonoBehaviour
{
    [SerializeField] private Text scoreText;
    [SerializeField] private int scoreMultiplier;

    private float score;
    private bool shouldCount = true;

    void Update()
    {
        if (!shouldCount) { return; }

        score += Time.deltaTime * scoreMultiplier;

        scoreText.text = Mathf.FloorToInt(score).ToString();
    }

    public int EndTimer()
    {
        shouldCount = false;

        scoreText.text = string.Empty;

        return Mathf.FloorToInt(score);
    }
}

4.进行广告的嵌入,创建一个空物体AdManager,并在其上挂载脚本Ad Manager

在unity中导入Advertisement Legacy(unity2022.3中是这个名字)

在Project Settings中选择Services

点击Dashboard进入unity Cloud

选择创建的项目

5.编写代码AdManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Advertisements;

/// <summary>
/// 广告管理器,用于管理游戏中的广告显示和响应
/// </summary>
public class AdManager : MonoBehaviour, IUnityAdsShowListener, IUnityAdsInitializationListener
{
    /// <summary>
    /// AdManager的单例实例
    /// </summary>
    public static AdManager Instance;

    /// <summary>
    /// 游戏结束处理的引用,用于在广告观看完成后继续游戏
    /// </summary>
    private GameOverHander gameOverHander;

    /// <summary>
    /// Unity Ads的游戏ID
    /// </summary>
    private string gameId = "5739023";

    /// <summary>
    /// 是否启用测试模式,true表示启用,false表示禁用
    /// </summary>
    [SerializeField] private bool testMode = true;

    /// <summary>
    /// 在Awake方法中初始化AdManager,确保只有一个实例存在,并初始化Unity Ads
    /// </summary>
    private void Awake()
    {
        if (Instance != null && Instance != this)
        {
            Destroy(this.gameObject);
        }
        else
        {
            Instance = this;

            DontDestroyOnLoad(this.gameObject);
            // 初始化Unity Ads
            Advertisement.Initialize(gameId, testMode, this);
        }
    }

    /// <summary>
    /// 当Unity Ads显示点击时调用,目前未实现
    /// </summary>
    /// <param name="placementId">广告位ID</param>
    public void OnUnityAdsShowClick(string placementId)
    {
        throw new System.NotImplementedException();
    }

    /// <summary>
    /// 当Unity Ads显示完成时调用,根据广告完成状态执行相应操作
    /// </summary>
    /// <param name="placementId">广告位ID</param>
    /// <param name="showCompletionState">广告完成状态</param>
    public void OnUnityAdsShowComplete(string placementId, UnityAdsShowCompletionState showCompletionState)
    {
        switch (showCompletionState)
        {
            // 广告完成,继续游戏
            case UnityAdsShowCompletionState.COMPLETED:
                gameOverHander.ContinueGame();
                break;
            case UnityAdsShowCompletionState.SKIPPED:
                break;
            // 其他情况
            case UnityAdsShowCompletionState.UNKNOWN:
                Debug.Log("Ad failed to show: " + showCompletionState);
                break;
        }
    }

    /// <summary>
    /// 当Unity Ads显示失败时调用,记录错误信息
    /// </summary>
    /// <param name="placementId">广告位ID</param>
    /// <param name="error">错误类型</param>
    /// <param name="message">错误信息</param>
    public void OnUnityAdsShowFailure(string placementId, UnityAdsShowError error, string message)
    {
        Debug.LogError("Ad failed to show:" + message);
    }

    /// <summary>
    /// 当Unity Ads开始显示时调用,记录日志信息
    /// </summary>
    /// <param name="placementId">广告位ID</param>
    public void OnUnityAdsShowStart(string placementId)
    {
        Debug.Log("Ad Started");
    }

    /// <summary>
    /// 显示广告,需要传入GameOverHander以在广告观看完成后继续游戏
    /// </summary>
    /// <param name="gameOverHander">游戏结束处理的实例</param>
    public void ShowAd(GameOverHander gameOverHander)
    {
        this.gameOverHander = gameOverHander;
        // 显示广告
        Advertisement.Show("rewardedVideo", this);
    }

    /// <summary>
    /// 当Unity Ads初始化完成时调用,记录日志信息
    /// </summary>
    public void OnInitializationComplete()
    {
        Debug.Log("Unity Ads initialization complete.");
    }

    /// <summary>
    /// 当Unity Ads初始化失败时调用,记录错误信息
    /// </summary>
    /// <param name="error">错误类型</param>
    /// <param name="message">错误信息</param>
    public void OnInitializationFailed(UnityAdsInitializationError error, string message)
    {
        Debug.LogError("Unity Ads initialization failed: " + message);
    }
}

其中gameID和广告名称修改为自己的

在GameOverHander脚本添加代码

[SerializeField] private GameObject player;
[SerializeField] private Button continueButton;

public void ContinueGame()
    {
        scoreSystem.StartTimer();

        player.transform.position = Vector3.zero;

        player.SetActive(true);

        player.GetComponent<Rigidbody>().velocity = Vector3.zero;

        asteroidSpawner.enabled = true;

        gameOverPanel.SetActive(false);
    }

    public void ContinueButton()
    {
        AdManager.Instance.ShowAd(this);

        continueButton.interactable = false;
    }

在ScoreSystem脚本添加代码

public void StartTimer()
    {
        shouldCount = true;
    }

给继续游戏按钮绑定事件