[(一)UI 功能需求](#(一)UI 功能需求)
[3.开始面板完善:BeginPanel 更新](#3.开始面板完善:BeginPanel 更新)
演示
一、需求分析
1.项目所需具备前提知识
(1)Unity : 理解 Unity 编辑器操作、场景搭建、游戏对象管理等核心基础。
(2)数据持久化: 能够通过 PlayerPrefs 实现数据的存储与读取。
**(3)UI 开发:**具备使用 GUI 创建游戏界面、添加交互控件的能力。
2.核心需求框架
(1)UI 功能
(2)数据存储功能
(3)游戏核心逻辑功能
**3.**详细功能需求
(一)UI 功能需求
8 个 UI 面板脚本,同时提取 1 个基类脚本封装所有 UI 面板的共同点

**(1)基类脚本:**提取所有 UI 面板的共性逻辑,如面板的显示 / 隐藏控制、通用控件初始化、基础交互事件绑定等,为 7 个功能面板提供基础支撑。
**(2)开始界面面板:**包含 "开始游戏""游戏设置""退出游戏" 三个核心按钮,点击对应按钮可触发进入游戏、打开设置界面、退出游戏(退出时需提示 "此时退出游戏成绩将丢失")的操作,是玩家进入游戏的入口界面。
**(3)游戏界面面板:**实时更新游戏关键信息,包括游戏时间、坦克血量、玩家分数,同时配置退出游戏的关键控件及监听函数,玩家可通过该面板直观掌握游戏进度与自身状态。
**(4)游戏设置面板:**核心功能为控制音视频相关数据,提供音乐、音效的开关控制及音量调节功能,玩家可根据自身需求调整游戏音频输出,提升游戏体验。
**(5)游戏失败界面面板:**当玩家坦克被摧毁时触发显示,界面提示 "很遗憾,您的坦克已被摧毁",同时提供 "重来""返回上一级""再次挑战" 按钮,支持玩家重新开始游戏或返回上级菜单。
**(6)游戏胜利界面面板:**玩家通关时显示,提示 "恭喜通关",并提供用户名输入框与 "确定" 按钮,玩家输入用户名后点击确定,即可将本次通关成绩计入排行榜。
**(7)排行榜面板:**以表格形式展示玩家排名信息,表格包含 "排名""玩家名""分数""通关时间" 四列,默认展示 10 个排名位置,未填充的位置标注 "虚位以待",玩家可在该面板查看历史优秀成绩,同时支持 "返回上一级" 操作。
**(8)功能面板:**整合游戏过程中的辅助功能控件与监听函数,为其他功能面板提供交互支持,确保各界面操作逻辑连贯。

(二)数据存储功能需求
通过设计 "数据管理类" 统一管理游戏数据,实现关键信息的持久化存储,确保玩家设置与游戏成绩不丢失

(1)音效设置信息存储:记录背景音乐、音效的开关状态及音量大小数据,玩家调整音效设置后,数据管理类通过 PlayerPrefs 将设置信息存储,下次启动游戏时自动加载上次设置,无需重复调整。
(2)排行榜信息存储:存储排行榜单条数据(包含玩家名字、分数、通关时间),形成排行榜数据列表。当玩家通关并输入用户名后,数据管理类将新成绩与历史成绩对比排序,更新排行榜并存储,确保排行榜信息实时、准确。

(三)游戏核心逻辑功能需求
(1)坦克类设计:提取所有坦克的共同点,创建 "坦克基类",包含坦克血量、移动速度、开火间隔时间等基础属性,以及移动、开火、受击等通用方法;在此基础上设计 "敌方移动坦克" 子类,处理敌方坦克的简单 AI 逻辑(如自动移动、攻击)与怪物相关行为,区分玩家坦克与敌方坦克的功能差异。
(2)战斗与奖励逻辑:
【1】战斗机制:玩家坦克可装备武器,武器存在开火间隔时间限制,发射的子弹命中敌方坦克或障碍物时触发相应碰撞处理;敌方坦克被摧毁后可能生成奖励对象,玩家坦克获取奖励可触发属性加成(如血量奖励)或武器升级(如切换特殊子弹)。
【2】奖励处理:场景中设置可获取的武器奖励对象与属性临时奖励对象,玩家坦克接触奖励对象后触发领取逻辑,实时更新自身属性或武器状态,增强游戏策略性与趣味性。
(3)场景与视角逻辑:配置小地图摄像机,实现摄像机跟随玩家坦克移动的功能,同时在小地图中标记玩家坦克、敌方坦克、奖励对象等关键物体信息,帮助玩家掌握整个战场布局,提升游戏操作体验。
(4)得分与死亡逻辑:玩家摧毁敌方坦克、获取奖励时触发得分逻辑,实时累计并更新分数;当玩家坦克血量为 0 时触发死亡逻辑,跳转至游戏失败界面,结束当前游戏进程。
二、场景搭建
1.导入素材

2.个性化搭建
(1)从导入的资源中,搭建个性化的场地

(2)从导入的GUI预制体中,搭建个性化的UI界面,如上图所示:

三、开始界面面板

1.通用面板基类:BasePanel<T>
实现一个泛型基类 BasePanel<T>:
(1)
为所有 UI 面板提供单例管理
(2)显示 / 隐藏基础功能,避免重复编码。
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BasePanel<T> : MonoBehaviour where T:class
{
//两个关键的静态成员
//私有的静态成员变量(申明)
private static T instance;
//公共的静态成员属性或者方法(获取)
public static T Instance => instance;
private void Awake()
{
//在Awake中初始化的 原因是
//我们的面板脚本 在场景上 肯定只会挂载一次
//那么我们可以在这个脚本的生命周期函数的Awake中
//直接记录场景上 唯一的这个脚本
instance = this as T;
}
public virtual void ShowMe()
{
this.gameObject.SetActive(true);
}
public virtual void HideMe()
{
this.gameObject.SetActive(false);
}
}
2.核心功能说明
(1)单例模式实现 :通过静态私有变量 instance
与公开属性 Instance
,确保每个面板在场景中只有一个实例,外部可通过 XXXPanel.Instance
直接访问(如后续的 BeginPanel.Instance
)。
(2)生命周期初始化 :在 Awake
方法中完成单例赋值,因为 Awake
在脚本生命周期中仅执行一次,且早于 Start
,能保证面板实例在使用前完成初始化。
(3)基础显示 / 隐藏接口 :提供 ShowMe()
(激活面板)和 HideMe()
(隐藏面板)两个虚方法,子类可根据需要重写(如添加动画过渡),当前保持基础功能。
3.开始界面面板:BeginPanel
BeginPanel
继承自 BasePanel<BeginPanel>
,是游戏启动后第一个交互界面,负责 "开始游戏""设置""退出""排行榜" 等核心操作入口。
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class BeginPanel : BasePanel<BeginPanel>
{
//首先声明公共的成员变量 来关联各个控件
public CustomGUIButton btnBegin;
public CustomGUIButton btnSetting;
public CustomGUIButton btnQuit;
public CustomGUIButton btnRank;
// Start is called before the first frame update
void Start()
{
//监听一次按钮点击过后要做什么
btnBegin.clickEvent += () =>
{
//切换场景
SceneManager.LoadScene("GameScene");
};
btnSetting.clickEvent += () =>
{
//打开设置面板
};
btnQuit.clickEvent += () =>
{
//退出游戏
Application.Quit();
};
btnRank.clickEvent += () =>
{
//打开排行榜面板
};
}
}
4.核心功能说明
(1)控件关联:声明 4 个 CustomGUIButton
类型的公共变量(btnBegin
/btnSetting
/btnQuit
/btnRank
),需在 Unity Inspector 面板中手动将 UI 按钮拖入对应字段,完成脚本与控件的绑定。
(2)按钮点击事件:在 Start
方法中为每个按钮绑定点击逻辑(基于自定义按钮的 clickEvent
事件):
- 开始游戏(btnBegin):通过
SceneManager.LoadScene("GameScene")
加载游戏主场景(需确保 "GameScene" 已在 Build Settings 中添加); - 退出游戏(btnQuit):通过
Application.Quit()
关闭游戏(打包后生效,Editor 模式下需额外处理可参考后续扩展); - 设置(btnSetting) 与 排行榜(btnRank):当前预留接口,后续可添加
SettingPanel.Instance.ShowMe()
与RankPanel.Instance.ShowMe()
实现面板切换。
四、设置面板实现

1.设置面板:SettingPanel
设置面板用于管理游戏中的音乐、音效等配置,继承自通用基类BasePanel<SettingPanel>
,实现基本的音视频设置功能。
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SettingPanel : BasePanel<SettingPanel>
{
//1. 声明成员变量 关联控件
public CustomGUISlider sliderMusic; // 音乐音量滑块
public CustomGUISlider sliderSound; // 音效音量滑块
public CustomGUIToggle togMusic; // 音乐开关
public CustomGUIToggle togSound; // 音效开关
public CustomGUIButton btnClose; // 关闭按钮
// Start is called before the first frame update
void Start()
{
//2. 监听对应的事件 处理逻辑
sliderMusic.changeValue += (value) =>
{
// 处理音乐音量变化
};
sliderSound.changeValue += (value) =>
{
// 处理音效音量变化
};
togMusic.changeValue += (value) =>
{
// 处理音乐开关状态变化
};
togSound.changeValue += (value) =>
{
// 处理音效效开关状态变化
};
btnClose.clickEvent += () =>
{
// 隐藏当前设置面板
HideMe();
// 重新显示开始面板
BeginPanel.Instance.ShowMe();
};
// 初始隐藏设置面板
HideMe();
}
}
2.功能说明
(1)控件关联:通过公共变量关联 4 个核心控件(2 个滑块、2 个开关、1 个按钮),需在 Unity Inspector 中手动绑定对应 UI 元素。
(2)事件绑定:
- 音量滑块(
sliderMusic
/sliderSound
):通过changeValue
事件监听数值变化,预留音乐 / 音效音量调节逻辑接口; - 开关控件(
togMusic
/togSound
):通过changeValue
事件监听开关状态,预留音乐 / 音效启用 / 禁用逻辑接口; - 关闭按钮(
btnClose
):点击后隐藏当前面板(HideMe()
),并重新显示开始面板(BeginPanel.Instance.ShowMe()
),实现面板切换。
(3)初始状态 :在Start
方法末尾调用HideMe()
,确保游戏启动时设置面板默认隐藏。
3.开始面板完善:BeginPanel 更新
cs
......
btnSetting.clickEvent += () =>
{
// 打开设置面板
SettingPanel.Instance.ShowMe();
// 隐藏当前开始面板(避免点击穿透)
HideMe();
};
......
在btnSetting
的点击事件中,通过SettingPanel.Instance.ShowMe()
显示设置面板,并调用HideMe()
隐藏自身,避免两个面板同时显示导致的交互冲突(如点击穿透)。
五、音乐数据管理
1.音乐数据类:MusicData
该类用于定义需要存储的音乐相关配置数据,是数据持久化的基础模型。
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 音效数据类 用于存储音乐设置相关的信息
/// </summary>
public class MusicData
{
//背景音乐是否开启
public bool isOpenBK;
//音效是否开启
public bool isOpenSound;
//背景音乐音量
public float bkValue;
//音效音量
public float soundValue;
//加一个是否是第一次加载数据的标识
public bool notFirst;
}
2.说明
(1)存储了 4 项核心配置:背景音乐开关(isOpenBK
)、音效开关(isOpenSound
)、背景音乐音量(bkValue
)、音效音量(soundValue
)
(2)notFirst
用于标记是否是首次进入游戏,便于初始化默认配置
3.游戏数据管理器:GameDataMgr
单例模式的游戏数据管理类,负责音乐数据的加载、更新和持久化存储。
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 这个是游戏数据管理类 是一个单例模式对象
/// </summary>
public class GameDataMgr
{
private static GameDataMgr instance = new GameDataMgr();
public static GameDataMgr Instance { get => instance; }
//音效数据对象
public MusicData musicData;
private GameDataMgr()
{
//初始化游戏数据
musicData = PlayerPrefsDataMgr.Instance.LoadData(typeof(MusicData), "Music") as MusicData;
//如果第一次进入游戏 没有音效数据 则初始化默认值
if( !musicData.notFirst )
{
musicData.notFirst = true;
musicData.isOpenBK = true;
musicData.isOpenSound = true;
musicData.bkValue = 1;
musicData.soundValue = 1;
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
}
//提供一些API给外部 方便数据的改变存储
//开启或者关闭背景音乐
public void OpenOrCloseBKMusic(bool isOpen)
{
musicData.isOpenBK = isOpen;
//存储改变后的数据
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
//开启或者关闭音效
public void OpenOrCloseSound(bool isOpen)
{
musicData.isOpenSound = isOpen;
//存储改变后的数据
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
//改变背景音乐大小
public void ChangeBKValue(float value)
{
musicData.bkValue = value;
//存储改变后的数据
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
//改变音效大小
public void ChangeSoundValue(float value)
{
musicData.soundValue = value;
//存储改变后的数据
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
}
4.核心功能说明
(1)单例模式 :通过私有构造函数和静态Instance
属性确保全局唯一实例
(2)数据初始化:
- 在构造函数中通过
PlayerPrefsDataMgr
加载本地存储的音乐配置 - 首次进入游戏时自动初始化默认配置(音乐音效开启,音量设为最大 1)
(3)数据操作 API:
- 提供了 4 个方法用于更新音乐配置(开关和音量调节)
- 每次数据变更后自动调用
SaveData
方法持久化存储
5.设置面板完善:SettingPanel
实现配置的实时更新和显示同步
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SettingPanel : BasePanel<SettingPanel>
{
//1声明成员变量 关联控件
public CustomGUISlider sliderMusic;
public CustomGUISlider sliderSound;
public CustomGUIToggle togMusic;
public CustomGUIToggle togSound;
public CustomGUIButton btnClose;
// Start is called before the first frame update
void Start()
{
//2监听对应的事件 处理逻辑
//处理音乐的变化
sliderMusic.changeValue += (value) => GameDataMgr.Instance.ChangeBKValue(value);
//处理音效的变化
sliderSound.changeValue += (value) => GameDataMgr.Instance.ChangeSoundValue(value);
//处理音乐开关
togMusic.changeValue += (value) => GameDataMgr.Instance.OpenOrCloseBKMusic(value);
//处理音效开关
togSound.changeValue += (value) => GameDataMgr.Instance.OpenOrCloseSound(value);
btnClose.clickEvent += () =>
{
//隐藏自己
HideMe();
//让开始面板重新显示出来
BeginPanel.Instance.ShowMe();
};
HideMe();
}
//根据数据 更新面板
public void UpdatePanelInfo()
{
//面板上的信息根据音效数据更新
MusicData data = GameDataMgr.Instance.musicData;
//设置面板内容
sliderMusic.nowValue = data.bkValue;
sliderSound.nowValue = data.soundValue;
togMusic.isSel = data.isOpenBK;
togSound.isSel = data.isOpenSound;
}
public override void ShowMe()
{
base.ShowMe();
//每次显示面板时 同步更新面板内容
UpdatePanelInfo();
}
}
6.核心更新说明
(1)事件绑定优化 :将滑块和开关的事件直接绑定到GameDataMgr
的 API,实现数据的实时更新
(2)面板数据同步:
- 新增
UpdatePanelInfo
方法,用于根据当前存储的音乐数据更新面板控件状态 - 重写
ShowMe
方法,确保每次打开面板时都能显示最新的配置信息
(3)交互逻辑:保持原有面板切换逻辑,关闭按钮点击后仍会隐藏设置面板并显示开始面板
六、排行榜的UI搭建与使用

1.开始面板的完善
cs
public class BeginPanel : BasePanel<BeginPanel>
{
......
btnRank.clickEvent += () =>
{
//打开排行榜面板
RankPanel.Instance.ShowMe();
//避免穿透 隐藏自己
HideMe();
};
......
}
}
排行榜按钮:点击后显示排行榜面板并隐藏自身
2.排行榜面板(RankPanel)
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RankPanel : BasePanel<RankPanel>
{
//关联public的 控件对象
public CustomGUIButton btnClose;
//因为控件较多 拖的话 工作量太大了 我们直接偷懒 通过代码找
private List<CustomGUILabel> labPM = new List<CustomGUILabel>();
private List<CustomGUILabel> labName = new List<CustomGUILabel>();
private List<CustomGUILabel> labScore = new List<CustomGUILabel>();
private List<CustomGUILabel> labTime = new List<CustomGUILabel>();
// Start is called before the first frame update
void Start()
{
for (int i = 1; i <= 10 ; i++)
{
//小知识应用 找子对象的子对象 可以通过 斜杠来区分父子关系
labPM.Add(this.transform.Find("PM/labPM" + i).GetComponent<CustomGUILabel>());
labName.Add(this.transform.Find("Name/labName" + i).GetComponent<CustomGUILabel>());
labScore.Add(this.transform.Find("Score/labScore" + i).GetComponent<CustomGUILabel>());
labTime.Add(this.transform.Find("Time/labTime" + i).GetComponent<CustomGUILabel>());
}
//处理事件监听逻辑
btnClose.clickEvent += () =>
{
HideMe();
BeginPanel.Instance.ShowMe();
};
HideMe();
}
public override void ShowMe()
{
base.ShowMe();
UpdatePanelInfo();
}
public void UpdatePanelInfo()
{
//处理根据排行榜数据 更新面板
}
}
3.说明
(1)控件获取:通过代码查找方式获取 10 条排行榜数据所需的标签控件,分为排名(PM)、名称(Name)、分数(Score)和时间(Time)四个列表
(2)关闭按钮逻辑:点击后隐藏排行榜面板并显示开始面板
(3)面板显示:重写 ShowMe 方法,在显示面板时调用 UpdatePanelInfo 方法更新数据
(4)预留了 UpdatePanelInfo 方法,用于后续根据排行榜数据更新面板显示
七、排行榜数据系统与面板完善
1.单条排行榜数据:RankInfo类
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 排行榜单条数据
/// </summary>
public class RankInfo
{
public string name; // 玩家名称
public int score; // 玩家分数
public float time; // 游戏时间(秒)
public RankInfo()
{
}
public RankInfo(string name, int score, float time)
{
this.name = name;
this.score = score;
this.time = time;
}
}
该类定义了单条排行榜记录应包含的核心信息:玩家名称、分数和游戏时间,提供了默认构造函数和带参构造函数便于数据初始化。
2.排行榜列表容器:RankList类
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 排行榜列表
/// </summary>
public class RankList
{
public List<RankInfo> list; // 排行榜数据列表
}
简单的容器类,用于管理多条排行榜数据,便于进行序列化存储和批量处理。
3.游戏数据管理器完善扩展:GameDataMgr类
cs
public class GameDataMgr
{
......
// 排行榜数据对象
public RankList rankData;
private GameDataMgr()
{
......
// 初始化排行榜数据
rankData = PlayerPrefsDataMgr.Instance.LoadData(typeof(RankList), "Rank") as RankList;
}
// 新增:添加排行榜数据并排序
public void AddRankInfo(string name, int score, float time)
{
rankData.list.Add(new RankInfo(name, score, time));
// 按游戏时间升序排序(时间越短排名越前)
rankData.list.Sort((a, b) => a.time < b.time ? -1 : 1);
// 只保留前10条数据
for (int i = rankData.list.Count - 1; i >= 10; i--)
{
rankData.list.RemoveAt(i);
}
// 保存更新后的数据
PlayerPrefsDataMgr.Instance.SaveData(rankData, "Rank");
}
......
}
4.核心扩展说明
(1)新增数据成员 :添加rankData
用于存储排行榜数据列表
(2)初始化逻辑 :在构造函数中通过PlayerPrefsDataMgr
加载本地存储的排行榜数据
(3)排行榜管理 API:
AddRankInfo
方法:添加新记录、按游戏时间排序、保留前 10 条数据并自动保存- 排序逻辑:使用 Lambda 表达式实现按游戏时间升序排序(时间越短排名越靠前)
- 数据限制:只保留排名前 10 的记录,超出部分从列表尾部移除
5.排行榜面板完善:RankPanel
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RankPanel : BasePanel<RankPanel>
{
// 关闭按钮
public CustomGUIButton btnClose;
// 排行榜显示控件列表(通过代码查找获取)
private List<CustomGUILabel> labName = new List<CustomGUILabel>();
private List<CustomGUILabel> labScore = new List<CustomGUILabel>();
private List<CustomGUILabel> labTime = new List<CustomGUILabel>();
void Start()
{
// 初始化控件列表(获取10条记录的显示控件)
for (int i = 1; i <= 10 ; i++)
{
labName.Add(this.transform.Find("Name/labName" + i).GetComponent<CustomGUILabel>());
labScore.Add(this.transform.Find("Score/labScore" + i).GetComponent<CustomGUILabel>());
labTime.Add(this.transform.Find("Time/labTime" + i).GetComponent<CustomGUILabel>());
}
// 关闭按钮事件
btnClose.clickEvent += () =>
{
HideMe();
BeginPanel.Instance.ShowMe();
};
// 测试代码(可选)
// GameDataMgr.Instance.AddRankInfo("测试数据", 100, 8432);
// 初始隐藏面板
HideMe();
}
// 重写显示方法,显示时更新数据
public override void ShowMe()
{
base.ShowMe();
UpdatePanelInfo();
}
// 更新面板数据
public void UpdatePanelInfo()
{
// 获取排行榜数据
List<RankInfo> list = GameDataMgr.Instance.rankData.list;
// 遍历数据更新UI
for (int i = 0; i < list.Count; i++)
{
// 更新玩家名称
labName[i].content.text = list[i].name;
// 更新分数
labScore[i].content.text = list[i].score.ToString();
// 格式化时间(秒 -> 时:分:秒)
int time = (int)list[i].time;
labTime[i].content.text = "";
// 处理小时
if (time / 3600 > 0)
{
labTime[i].content.text += time / 3600 + "时";
}
// 处理分钟
if (time % 3600 / 60 > 0 || labTime[i].content.text != "")
{
labTime[i].content.text += time % 3600 / 60 + "分";
}
// 处理秒
labTime[i].content.text += time % 60 + "秒";
}
}
}
6.功能说明
(1)控件初始化:通过代码查找方式获取 10 条记录所需的显示控件(名称、分数、时间),避免手动拖拽绑定的繁琐操作
(2)面板交互:关闭按钮点击后隐藏排行榜面板并显示开始面板,保持面板切换的一致性
(3)数据展示:
UpdatePanelInfo
方法:从GameDataMgr
获取排行榜数据并更新到 UI- 时间格式化:将秒数转换为 "时:分: 秒" 的易读格式,只显示有意义的时间单位
(4)显示逻辑 :重写ShowMe
方法,确保每次打开面板时都能显示最新的排行榜数据
7.实现流程与原理
(1)数据流向:
- 新增记录 → 调用
GameDataMgr.AddRankInfo
→ 数据排序与限制 → 保存到本地 - 打开排行榜 → 调用
UpdatePanelInfo
→ 从GameDataMgr
获取数据 → 更新 UI 显示
(2)UI 结构要求:
- 排行榜面板需包含 Name、Score、Time 三个父节点
- 每个父节点下需有 10 个子节点(labName1 至 labName10 等),用于显示对应排名的信息
八、背景音乐管理系统

1.背景音乐管理类:BKMusic
该类负责背景音乐的实际播放控制,采用单例模式确保全局唯一的音乐管理实例。
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BKMusic : MonoBehaviour
{
private static BKMusic instance;
public static BKMusic Instance => instance;
private AudioSource audioSource;
// Start is called before the first frame update
void Awake()
{
instance = this;
// 得到自己依附的游戏对象上挂载的音频源脚本
audioSource = this.GetComponent<AudioSource>();
// 初始化时根据数据设置音量和开关状态
ChangeValue(GameDataMgr.Instance.musicData.bkValue);
ChangeOpen(GameDataMgr.Instance.musicData.isOpenBK);
}
/// <summary>
/// 改变背景音乐大小
/// </summary>
/// <param name="value"></param>
public void ChangeValue(float value)
{
audioSource.volume = value;
}
/// <summary>
/// 开关背景音乐
/// </summary>
/// <param name="isOpen"></param>
public void ChangeOpen(bool isOpen)
{
// 如果开启就是不静音,关闭则静音
audioSource.mute = !isOpen;
}
}
2.核心功能说明
(1)单例模式实现 :通过静态Instance
属性提供全局访问点,确保音乐控制的唯一性
(2)音频源获取 :在Awake
方法中获取组件上的AudioSource
组件,用于实际的音频播放控制
(3)初始化配置 :启动时自动从GameDataMgr
读取保存的音乐配置,设置初始音量和开关状态
(4)控制接口:
ChangeValue
:调整背景音乐音量ChangeOpen
:控制背景音乐开关(通过静音状态实现)
3.游戏数据管理器更新:GameDataMgr
cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 游戏数据管理类(单例模式)
/// </summary>
public class GameDataMgr
{
......
// 背景音乐开关控制(新增实时控制逻辑)
public void OpenOrCloseBKMusic(bool isOpen)
{
musicData.isOpenBK = isOpen;
// 实时控制场景上的背景音乐开关
BKMusic.Instance.ChangeOpen(isOpen);
// 存储改变后的数据
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
......
// 背景音乐音量控制(新增实时控制逻辑)
public void ChangeBKValue(float value)
{
musicData.bkValue = value;
// 实时控制场景上的背景音乐大小
BKMusic.Instance.ChangeValue(value);
// 存储改变后的数据
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
......
}
4.核心更新说明
(1)背景音乐实时控制:
- 在
OpenOrCloseBKMusic
方法中新增BKMusic.Instance.ChangeOpen(isOpen)
调用,实现开关状态的实时生效 - 在
ChangeBKValue
方法中新增BKMusic.Instance.ChangeValue(value)
调用,实现音量的实时调整
(2)数据与播放同步:保持原有数据持久化逻辑,确保配置修改后既能立即生效,又能保存到本地
九、资源以及源代码
1.资源(切勿商用)
通过网盘分享的文件:资源.zip
链接: https://pan.baidu.com/s/1IOyXuw8z5YLATI9Bwwpn5Q?pwd=1111 提取码: 1111
--来自百度网盘超级会员v5的分享
2.源代码
因为只是UI且篇幅已经较长,所以项目以及源代码放在下篇(游戏场景篇)