unity制作捕鱼达人

news2025/2/11 15:24:39

文章目录

  • 介绍
  • 制作水波特效
  • 制作多种ui
  • 制作不同种类鱼的动画
  • 鱼的多种移动效果
  • 制作鱼的生成点
  • 多种炮台
  • 多种子弹
  • 多种网
  • 游戏控制器
  • 声音控制器
  • 游戏存档
  • 游戏开始


介绍

水波荡漾的特效
鱼有多种运动轨迹
每隔一段时间自动收集金币
可以切换不同的炮台
升级后有不同的特效
捕捉到普通鱼类有金币特效
捕捉到大金鱼后有特效
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();
    }
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/645948.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Salesforce开发人员如何利用生成式AI?

AI浪潮来袭&#xff0c;技术和产品的新消息奔涌而来&#xff0c;开发者们的工作模式正在经历巨变。ChatGPT的出现&#xff0c;让问题的解法更有想象力&#xff0c;也让敲下一行代码、发布一款产品变得更容易。 AI可以帮助指导开发过程中的错误&#xff0c;并改进解决方案&…

ChatGPT/InstructGPT详解

前言 GPT系列是OpenAI的一系列预训练文章&#xff0c;GPT的全称是Generative Pre-Trained Transformer&#xff0c;顾名思义&#xff0c;GPT的目的就是通过Transformer为基础模型&#xff0c;使用预训练技术得到通用的文本模型。目前已经公布论文的有文本预训练GPT-1&#xff…

【iM群发部署,苹果推是什么】苹果日历推,配置 iOS 设备:您可以创建自定义配置文件

Apple Configurator 是苹果官方提供的一款工具&#xff0c;主要面向企业和教育机构&#xff0c;用于集中管理和配置多个 iOS 设备。 使用 Apple Configurator&#xff0c;您可以在 PC 端进行以下操作&#xff1a; 配置 iOS 设备&#xff1a;您可以创建自定义配置文件&#xf…

经典文献阅读之--A Review of Motion Planning(轨迹规划回顾)

0. 简介 对于自动驾驶以及机器人而言&#xff0c;除了SLAM以外&#xff0c;另一个比较重要的部分就是轨迹规划了。而最近作者看到了几篇比较好的文章&#xff0c;分别为《A Review of Motion Planning Techniques for Automated Vehicle》、《A review of motion planning alg…

《现代中学生》初中版期刊简介及投稿邮箱

《现代中学生》初中版期刊简介&#xff1a; 《现代中学生》现代中学生初中版 主管单位 吉林省教育厅 主办单位 吉林教育杂志社 国际刊号ISSN&#xff1a;1009-5748&#xff1b;国内刊号CN&#xff1a;22-1046/G4&#xff1b;邮发代号&#xff1a;12-52 出版周期&#xff1…

关于MySQL数据库的基本概念

MySQL数据库初体验 一、数据库的基本概念二、 数据库的发展三、主流的数据库介绍四、 关系数据库五、非关系数据库 一、数据库的基本概念 1. 数据 (Data) 数据就是描述事物的符号记录。包括数字&#xff0c;文字、图形、图像、声音、档案记录等。以“记录”形式按统一的格式进…

三勾点餐新增功能特价团购

点击后台-插件-特价团购&#xff0c;展示下方界面 ☆ 团购订单 所有团购的订单将在此处展示订单搜索&#xff1a;填写任意项点击“查询即可订单详情&#xff1a;可以看到单个订单的基本信息、门店信息、团购信息、付款信息、券码信息订单核销&#xff1a;前端核销&#xff0c;…

MySQL性能深度优化

这里的深度优化是指&#xff0c;除了建索引、左匹配索引等等其他的优化手段。 文章涉及到操作系统连接数、IO、Mysql本身的某些参数设置&#xff0c;值得记录下来。 文章目录 一.数据库服务器配置二.CPU的优化三.内存的优化四.IO的优化五.连接的优化六.数据一致性的优化原文链…

scDesign3:多模态单细胞和空间组学数据生成

scDesign3是一个统计模拟器&#xff0c;通过从真实数据中学习可解释的参数&#xff0c;生成真实的单细胞和空间组学数据&#xff0c;包括各种细胞状态、实验设计和特征模态。使用单细胞和空间组学数据的统一概率模型&#xff0c;scDesign3可以推断出具有生物学意义的参数&#…

DC降压电源模块 输入8-32V输出电流50A/1V-12V 恒流恒压可调模块

【产品参数】 [] 非隔离同步降压(BUCK)电源模块 [] 宽输入DC6-32V&#xff0c;输出DC0.6-12.2V [] 峰值效率>96% [] 过流保护 短路保护自恢复 [] 远程ON/OFF [] 过温保护、高稳压精度、动态响应快 [] 输出限流指示灯 [] 输出电压电流可调 [] 低纹波、低静态电流 […

Kafka学习--3、Kafka Broker、节点服役和退役、Kafka 副本、Leader 选举流程、故障处理

1、Kafka Broker 1.1 Kafka Broker工作流程 1.1.1 Zookeeper储存的Kafka信息 &#xff08;1&#xff09;启动Zookeeper集群、再启动Kafka集群&#xff0c;然后启动Zookeeper客户端 &#xff08;2&#xff09;通过ls命令可以查看kafka相关信息。 1.1.2 Kafka Broker总体工作…

【冷冻电镜】IMOD使用教程(Etomo tutorial)

参考教程&#xff1a; Etomo Tuturial for IMOD version 4.11 1. Initial Setup 本教程提供了一个小双轴示例数据集和Etomo的分布指南&#xff0c;更详细的内容参考Tomography Guide。该版本使用1k*1k的图像而不是压缩版本。imodhelp命令可以打开帮助界面&#xff0c;查看各种…

自定义修改Typora原生默认github风格样式

使用typora的时候&#xff0c;想要自定义一些颜色、字体&#xff0c;或者修改一些设置&#xff0c;这个时候需要修改或者自己编写css文件。 修改涉及的样式&#xff1a; ① 目录 ② 块应用 我还是比较喜欢原生自带的默认样式&#xff08;github样式&#xff09;&#xff0c; 但…

公司采购缺进项发票,税负重?买票违法不可取,这招可合规节税!

公司采购缺进项发票&#xff0c;税负重&#xff1f;买票违法不可取&#xff0c;这招可合规节税&#xff01; 《税筹顾问》专注于园区招商&#xff0c;您的贴身节税小能手&#xff0c;合理合规节税&#xff01; 自从金税四期的上线&#xff0c;我国的税务环境有了翻天覆地的变化…

软件开发流程解析

文章目录 1. 软件开发生命周期2.常见开发流程2.1 瀑布模型2.2 敏捷开发 3.实例开发过程示例 1. 软件开发生命周期 来源于百度百科&#xff1a;软件生命周期(Software Life Cycle,SLC)是软件的产生直到报废或停止使用的生命周期。软件生命周期内有问题定义、可行性分析、总体描述…

哈工大人工智能数学基础考试题型和资料(考查课)

大作业 【免费】人工智能数学基础11111资源-CSDN文库 PPT (1条消息) 【免费】人工智能数学基础PPT解压缩打开不会出现乱码资源-CSDN文库

Docker安装wordpress并配置数据库(详细步骤)

Docker在线拉取安装wordpress并配置数据库 一、拉取wordpress镜像(默认最新)二、启动wordpress容器三、查看容器状态四、安装wordpress博客程序 如果您已经在 Docker 容器中分别安装了 WordPress 和 MySQL&#xff0c;并且想要让它们链接起来&#xff0c;可以按照以下步骤进行操…

这所武汉的211,面试仅占比15%,却刷掉了409分的同学!Why?

一、学校及专业介绍 武汉理工大学&#xff08;Wuhan University of Technology&#xff09;&#xff0c;简称武理工&#xff0c;位于武汉市&#xff0c;是中华人民共和国教育部直属全国重点大学&#xff0c;国家“双一流”建设高校&#xff0c;“211工程”、“985工程优势学科创…

西门子PPI协议开发

目录 西门子PPI协议开发 1 协议介绍 2 仿真环境 2.1 安装修改仿真软件 2.2 设置PPI串口 3 报文示例 西门子PPI协议开发 西门子PPI协议适用S7-200、S7-200SMART PLC。 1 协议介绍 仔细读下&#xff0c;用于开发是满足的&#xff0c;不用再去找其他文章了。网上找了不少&a…

wfe进不了standby模式怎么办

快速链接: . &#x1f449;&#x1f449;&#x1f449; 【目录】ARM/TEE/ATF/SOC微信群问题记录 &#x1f448;&#x1f448;&#x1f448; 付费专栏-付费课程 【购买须知】:联系方式-加入交流群 ----联系方式-加入交流群 (说明&#xff1a;本文总结来自于微信群的公开讨论&a…