👨💻个人主页 :@元宇宙-秩沅
👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!
👨💻 本文由 秩沅 原创
👨💻 收录于专栏:unityUI专题篇
⭐单例模式管理面板对象⭐
文章目录
🎶前言
🅰️
🎶(A)常用关键API
🎶(B)需求分析
🎶(C)逻辑封装------游戏音乐数据存储
😶🌫️:步骤实现
1.首先将音乐数据封装在类中,不采用单例模式
- 而后封装一个游戏数据类为单例模式:功能:利用Playerfabs进行数据存储音乐数据
3.读取存盘中的数据更新游戏数据
1.首先将音乐数据封装在类中,不采用单例模式
cpp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//---------------------------------------------------------------------------------------------------------------
//___________脚本名: 音乐相关数据存储类
//___________功能: 记录音乐相关的数据
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class MusicData
{
//记录音乐,音效的开关状态和拖动条
public bool musicSwitch;
public bool soundSwitch;
public float musicRoll;
public float soundRoll;
public bool isFirst;
}
2. 而后封装一个游戏数据类为单例模式:功能:利用Playerfabs进行数据存储音乐数据
cpp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//---------------------------------------------------------------------------------------------------------------
//___________脚本名: 游戏数据类
//___________功能: 记录游戏的数据并用PlayerFabs存储
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class GameData
{
static private GameData dataContorl = new GameData ();
static public GameData DataContorl => dataContorl ;
public MusicData musicData ;
private GameData()
{
musicData = new MusicData();
musicData = PlayerfabsClass.Chats.GetDataMess(typeof(MusicData), "Music") as MusicData ;
if ( !musicData.isFirst ) //如果是第一次进入游戏
{
musicData.musicSwitch = true;
musicData.soundSwitch = true;
musicData.musicRoll = 0.5f;
musicData.soundRoll = 0.5f;
PlayerfabsClass.Chats.SaveDataMess(musicData, "Music"); //设置为自定义的默认值后进行存储
}
}
}
3.读取存盘中的数据更新游戏数据
cpp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//---------------------------------------------------------------------------------------------------------------
//___________项目: ______________
//___________功能: 设置面板功能
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class SetPlane : BeginFather<SetPlane>
{
//将功能控件拖拽对应的成员变量中
public Button closeButt;
public Slider sliderMusic;
public Slider sliderSound;
public ToggleM toggleMusic;
public ToggleM toggleSound;
private float toggle1;
private float toggle2;
private void Start()
{
//按钮中事件的添加
closeButt.triggerEvent += () => {
this.gameObject.SetActive(false);
BeginPlane.SingleInstance.Show();
};
//滑条中事件的添加
sliderMusic.triggerEvent += (value) =>
{
};
sliderSound.triggerEvent += (value) =>
{
};
//多选框中事件的添加
toggleMusic.triggerEvent += (value) =>
{
};
toggleSound .triggerEvent += (value) =>
{
};
this.Hidden();
}
private void MusicDataUpdate()
{
MusicData data = GameData.DataContorl.musicData;
sliderMusic.NowValue = data.musicRoll;
sliderSound.NowValue = data.soundRoll;
toggleMusic.IsSwitch = data.musicSwitch;
toggleSound.IsSwitch = data.soundSwitch;
}
public override void Show()
{
base.Show(); //保留父类的封装逻辑
MusicDataUpdate();
}
}
实现音乐数据的同步更新------最终代码
目的: 将游戏游戏数据保存至硬盘,下次开启游戏实现数据同步
cpp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//---------------------------------------------------------------------------------------------------------------
//___________脚本名: 游戏数据类
//___________功能: 记录游戏的数据并用PlayerFabs存储
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class GameData
{
static private GameData dataContorl = new GameData ();
static public GameData DataContorl => dataContorl ;
public MusicData musicData ;
private GameData()
{
musicData = PlayerPrefsDataMgr.Instance.LoadData(typeof(MusicData), "Music") as MusicData ;
if ( !musicData.isFirst ) //如果是第一次进入游戏(表示注册表中第一次存该类型数据时)
{
musicData.isFirst = true;
musicData.musicSwitch = true;
musicData.soundSwitch = true;
musicData.musicRoll = 1f;
musicData.soundRoll = 1f;
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
}
//音乐开关数据的更新存储
public void ChangeMusicS( bool value)
{
musicData.musicSwitch = value;
PlayerPrefsDataMgr.Instance.SaveData(musicData,"Music");
}
//音效开关数据的更新存储
public void ChangeSoundS(bool value)
{
musicData.soundSwitch = value;
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
//音乐滑条数据的更新存储
public void ChangeMusicR(float value)
{
musicData.musicRoll = value;
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
//音效滑条数据的更新存储
public void ChangeSoundR(float value)
{
musicData.soundRoll = value;
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
}
cpp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//---------------------------------------------------------------------------------------------------------------
//___________项目: ______________
//___________功能: 设置面板功能
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class SetPlane : BeginFather<SetPlane>
{
//将功能控件拖拽对应的成员变量中
public Button closeButt;
public Slider sliderMusic;
public Slider sliderSound;
public ToggleM toggleMusic;
public ToggleM toggleSound;
private float toggle1;
private float toggle2;
private MusicData musicData;
private void Start()
{
//按钮中事件的添加
closeButt.triggerEvent += () => {
Hidden();
BeginPlane.SingleInstance.Show();
};
//多选框中事件的添加
toggleMusic.triggerEvent += (value) => GameData.DataContorl.ChangeMusicS(value);
toggleSound.triggerEvent += (value) => GameData.DataContorl.ChangeSoundS(value);
//滑条中事件的添加
sliderMusic.triggerEvent += (value) => GameData.DataContorl.ChangeMusicR(value);
sliderSound.triggerEvent += (value) => GameData.DataContorl.ChangeSoundR(value);
Hidden();
}
private void MusicDataUpdate() //将已存盘的数据读取后更新
{
MusicData data = GameData.DataContorl.musicData;
toggleMusic.IsSwitch = data.musicSwitch;
toggleSound.IsSwitch = data.soundSwitch;
sliderMusic.NowValue = data.musicRoll;
sliderSound.NowValue = data.soundRoll;
}
public override void Show()
{
base.Show(); //保留父类的封装逻辑
MusicDataUpdate(); //在展示时更新
}
}
cpp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
//-------------------------------------
//---------------------------------------------------------------------------------------------------------------
//___________项目: ______________
//___________功能: 开始面板类
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class BeginPlane : BeginFather<BeginPlane>
{
// 获取开始面板中的各个按钮控件
public Button but1;
public Button but2;
public Button but3;
public Button but4;
private void Start()
{
but1.triggerEvent += () => { SceneManager.LoadScene("Start"); }; //点击"开始游戏"
but2.triggerEvent += () => { Hidden(); SetPlane.SingleInstance.Show(); }; //点击"游戏设置"
but3.triggerEvent += () => { Application.Quit(); }; //点击"退出游戏"
but4.triggerEvent += () => { Hidden(); }; //点击"排行榜"
}
}
🎶(D)逻辑封装------游戏排行榜数据存储
界面设计
- 效果演示:
😶🌫️:步骤实现
-
1.封装排行榜数据类(无参构造做new ,有参构造做一键赋值)
-
2.以数据管理类为载体进行更新API封装------只存储排行榜中的数据到盘(注册表)中
-
3.封装排行榜面板类进行实时显示
-----
封装排行榜数据类(无参构造做new ,有参构造做一键赋值)
cpp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//---------------------------------------------------------------------------------------------------------------
//___________项目:
//___________功能: 排行榜数据的载体
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class RankData
{
public string name;
public int score;
public int time;
public RankData() //用来new
{
}
public RankData(string name, int score, int time ) //用来一键赋值
{
this.name = name ;
this.score = score ;
this.time = time;
}
}
----------------------
以数据管理类为载体进行更新API封装
cpp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//---------------------------------------------------------------------------------------------------------------
//___________脚本名: 游戏数据管理类
//___________功能: 记录和更新游戏的数据并用PlayerFabs存储
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class GameData
{
static private GameData dataContorl = new GameData ();
static public GameData DataContorl => dataContorl ;
public MusicData musicData ;
public List<RankData> rankTopData;//固定承载前六名的数据信息
private GameData()
{
//初始化读取音乐数据
musicData = PlayerPrefsDataMgr.Instance.LoadData(typeof(MusicData), "Music") as MusicData ;
//初始化读取排行榜数据
rankTopData = PlayerPrefsDataMgr.Instance.LoadData(typeof(List<RankData>), "Rank") as List<RankData>;
if ( !musicData.isFirst ) //如果是第一次进入游戏(表示注册表中第一次存该类型数据时)
{
musicData.isFirst = true;
musicData.musicSwitch = true;
musicData.soundSwitch = true;
musicData.musicRoll = 1f;
musicData.soundRoll = 1f;
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
}
//------------------------排行榜数据的更新封装-------------------------------
//在排行榜中添加数据
public void SaveRankData(string name, int score, int time)
{
rankTopData.Add(new RankData(name, score, time));
Debug.Log(rankTopData);
rankTopData.Sort((a, b) => { return a.score > b.score ? -1 : 1; }); //添加排序规则
//但list大于6时
for (int i = rankTopData.Count - 1 ; i > 5; i--)
{
rankTopData.RemoveAt(i); //删除
}
PlayerPrefsDataMgr.Instance.SaveData(rankTopData, "Rank" );
}
//------------------------音乐数据的更新封装------------------------------
//音乐开关数据的更新存储
public void ChangeMusicS( bool value)
{
musicData.musicSwitch = value;
PlayerPrefsDataMgr.Instance.SaveData(musicData,"Music");
}
//音效开关数据的更新存储
public void ChangeSoundS(bool value)
{
musicData.soundSwitch = value;
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
//音乐滑条数据的更新存储
public void ChangeMusicR(float value)
{
musicData.musicRoll = value;
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
//音效滑条数据的更新存储
public void ChangeSoundR(float value)
{
musicData.soundRoll = value;
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
}
-----------
3.封装排行榜面板类进行实时显示
cpp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//---------------------------------------------------------------------------------------------------------------
//___________脚本名: 排行榜面板
//___________功能: 掌控排行榜面板相关控件
//___________创建者: 秩沅_______________
//_____________________________________
//-------------------------------------
public class RankPlane : BeginFather<RankPlane >
{
public Button closeButton;
//采用列表的方式进行排行数据的暂时存储
private List<Label> RK_Name = new List<Label>();
private List<Label> RK_Score = new List<Label>();
private List<Label> RK_Time = new List<Label>();
private void Start()
{
//通过API获取排行榜中的标签
for (int i = 1; i <= 6; i++)
{
RK_Name.Add(this.transform.Find("RKName/player" + i ).GetComponent<Label>());
RK_Score.Add(this.transform.Find("RKScore/Score" + i ).GetComponent<Label>());
RK_Time.Add(this.transform.Find("RKTime/time" + i ).GetComponent<Label>());
}
//为按钮中的事件添加方法
closeButton .triggerEvent += ()=>{
Hidden(); BeginPlane.SingleInstance.Show();
};
Hidden();
}
public override void Show()
{
base.Show();
ShowRankData();
}
public void ShowRankData() //读盘排行榜数据并显示
{
GameData.DataContorl .SaveRankData("nibb", 100, 342);
List<RankData> data = GameData.DataContorl.rankTopData;
for (int i = 0; i < data.Count; i++)
{
string showTime = "";
int hour, min, second;
print(data[i].name);
RK_Name[i].ContorlContent.text = data[i].name;
RK_Score[i].ContorlContent.text = data[i].score.ToString();
RK_Time[i].ContorlContent.text = "";
//时间格式转化
hour = data[i].time / 3600;
min = data[i].time / 60 % 60;
second = data[i].time % 60;
showTime = $"{hour}小时{min}分钟{second}秒";
RK_Time[i].ContorlContent.text = showTime;
}
}
}
总UML图
🎶(E)逻辑封装------音乐数据管理类
😶🌫️步骤:
- 1.封装音乐数据管理类------单例
- 2.在游戏数据管理类中,更新音乐数据更新方法
封装音乐数据类
cpp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//---------------------------------------------------------------------------------------------------------------
//___________项目: ______________
//___________功能: 更新音乐
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class MusicContol : MonoBehaviour
{
static private MusicContol singleMusicContol;
static public MusicContol SingleMusicContol => singleMusicContol;
private AudioSource beginAudio;
private MusicData nowMusicData;
void Awake()
{
singleMusicContol = this;
//达到一运行游戏就有音乐的效果
beginAudio = GetComponent<AudioSource>();
//从盘中读取
nowMusicData = PlayerPrefsDataMgr.Instance.LoadData(typeof(MusicData), "Music") as MusicData;
beginAudio.enabled = nowMusicData.musicSwitch;
beginAudio.volume = nowMusicData.musicRoll;
}
//----将其变成外界可调用的方法------
public void ChangeMusicSwitch(bool value) //改变音乐开关
{
beginAudio.enabled = value;
}
public void ChangeMusicRoll(float value) //改变音乐大小
{
beginAudio.volume = value;
}
public void ChangeSoundSwitch(bool value) //改变音效开关
{
}
public void ChangeSoundRoll(float value) //改变音效大小
{
}
}
游戏数据管理类,也需要更新------在方法中更新逻辑
cpp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//---------------------------------------------------------------------------------------------------------------
//___________脚本名: 游戏数据管理类
//___________功能: 记录和更新游戏的数据并用PlayerFabs存储
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class GameData
{
static private GameData dataContorl = new GameData ();
static public GameData DataContorl => dataContorl ;
public MusicData musicData ;
public List<RankData> rankTopData;//固定承载前六名的数据信息
private GameData()
{
//初始化读取音乐数据
musicData = PlayerPrefsDataMgr.Instance.LoadData(typeof(MusicData), "Music") as MusicData ;
//初始化读取排行榜数据
rankTopData = PlayerPrefsDataMgr.Instance.LoadData(typeof(List<RankData>), "Rank") as List<RankData>;
if ( !musicData.isFirst ) //如果是第一次进入游戏(表示注册表中第一次存该类型数据时)
{
musicData.isFirst = true;
musicData.musicSwitch = true;
musicData.soundSwitch = true;
musicData.musicRoll = 1f;
musicData.soundRoll = 1f;
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
}
//【------------------------排行榜数据的更新封装----------------------------------】
//在排行榜中添加数据
public void SaveRankData(string name, int score, int time)
{
rankTopData.Add(new RankData(name, score, time));
Debug.Log(rankTopData);
rankTopData.Sort((a, b) => { return a.score > b.score ? -1 : 1; }); //添加排序规则
//但list大于6时
for (int i = rankTopData.Count - 1 ; i > 5; i--)
{
rankTopData.RemoveAt(i); //删除
}
PlayerPrefsDataMgr.Instance.SaveData(rankTopData, "Rank" );
}
//【------------------------音乐数据的更新(存盘)封装----------------------------------】
//音乐开关数据的更新存储
public void ChangeMusicS( bool value)
{
musicData.musicSwitch = value;
MusicContol.SingleMusicContol.ChangeMusicSwitch(value); //实时改变音乐大小_下同
PlayerPrefsDataMgr.Instance.SaveData(musicData,"Music"); //实时进行音乐数据存盘_下同
}
//音效开关数据的更新存储
public void ChangeSoundS(bool value)
{
musicData.soundSwitch = value;
MusicContol.SingleMusicContol.ChangeSoundSwitch(value);
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
//音乐滑条数据的更新存储
public void ChangeMusicR(float value)
{
musicData.musicRoll = value;
MusicContol.SingleMusicContol.ChangeMusicRoll(value);
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
//音效滑条数据的更新存储
public void ChangeSoundR(float value)
{
musicData.soundRoll = value;
MusicContol.SingleMusicContol.ChangeSoundRoll(value);
PlayerPrefsDataMgr.Instance.SaveData(musicData, "Music");
}
}
过程中的错误------优化思维
进行优化__________==>
结论:
👌结论:
- 1.进行模块化处理,数据管理就是数据管理,面板显示就是面板显示,各司其职,员工不得乱工作
- 2.抽象行为,分配行为,你就是掌控者
- 3.如果某个行为/操作,不仅限于一个对象,要将其封装成外界可以调用的API
(例如修改主界面音频时,自己直接获取,却没想到将其封装成外界调用的方法)
⭐相关文章⭐
⭐【2023unity游戏制作-mango的冒险】-6.关卡设计
⭐【2023unity游戏制作-mango的冒险】-5.攻击系统的简单实现
⭐【2023unity游戏制作-mango的冒险】-4.场景二的镜头和法球特效跟随
⭐【2023unity游戏制作-mango的冒险】-3.基础动作和动画API实现
⭐【2023unity游戏制作-mango的冒险】-2.始画面API制作
⭐【2023unity游戏制作-mango的冒险】-1.场景搭建
⭐本站最全-unity常用API大全(万字详解),不信你不收藏
你们的点赞👍 收藏⭐ 留言📝 关注✅是我持续创作,输出优质内容的最大动力!