unity制作捕鱼达人


介绍

水波荡漾的特效
鱼有多种运动轨迹
每隔一段时间自动收集金币
可以切换不同的炮台
升级后有不同的特效
捕捉到普通鱼类有金币特效
捕捉到大金鱼后有特效
playerprefs存档读档
在这里插入图片描述


制作水波特效

在这里插入图片描述

新建一个面板Plane

在这里插入图片描述

新建一个材质球,设置为Legacy Shaders/Particles/Additive
在这里插入图片描述

添加脚本:

using UnityEngine;

public class Ef_WaterWave : MonoBehaviour
{
    
    
    public Texture[] textures;  // 存储多个纹理的数组
    private Material material;  // 存储材质的变量
    private int index = 0;  // 纹理索引

    void Start()
    {
    
    
        // 获取当前对象上的MeshRenderer组件,并将其材质赋值给material变量
        material = GetComponent<MeshRenderer>().material;

        // 每隔0.1秒调用ChangeTexture方法
        InvokeRepeating("ChangeTexture", 0, 0.1f);
    }

    void ChangeTexture()
    {
    
    
        // 将当前纹理数组textures中的纹理赋值给材质的mainTexture属性
        material.mainTexture = textures[index];

        // 更新纹理索引,当索引超过纹理数组长度时,将索引重置为0
        index = (index + 1) % textures.Length;
    }
}


制作多种ui

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


制作不同种类鱼的动画

在这里插入图片描述

在这里插入图片描述


鱼的多种移动效果

在这里插入图片描述

鱼儿可以直着走、弯着走

using UnityEngine;                     // 引入UnityEngine命名空间

using System.Collections;            // 引入System.Collections命名空间

public class FishMaker : MonoBehaviour   // 定义一个名为FishMaker的类并继承MonoBehaviour
{
    
    
    public Transform fishHolder;        // 定义一个Transform类型的公共变量fishHolder,用于存储生成的鱼
    public Transform[] genPositions;    // 定义一个Transform数组类型的公共变量genPositions,用于存储生成鱼的位置
    public GameObject[] fishPrefabs;    // 定义一个GameObject数组类型的公共变量fishPrefabs,用于存储不同种类的鱼的预制体

    public float fishGenWaitTime = 0.5f;    // 定义一个公共浮点型变量fishGenWaitTime,用于控制生成鱼的时间间隔
    public float waveGenWaitTime = 0.3f;    // 定义一个公共浮点型变量waveGenWaitTime,用于控制每次生成鱼的时间间隔

    void Start()                         // Start方法,用于在游戏开始时执行初始化逻辑
    {
    
    
        InvokeRepeating("MakeFishes", 0, waveGenWaitTime);    // 重复调用MakeFishes方法,0表示不延迟,waveGenWaitTime表示每次调用之间的时间间隔
    }

    void MakeFishes()                   // MakeFishes方法,用于生成鱼
    {
    
    
        int genPosIndex = Random.Range(0, genPositions.Length);    // 随机生成一个0到genPositions.Length-1之间的整数,作为生成鱼的位置的索引
        int fishPreIndex = Random.Range(0, fishPrefabs.Length);    // 随机生成一个0到fishPrefabs.Length-1之间的整数,作为生成鱼的预制体的索引
        int maxNum = fishPrefabs[fishPreIndex].GetComponent<FishAttr>().maxNum;    // 获取生成鱼预制体的FishAttr组件中的最大数量
        int maxSpeed = fishPrefabs[fishPreIndex].GetComponent<FishAttr>().maxSpeed;    // 获取生成鱼预制体的FishAttr组件中的最大速度
        int num = Random.Range((maxNum / 2) + 1, maxNum);    // 随机生成一个最大数量的一半到最大数量之间的整数,作为生成鱼的数量
        int speed = Random.Range(maxSpeed / 2, maxSpeed);    // 随机生成一个最大速度的一半到最大速度之间的整数,作为生成鱼的速度
        int moveType = Random.Range(0, 2);    // 随机生成一个0或1,0表示直走,1表示转弯
        int angOffset;    // 定义一个整型变量angOffset,表示直走时的倾斜角
        int angSpeed;     // 定义一个整型变量angSpeed,表示转弯时的角速度

        if (moveType == 0)    // 如果moveType等于0,表示生成直走的鱼
        {
    
    
            angOffset = Random.Range(-22, 22);    // 随机生成一个-22到22之间的整数,表示直走的倾斜角
            StartCoroutine(GenStraightFish(genPosIndex, fishPreIndex, num, speed, angOffset));    // 使用协程生成直走的鱼
        }
        else    // 如果moveType等于1,表示生成转弯的鱼
        {
    
    
            if (Random.Range(0, 2) == 0)    // 随机生成一个0或1,表示是否取负的角速度
            {
    
    
                angSpeed = Random.Range(-15, -9);    // 随机生成一个-15到-9之间的整数,作为角速度
            }
            else
            {
    
    
               angSpeed = Random.Range(9, 15);    // 随机生成一个9到15之间的整数,作为角速度
            }
            StartCoroutine(GenTrunFish(genPosIndex, fishPreIndex, num, speed, angSpeed));    // 使用协程生成转弯的鱼
        }
    }

    IEnumerator GenStraightFish(int genPosIndex,int fishPreIndex,int num,int speed,int angOffset)    // 生成直走的鱼的协程
    {
    
    
        for (int i = 0; i < num; i++)    // 循环生成指定数量的鱼
        {
    
    
            GameObject fish = Instantiate(fishPrefabs[fishPreIndex]);    // 生成鱼的实例
            fish.transform.SetParent(fishHolder, false);    // 设置鱼的父物体为fishHolder
            fish.transform.localPosition = genPositions[genPosIndex].localPosition;    // 设置鱼的初始位置为指定的生成位置的本地位置
            fish.transform.localRotation = genPositions[genPosIndex].localRotation;    // 设置鱼的初始角度为指定的生成位置的本地角度
            fish.transform.Rotate(0, 0, angOffset);    // 将鱼绕z轴旋转指定的倾斜角
            fish.GetComponent<SpriteRenderer>().sortingOrder += i;    // 设置鱼的渲染层级
            fish.AddComponent<Ef_AutoMove>().speed = speed;    // 添加Ef_AutoMove组件,并设置移动速度
            yield return new WaitForSeconds(fishGenWaitTime);    // 等待指定的时间后再生成下一条鱼
        }
    }

    IEnumerator GenTrunFish(int genPosIndex, int fishPreIndex, int num, int speed, int angSpeed)    // 生成转弯的鱼的协程
    {
    
    
        for (int i = 0; i < num; i++)    // 循环生成指定数量的鱼
        {
    
    
            GameObject fish = Instantiate(fishPrefabs[fishPreIndex]);    // 生成鱼的实例
            fish.transform.SetParent(fishHolder, false);    // 设置鱼的父物体为fishHolder
            fish.transform.localPosition = genPositions[genPosIndex].localPosition;    // 设置鱼的初始位置为指定的生成位置的本地位置
            fish.transform.localRotation = genPositions[genPosIndex].localRotation;    // 设置鱼的初始角度为指定的生成位置的本地角度
            fish.GetComponent<SpriteRenderer>().sortingOrder += i;    // 设置鱼的渲染层级
            fish.AddComponent<Ef_AutoMove>().speed = speed;    // 添加Ef_AutoMove组件,并设置移动速度
            fish.AddComponent<Ef_AutoRotate>().speed = angSpeed;    // 添加Ef_AutoRotate组件,并设置旋转速度
            yield return new WaitForSeconds(fishGenWaitTime);    // 等待指定的时间后再生成下一条鱼
        }
    }
}
using UnityEngine;

public class Ef_AutoRotate : MonoBehaviour
{
    
    
    public float speed = 10f;

    void Update()
    {
    
    
        transform.Rotate(Vector3.forward, speed * Time.deltaTime);
    }
}

using UnityEngine;

public class Ef_AutoMove : MonoBehaviour
{
    
    
    public float speed = 1f;
    public Vector3 dir = Vector3.right;

    void Update()
    {
    
    
        transform.Translate(dir * speed * Time.deltaTime);
    }
}


制作鱼的生成点

在这里插入图片描述

这段代码主要实现了生成不同类型的鱼,并让它们在屏幕上游动。

函数功能简介:

  • Start():在游戏开始时调用,通过InvokeRepeating函数定时调用MakeFishes函数生成鱼。
  • MakeFishes():随机生成不同种类的鱼,并根据鱼的属性生成不同运动轨迹的鱼。
  • GenStraightFish():生成直走的鱼,每生成一条鱼就等待一定时间,然后再生成下一条鱼。
  • GenTrunFish():生成转弯的鱼,每生成一条鱼就等待一定时间,然后再生成下一条鱼。

变量功能简介:

  • fishHolder:存放生成的鱼的父物体。
  • genPositions:存放生成鱼的位置的数组。
  • fishPrefabs:存放不同种类鱼的预制体的数组。
  • fishGenWaitTime:生成鱼的间隔时间。
  • waveGenWaitTime:生成不同类型鱼的间隔时间。
using UnityEngine;
using System.Collections;

public class FishMaker : MonoBehaviour
{
    
    
    public Transform fishHolder;                // 鱼的父物体
    public Transform[] genPositions;            // 生成鱼的位置数组
    public GameObject[] fishPrefabs;            // 鱼的预制体数组

    public float fishGenWaitTime = 0.5f;        // 生成鱼的等待时间
    public float waveGenWaitTime = 0.3f;        // 波次生成的等待时间

    void Start()
    {
    
    
        InvokeRepeating("MakeFishes", 0, waveGenWaitTime);     // 开始重复调用MakeFishes方法
    }

    void MakeFishes()
    {
    
    
        int genPosIndex = Random.Range(0, genPositions.Length);        // 随机生成位置的索引
        int fishPreIndex = Random.Range(0, fishPrefabs.Length);        // 随机鱼的预制体的索引
        int maxNum = fishPrefabs[fishPreIndex].GetComponent<FishAttr>().maxNum;       // 获取最大数量
        int maxSpeed = fishPrefabs[fishPreIndex].GetComponent<FishAttr>().maxSpeed;   // 获取最大速度
        int num = Random.Range((maxNum / 2) + 1, maxNum);              // 随机生成数量
        int speed = Random.Range(maxSpeed / 2, maxSpeed);               // 随机生成速度
        int moveType = Random.Range(0, 2);                              // 随机生成移动类型,0:直走;1:转弯
        int angOffset;                                                  // 仅直走生效,直走的倾斜角
        int angSpeed;                                                   // 仅转弯生效,转弯的角速度

        if (moveType == 0)
        {
    
    
            angOffset = Random.Range(-22, 22);                          // 随机生成倾斜角
            StartCoroutine(GenStraightFish(genPosIndex, fishPreIndex, num, speed, angOffset));   // 开始生成直走的鱼
        }
        else
        {
    
    
            if (Random.Range(0, 2) == 0)        // 是否取负的角速度
            {
    
    
                angSpeed = Random.Range(-15, -9);       // 随机生成负的角速度
            }
            else
            {
    
    
                angSpeed = Random.Range(9, 15);         // 随机生成正的角速度
            }
            StartCoroutine(GenTrunFish(genPosIndex, fishPreIndex, num, speed, angSpeed));    // 开始生成转弯的鱼
        }
    }

    IEnumerator GenStraightFish(int genPosIndex, int fishPreIndex, int num, int speed, int angOffset)
    {
    
    
        for (int i = 0; i < num; i++)
        {
    
    
            GameObject fish = Instantiate(fishPrefabs[fishPreIndex]);         // 实例化鱼的预制体
            fish.transform.SetParent(fishHolder, false);                      // 设置鱼的父物体
            fish.transform.localPosition = genPositions[genPosIndex].localPosition;     // 设置鱼的本地位置
            fish.transform.localRotation = genPositions[genPosIndex].localRotation;     // 设置鱼的本地旋转
            fish.transform.Rotate(0, 0, angOffset);                            // 对鱼进行倾斜角旋转
            fish.GetComponent<SpriteRenderer>().sortingOrder += i;            // 设置鱼的渲染层级
            fish.AddComponent<Ef_AutoMove>().speed = speed;                     // 添加自动移动组件并设置速度
            yield return new WaitForSeconds(fishGenWaitTime);                  // 等待一段时间后继续生成下一条鱼
        }
    }

    IEnumerator GenTrunFish(int genPosIndex, int fishPreIndex, int num, int speed, int angSpeed)
    {
    
    
        for (int i = 0; i < num; i++)
        {
    
    
            GameObject fish = Instantiate(fishPrefabs[fishPreIndex]);          // 实例化鱼的预制体
            fish.transform.SetParent(fishHolder, false);                       // 设置鱼的父物体
            fish.transform.localPosition = genPositions[genPosIndex].localPosition;      // 设置鱼的本地位置
            fish.transform.localRotation = genPositions[genPosIndex].localRotation;      // 设置鱼的本地旋转
            fish.GetComponent<SpriteRenderer>().sortingOrder += i;             // 设置鱼的渲染层级
            fish.AddComponent<Ef_AutoMove>().speed = speed;                      // 添加自动移动组件并设置速度
            fish.AddComponent<Ef_AutoRotate>().speed = angSpeed;                 // 添加自动旋转组件并设置角速度
            yield return new WaitForSeconds(fishGenWaitTime);                   // 等待一段时间后继续生成下一条鱼
        }
    }
}


多种炮台

多种炮台,点击按钮进行升级

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


多种子弹

升级后,子弹也会升级,伤害更高。

在这里插入图片描述


多种网

升级后,渔网的大小和形状也会升级,范围更大、消失时间更长

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


游戏控制器

游戏控制器(GameController)的脚本,负责管理游戏的各种逻辑和UI元素。

该脚本的功能和作用如下:

声明了GameController的单例模式,提供对唯一实例的访问。
声明了一系列用于显示UI的文本、按钮和滑动条等元素。
定义了一些游戏的变量,如等级(lv)、经验值(exp)、金币(gold)、倒计时等等。
声明了一些用于显示游戏背景、特效和子弹的元素,如背景图片(bgImage)、特效(fireEffect、changeEffect等)、子弹对象数组等。
在Awake函数中初始化GameController的实例。
在Start函数中读取之前保存的游戏数据,并更新UI的显示。
在Update函数中更新游戏逻辑,包括切换子弹的花费、开火、更新UI、切换背景等。
定义了ChangeBg函数,用于根据当前等级切换游戏背景。
定义了UpdateUI函数,用于更新游戏UI的显示,包括倒计时、金币、等级等。
定义了Fire函数,用于处理开火逻辑,生成子弹并扣除金币。
定义了ChangeBulletCost函数,用于根据鼠标滚轮的输入切换子弹花费。
定义了一些按钮的回调函数,如OnButtonPDown和OnButtonMDown,用于切换子弹花费。
定义了OnBigCountdownButtonDown函数,用于处理大倒计时按钮的点击事件。
定义了GoldNotEnough协程函数,用于在金币不足时显示提示信息。

该脚本是一个游戏控制器,负责管理游戏的逻辑、UI和各种元素的显示和交互。它处理了游戏中的等级、经验、金币、倒计时、背景切换、开火等功能,并提供了与UI元素交互的回调函数。

using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class GameController : MonoBehaviour
{
    
    
    private static GameController _instance;
    public static GameController Instance
    {
    
    
        get
        {
    
    
            return _instance;
        }
    }

    // UI 元素的引用
    public Text oneShootCostText; // 显示一次射击的花费
    public Text goldText; // 显示金币数量
    public Text lvText; // 显示等级
    public Text lvNameText; // 显示等级名称
    public Text smallCountdownText; // 显示小倒计时
    public Text bigCountdownText; // 显示大倒计时
    public Button bigCountdownButton; // 大倒计时按钮
    public Button backButton; // 返回按钮
    public Button settingButton; // 设置按钮
    public Slider expSlider; // 经验条

    // 游戏状态变量
    public int lv = 0; // 等级
    public int exp = 0; // 经验值
    public int gold = 500; // 金币数量
    public const int bigCountdown = 240; // 大倒计时常量
    public const int smallCountdown = 60; // 小倒计时常量
    public float bigTimer = bigCountdown; // 大倒计时计时器
    public float smallTimer = smallCountdown; // 小倒计时计时器
    public Color goldColor; // 金币的颜色
    public int bgIndex = 0; // 背景索引

    // 引用的游戏对象和精灵数组
    public Image bgImage; // 背景图像
    public GameObject lvUpTips; // 升级提示
    public GameObject seaWaveEffect; // 海浪特效
    public GameObject fireEffect; // 开火特效
    public GameObject changeEffect; // 切换特效
    public GameObject lvEffect; // 升级特效
    public GameObject goldEffect; // 金币特效

    public Transform bulletHolder; // 子弹容器
    public Sprite[] bgSprites; // 背景精灵数组
    public GameObject[] gunGos; // 枪支游戏对象数组
    public GameObject[] bullet1Gos; // 炮弹1游戏对象数组
    public GameObject[] bullet2Gos; // 炮弹2游戏对象数组
    public GameObject[] bullet3Gos; // 炮弹3游戏对象数组
    public GameObject[] bullet4Gos; // 炮弹4游戏对象数组
    public GameObject[] bullet5Gos; // 炮弹5游戏对象数组

    // 使用的是第几档的炮弹
    private int costIndex = 0;
    // 每一炮所需的金币数和造成的伤害值
    private int[] oneShootCosts = {
    
     5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 };
    private string[] lvName = {
    
     "新手", "入门", "钢铁", "青铜", "白银", "黄金", "白金", "钻石", "大师", "宗师" };

    void Awake()
    {
    
    
        // 单例模式
        _instance = this;
    }

    void Start()
    {
    
    
        // 从 PlayerPrefs 中获取存储的数据
        gold = PlayerPrefs.GetInt("gold", gold);
        lv = PlayerPrefs.GetInt("lv", lv);
        exp = PlayerPrefs.GetInt("exp", exp);
        smallTimer = PlayerPrefs.GetFloat("scd", smallCountdown);
        bigTimer = PlayerPrefs.GetFloat("bcd", bigCountdown);
        UpdateUI();
    }

    void Update()
    {
    
    
        // 更新各种状态和 UI
        ChangeBulletCost();
        Fire();
        UpdateUI();
        ChangeBg();
    }

    // 改变背景
    void ChangeBg()
    {
    
    
        if (bgIndex != lv / 20)
        {
    
    
            // 根据等级计算背景索引
            bgIndex = lv / 20;
            AudioManager.Instance.PlayEffectSound(AudioManager.Instance.seaWaveClip);
            Instantiate(seaWaveEffect);
            if (bgIndex >= 3)
            {
    
    
                bgImage.sprite = bgSprites[3];
            }
            else
            {
    
    
                bgImage.sprite = bgSprites[bgIndex];
            }
        }
    }

    // 更新 UI
    void UpdateUI()
    {
    
    
        bigTimer -= Time.deltaTime;
        smallTimer -= Time.deltaTime;
        if (smallTimer <= 0)
        {
    
    
            smallTimer = smallCountdown;
            gold += 50;
        }
        if (bigTimer <= 0 && bigCountdownButton.gameObject.activeSelf == false)
        {
    
    
            bigCountdownText.gameObject.SetActive(false);
            bigCountdownButton.gameObject.SetActive(true);
        }
        // 经验等级换算公式:升级所需经验=1000+200*当前等级
        while (exp >= 1000 + 200 * lv)
        {
    
    
            exp = exp - (1000 + 200 * lv);
            lv++;
            lvUpTips.SetActive(true);
            lvUpTips.transform.Find("Text").GetComponent<Text>().text = lv.ToString();
            StartCoroutine(lvUpTips.GetComponent<Ef_HideSelf>().HideSelf(0.6f));
            AudioManager.Instance.PlayEffectSound(AudioManager.Instance.lvUpClip);
            Instantiate(lvEffect);
        }
        goldText.text = "$" + gold;
        lvText.text = lv.ToString();
        if ((lv / 10) <= 9)
        {
    
    
            lvNameText.text = lvName[lv / 10];
        }
        else
        {
    
    
            lvNameText.text = lvName[9];
        }
        smallCountdownText.text = "  " + (int)smallTimer / 10 + "  " + (int)smallTimer % 10;
        bigCountdownText.text = (int)bigTimer + "s";
        expSlider.value = ((float)exp) / (1000 + 200 * lv);
    }

    // 开火
    void Fire()
    {
    
    
        GameObject[] useBullets = bullet5Gos;
        int bulletIndex;
        if (Input.GetMouseButtonDown(0) && EventSystem.current.IsPointerOverGameObject() == false)
        {
    
    
            if (gold - oneShootCosts[costIndex] >= 0)
            {
    
    
                switch (costIndex / 4)
                {
    
    
                    case 0: useBullets = bullet1Gos; break;
                    case 1: useBullets = bullet2Gos; break;
                    case 2: useBullets = bullet3Gos; break;
                    case 3: useBullets = bullet4Gos; break;
                    case 4: useBullets = bullet5Gos; break;
                }
                bulletIndex = (lv % 10 >= 9) ? 9 : lv % 10;
                gold -= oneShootCosts[costIndex];
                AudioManager.Instance.PlayEffectSound(AudioManager.Instance.fireClip);
                Instantiate(fireEffect);
                GameObject bullet = Instantiate(useBullets[bulletIndex]);
                bullet.transform.SetParent(bulletHolder, false);
                bullet.transform.position = gunGos[costIndex / 4].transform.Find("FirePos").transform.position;
                bullet.transform.rotation = gunGos[costIndex / 4].transform.Find("FirePos").transform.rotation;
                bullet.GetComponent<BulletAttr>().damage = oneShootCosts[costIndex];
                bullet.AddComponent<Ef_AutoMove>().dir = Vector3.up;
                bullet.GetComponent<Ef_AutoMove>().speed = bullet.GetComponent<BulletAttr>().speed;
            }
            else
            {
    
    
                StartCoroutine(GoldNotEnough());
            }
        }
    }

    // 切换炮弹花费
    void ChangeBulletCost()
    {
    
    
        if (Input.GetAxis("Mouse ScrollWheel") < 0)
        {
    
    
            OnButtonMDown();
        }
        if (Input.GetAxis("Mouse ScrollWheel") > 0)
        {
    
    
            OnButtonPDown();
        }
    }

    // 点击 "+" 按钮
    public void OnButtonPDown()
    {
    
    
        gunGos[costIndex / 4].SetActive(false);
        costIndex++;
        AudioManager.Instance.PlayEffectSound(AudioManager.Instance.changeClip);
        Instantiate(changeEffect);
        costIndex = (costIndex > oneShootCosts.Length - 1) ? 0 : costIndex;
        gunGos[costIndex / 4].SetActive(true);
        oneShootCostText.text = "$" + oneShootCosts[costIndex];
    }

    // 点击 "-" 按钮
    public void OnButtonMDown()
    {
    
    
        gunGos[costIndex / 4].SetActive(false);
        costIndex--;
        AudioManager.Instance.PlayEffectSound(AudioManager.Instance.changeClip);
        Instantiate(changeEffect);
        costIndex = (costIndex < 0) ? oneShootCosts.Length - 1 : costIndex;
        gunGos[costIndex / 4].SetActive(true);
        oneShootCostText.text = "$" + oneShootCosts[costIndex];
    }

    // 点击大倒计时按钮
    public void OnBigCountdownButtonDown()
    {
    
    
        gold += 500;
        AudioManager.Instance.PlayEffectSound(AudioManager.Instance.rewardClip);
        Instantiate(goldEffect);
        bigCountdownButton.gameObject.SetActive(false);
        bigCountdownText.gameObject.SetActive(true);
        bigTimer = bigCountdown;
    }

    // 金币不足时的协程
    IEnumerator GoldNotEnough()
    {
    
    
        goldText.color = goldColor;
        goldText.color = Color.red;
        yield return new WaitForSeconds(0.5f);
        goldText.color = goldColor;
    }
}


声音控制器

Awake(): 在对象被创建时调用,用于初始化音频管理器。它设置音频管理器的实例,并从PlayerPrefs中获取静音状态,并根据静音状态设置音频的播放状态。

SwitchMuteState(bool isOn): 切换静音状态的方法。根据传入的参数 isOn 来确定是否要静音。它会反转静音状态,并调用 DoMute() 方法以应用变更。

DoMute(): 根据静音状态来控制背景音乐的播放和暂停。如果静音,背景音乐会暂停播放;如果非静音,背景音乐会开始播放。

PlayEffectSound(AudioClip clip): 播放音效的方法。根据当前的静音状态,判断是否播放音效。如果非静音,会在世界坐标原点(Vector3.zero)处播放传入的音效剪辑。

using UnityEngine;

public class AudioManager : MonoBehaviour
{
    
    
    private static AudioManager _instance;
    public static AudioManager Instance
    {
    
    
        get
        {
    
    
            return _instance;
        }
    }

    private bool isMute = false;
    public bool IsMute
    {
    
    
        get
        {
    
    
            return isMute;
        }
    }

    public AudioSource bgmAudioSource; // 背景音频源
    public AudioClip seaWaveClip; // 海浪音频剪辑
    public AudioClip goldClip; // 金币音频剪辑
    public AudioClip rewardClip; // 奖励音频剪辑
    public AudioClip fireClip; // 发射音频剪辑
    public AudioClip changeClip; // 切换音频剪辑
    public AudioClip lvUpClip; // 升级音频剪辑

    void Awake()
    {
    
    
        _instance = this;
        isMute = (PlayerPrefs.GetInt("mute", 0) == 0) ? false : true; // 从PlayerPrefs中获取静音状态
        DoMute();
    }

    public void SwitchMuteState(bool isOn)
    {
    
    
        isMute = !isOn; // 切换静音状态
        DoMute();
    }

    void DoMute()
    {
    
    
        if (isMute)
        {
    
    
            bgmAudioSource.Pause(); // 静音时暂停背景音乐
        }
        else
        {
    
    
            bgmAudioSource.Play(); // 恢复播放背景音乐
        }
    }

    public void PlayEffectSound(AudioClip clip)
    {
    
    
        if (!isMute)
        {
    
    
            AudioSource.PlayClipAtPoint(clip, Vector3.zero); // 在世界坐标原点播放音效
        }
    }
}


游戏存档

在这里插入图片描述

Start(): 在对象启动时调用,用于初始化主场景的UI。它设置静音开关的初始状态,根据音频管理器的静音状态来确定切换按钮的选中状态。

SwitchMute(bool isOn): 切换静音状态的方法。根据传入的参数 isOn 来确定是否要静音。它调用音频管理器的 SwitchMuteState() 方法来切换静音状态。

OnBackButtonDown(): 返回按钮按下时调用的方法。它保存当前游戏状态(包括金币、等级、计时器、经验和静音状态)到 PlayerPrefs 中,并加载场景索引为 0 的场景。

OnSettingButtonDown(): 设置按钮按下时调用的方法。它激活设置面板,使其可见。

OnCloseButtonDown(): 关闭按钮按下时调用的方法。它隐藏设置面板,使其不可见。

using UnityEngine;
using UnityEngine.UI;

public class MainSceneUI : MonoBehaviour
{
    
    
    public Toggle muteToogle;       // 静音切换开关
    public GameObject settingPanel; // 设置面板

    void Start()
    {
    
    
        muteToogle.isOn = !AudioManager.Instance.IsMute; // 设置静音开关的初始状态为音频管理器的静音状态的相反值
    }

    public void SwitchMute(bool isOn)
    {
    
    
        AudioManager.Instance.SwitchMuteState(isOn); // 切换静音状态
    }

    public void OnBackButtonDown()
    {
    
    
        // 保存当前游戏状态到PlayerPrefs
        PlayerPrefs.SetInt("gold", GameController.Instance.gold);
        PlayerPrefs.SetInt("lv", GameController.Instance.lv);
        PlayerPrefs.SetFloat("scd", GameController.Instance.smallTimer);
        PlayerPrefs.SetFloat("bcd", GameController.Instance.bigTimer);
        PlayerPrefs.SetInt("exp", GameController.Instance.exp);
        int temp = (AudioManager.Instance.IsMute == false) ? 0 : 1;
        PlayerPrefs.SetInt("mute", temp);

        // 加载场景索引为0的场景
        UnityEngine.SceneManagement.SceneManager.LoadScene(0);
    }

    public void OnSettingButtonDown()
    {
    
    
        settingPanel.SetActive(true); // 激活设置面板,使其可见
    }

    public void OnCloseButtonDown()
    {
    
    
        settingPanel.SetActive(false); // 关闭设置面板,使其不可见
    }
}


游戏开始

在这里插入图片描述

using UnityEngine;
using UnityEngine.SceneManagement;

public class StartSceneUI : MonoBehaviour
{
    
    
    public void NewGame()
    {
    
    
        // 删除已保存的游戏状态
        PlayerPrefs.DeleteKey("gold");
        PlayerPrefs.DeleteKey("lv");
        PlayerPrefs.DeleteKey("exp");
        PlayerPrefs.DeleteKey("scd");
        PlayerPrefs.DeleteKey("bcd");

        // 加载场景索引为1的场景(新游戏场景)
        SceneManager.LoadScene(1);
    }

    public void OldGame()
    {
    
    
        // 加载场景索引为1的场景(继续游戏场景)
        SceneManager.LoadScene(1);
    }

    public void OnCloseButton()
    {
    
    
        // 关闭应用程序
        Application.Quit();
    }
}


猜你喜欢

转载自blog.csdn.net/qq_20179331/article/details/130864141
今日推荐