开学了开学了,虽然后期很浪,但总的来说过了一个收获颇多的暑假。这里讲一讲最后实现设置面板和存档读档的思路


设置面板

可以采用之前类神庙逃亡项目的思路来写:
在主Canvas上创建一个Panel,当作设置面板,先禁用
如何控制BGM音量和文字显示的快慢?很简单,创建一个SettingManager脚本来管理设置面板,先获取BGM的脚本和带显示文字协程的脚本(好吧,后面看来其实不用,因为我的所有脚本都写有一个供全局调用的实例)

//static:public static Setting_Controller Setting_Instance;//public:public GameObject BGM;public GameObject TextSpeed;// Use this for initializationprivate void Awake(){Setting_Instance = this;//initializeBGM = GameObject.Find("BGM_Source");TextSpeed = GameObject.Find("UI_Control");}

然后在Panel上创建两个Slider来控制,如图:

在SettingManager中写两个函数来修改对应参数,用滑动条来改变值即可:

 public void SetBGMVolume(){BGM.GetComponent<AudioSource>().volume = gameObject.GetComponent<Slider>().value; }public void SetTextSpeed(){UI_Manager.UIManager_Instance.SetTextSpeed(gameObject.GetComponent<Slider>().value);}// Update is called once per frame

存档&读档

比较严谨的可以用PlayerPrefeb或者JSON来处理,这里就说说最最简单的思路,用文件读写来实现。可以分析一下可以用什么来当储存的数据,之前定义过一个LineIndex变量,代表当前脚本的行数,刚好是我们需要的,就它了。然而这是肯定不够的,因为我们在游戏中储存的脚本行必然是一行对话脚本,当前的人物,背景,bgm是没有被储存的(它们是在之前的命令脚本被改变的)
于是,必须将所有信息先存起来,建立一个SaveData类:

 //public:public int LineIndex;public string BGMName;public string BackgroundImgName;public string LCharacter, MCharacter, RCharacter;public float BGMVolume;public float TextSpeed;//private://private Color compare_color;// Use this for initializationprivate void Awake(){LineIndex = TextParser.TextParser_Instance.LineIndex;BGMName = BGM_Management.BGM_Manager_Instance.Current_BGM;BackgroundImgName = UI_Manager.UIManager_Instance.Cor_bgname;//compare_color = new Color(1, 1, 1, 1);TextSpeed = UI_Manager.UIManager_Instance.Cor_DisplayingSpeed;BGMVolume = GameObject.Find("BGM_Source").GetComponent<AudioSource>().volume;}

在初始化时获取当前场景的bgm,背景,角色,以及设置界面。角色立绘储存还需要处理一下,把所有位置变为字符串储存起来

    public void GetCharacters(){LCharacter = TextParser.TextParser_Instance.CurrentCharas[0];MCharacter = TextParser.TextParser_Instance.CurrentCharas[1];RCharacter = TextParser.TextParser_Instance.CurrentCharas[2];}

这样需要储存的东西都到位了,创建一个SavingManager脚本来把数据写入文件中,把savedata类挂到一个空物体上,让SavingManager获取它,将数据打包存进一个string数组中:
初始化:

//publicpublic string DirectPath;public StreamWriter SW1;public SaveData CurrentData;public FileStream fs;// Use this for initializationvoid Start () {DirectPath = Application.streamingAssetsPath;}

packing&writing

public string[] PackingData(SaveData sd1){string[] DataArray = new string[8];DataArray[0] = sd1.LineIndex.ToString();DataArray[1] = sd1.BGMName;DataArray[2] = sd1.BackgroundImgName;DataArray[3] = sd1.LCharacter;DataArray[4] = sd1.MCharacter;DataArray[5] = sd1.RCharacter;DataArray[6] = sd1.BGMVolume.ToString();DataArray[7] = sd1.TextSpeed.ToString();return DataArray;}//public void WriteData(StreamWriter temp){string[] DataStream=PackingData(CurrentData);foreach(string str in DataStream){temp.WriteLine(str);temp.Flush();}temp.Close();}

这里用的StreamWriter来写入,有点麻瓜,毫无安全性可言(但很简单省时),需要先创建好几个存档槽位,然后通过点击slot的按钮来储存。用switch语句来判断是哪个槽位,写入,然后更新存档槽的图片就ok了

switch (gameObject.name){case "Slot_1":UpdateImage(gameObject);fs = new FileStream(DirectPath + "/Slot1.txt", FileMode.Create);SW1 = new StreamWriter(fs);WriteData(SW1);fs.Close();break;case "Slot_2":UpdateImage(gameObject);fs = new FileStream(DirectPath + "/Slot2.txt", FileMode.Create);SW1 = new StreamWriter(fs);WriteData(SW1);fs.Close();break;case "Slot_3":UpdateImage(gameObject);fs = new FileStream(DirectPath + "/Slot3.txt", FileMode.Create);SW1 = new StreamWriter(fs);fs.Close();WriteData(SW1);break;case "Slot_4":UpdateImage(gameObject);fs = new FileStream(DirectPath + "/Slot4.txt", FileMode.Create);SW1 = new StreamWriter(fs);fs.Close();WriteData(SW1);break;default:break;}public void UpdateImage(GameObject gb1){CurrentData = GameObject.Find("SaveDataObject").GetComponent<SaveData>();gb1.GetComponent<Image>().sprite = (Sprite)Resources.Load("Background/" + CurrentData.BackgroundImgName, typeof(Sprite));}


然后是读档,存档和读档用的是一个面板,所以写一个状态量,点击不同的按钮进入不同的(存档,读挡)状态,写一个协程,隔个零点几秒检测一次状态,直接上代码了:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum SLState {none,Saving,Loading}
public class State_Manager : MonoBehaviour {public static SLState SaveLoadState;public GameObject Manager_Save;public GameObject Manager_Load;// Use this for initializationprivate void Awake(){SaveLoadState = SLState.none;}void Start () {StartCoroutine("SaveStateCheck");}IEnumerator SaveStateCheck(){yield return new WaitForEndOfFrame();while(true){yield return new WaitForSeconds(0.2f);if(SaveLoadState==SLState.Saving){Manager_Save.SetActive(true);Manager_Load.SetActive(false);}else if(SaveLoadState==SLState.Loading){Manager_Save.SetActive(false);Manager_Load.SetActive(true);}else{Manager_Save.SetActive(false);Manager_Load.SetActive(false);}}}// Update is called once per framevoid Update () {//}
}

通过状态来指示当前储存面板点击槽位是储存还是读取,接着来写读档的LoadingManager脚本,很简单,把文件中的string按行读取,再改变对应UI即可,定义初始化:

public static Loading_Manager Loading_Manager_Instance;public string DirectPath;public string[] CurArray;// Use this for initializationvoid Start () {DirectPath = Application.streamingAssetsPath;Loading_Manager_Instance = this;}

然后是解析和改变UI的函数:

public void Slot_Clicked(){if (State_Manager.SaveLoadState == SLState.Loading){switch (gameObject.name){case "Slot_1":CurArray = LoadData("Slot1.txt");SetUI();break;case "Slot_2":CurArray = LoadData("Slot2.txt");SetUI();break;case "Slot_3":CurArray = LoadData("Slot3.txt");SetUI();break;case "Slot_4":CurArray = LoadData("Slot4.txt");SetUI();break;default:break;}}}public string[] LoadData(string filename){string path = DirectPath + "/" + filename;Debug.Log("readfile:" + path);string[] AllText = File.ReadAllLines(path);//split by linesreturn AllText;}public void SetUI(){string[] pack = CurArray;TextParser.TextParser_Instance.LineIndex = int.Parse(pack[0]);BGM_Management.BGM_Manager_Instance.SetBGM(pack[1]);UI_Manager.UIManager_Instance.SetBackground(pack[2], 1f);UI_Manager.UIManager_Instance.CharacterDisplay("all", "off");if(pack[3]!="null"){UI_Manager.UIManager_Instance.SetCharacter(pack[3], "left");}if (pack[3] != "null"){UI_Manager.UIManager_Instance.SetCharacter(pack[3], "center");}if (pack[3] != "null"){UI_Manager.UIManager_Instance.SetCharacter(pack[3], "right");}Setting_Controller.Setting_Instance.SetBGMVolume();Setting_Controller.Setting_Instance.SetTextSpeed();}

之前的savingmanager也要加入状态的判断,这里就不写了。把ButtonManager更新一下,添加对应的按钮事件,基本完成了,可以运行看看效果

 case "Save_BTN":State_Manager.SaveLoadState = SLState.Saving;UI_Manager.UIManager_Instance.SavingPanel.SetActive(true);GameObject.Find("SaveDataObject").AddComponent<SaveData>();break;case "Load_BTN":State_Manager.SaveLoadState = SLState.Loading;UI_Manager.UIManager_Instance.SavingPanel.SetActive(true);break;case "Setting_BTN":UI_Manager.UIManager_Instance.SettingPanel.SetActive(true);UI_Manager.UIManager_Instance.InitSettingWindow();break;

基本就完成了,暂时就到这里吧,开学了,有时间再更新

我如何用Unity3D实现一个Galgame框架(存档读档与设置面板的思路)相关推荐

  1. 我如何用Unity3D实现一个Galgame框架(一)

    序 Galgame我很早就陆陆续续的接触过,但大都是别人推荐或名声很大.梗很多的,比如催泪的有clannad,狗血的有School Days,还有胃疼的白学.但自己对Galgame和AVG真正产生兴趣 ...

  2. [译] 如何用 Python 写一个 Discord 机器人

    原文地址:How to write a Discord bot in Python 原文作者:Junpei Shimotsu 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/go ...

  3. 如何用Phaser实现一个全家福拼图H5

    一.Phaser介绍 二.整体框架搭建 三.资源加载 四.游戏逻辑 五.完成 六.总结 参考文档 最近用Phaser做了一个全家福拼图h5的项目,这篇文章将会从零开始讲解如何用Phaser实现,最终效 ...

  4. 如何用java开发一个网站?

    问题:如何用java开发一个网站? 下载了最新的JDK软件.最新的Eclipse.数据库mysql以及tomcat.struts但是不知道怎么连接起来,在数据库连接的时候mysql-connector ...

  5. 如何用Python搭建一个36Kr网站|高手4步带你入门

    感谢关注天善智能,走好数据之路↑↑↑阅读本文大概需要3分钟 欢迎关注天善智能,我们是专注于商业智能BI,大数据,数据分析领域的垂直社区,学习,问答.求职一站式搞定! 天善学院618活动正在进行中!天善 ...

  6. unity+live2d制作galgame框架

    unity+live2d制作galgame框架 前置准备 分层 按钮和背景图 live2D模型控制 前置准备 安装unity[free版即可] unity下载 下载live2d for unity的s ...

  7. ❤️❌ 如何用vue制作一个探探滑动组件

    前言 嗨,说起探探想必各位程序汪都不陌生(毕竟妹子很多),能在上面丝滑的翻牌子,探探的的堆叠滑动组件起到了关键的作用,下面就来看看如何用vue写一个探探的堆叠组件 ? 一. 功能分析 简单使用下探探会 ...

  8. 如何用Java设计一个简单的窗口界面(学习中.1)

    如何用Java设计一个简单的窗口界面 一.前言 二.简单了解 1.Swing简介 2.框架(frame) 3.层次 三.步骤 1.打开eclipse,依次创建项目,包,类. 2.代码 2.1最简单的可 ...

  9. 如何用OKR搞垮一个团队?

    作者| Mr.K   整理| Emma 来源| 技术领导力(ID:jishulingdaoli) 这几天一大堆读者在后台留言催更: "老K又偷懒了,看了这么多天恰饭文,我都忍了!再不写干货, ...

  10. 如何用 css 画一个心形

    如何用 css 画一个心形 (How to draw hearts using CSS) 用两个长方形切圆角倾斜位移并合并为一个心形 第一步 画一个长方形 (Draw a rectangle) 这个长 ...

最新文章

  1. uboot源码分析笔记
  2. Duktape:一个新的小巧的超精简可嵌入式JavaScript引擎
  3. Guava Cache 1(脉络)
  4. 小白重装系统教程_重装解决99%的电脑问题:小白U盘重装系统教程
  5. 深度学习之迁移学习实现神奇宝贝识别
  6. 如何将rootfs打包进kernel image
  7. leetcode No.15-16 三数之和相关问题
  8. python在web可以开发吗_怎么用python进行web开发
  9. android studio后端写在哪里_c++写的在终端上的2048游戏
  10. 阿里java规范_阿里Java规范
  11. 【数据库】Hive SQL 正则表达式进阶二(regexp_extract函数进阶使用)
  12. Android 微信高性能日志存储库Xlog的使用
  13. 海定计算机计算标准差,方差 标准差
  14. word公式快捷键使用
  15. 【web前端(三十九)】javascript_jquery操作样式
  16. 2021年,这个岗位发展前景广,刚入行月薪上万?
  17. oneplus 驱动_450美元的旗舰旗舰产品OnePlus Nord动手实践
  18. win7下php 5.6连接mongodb扩展
  19. 用 OpenCV 检测图像中各物体大小
  20. luogu3959 宝藏

热门文章

  1. Linux小程序——彩色进度条
  2. Windows7高级检索功能——搜索筛选器
  3. 从0开始学大数据(十二)
  4. vue+elementUI 怎么上传图片至阿里云
  5. 如何批量打印dwf文件
  6. 极简桌面 android 2.3,低端 Android 备机的轻量级启动器:极简光速桌面
  7. 复制网站zencart模板的方法
  8. 【技巧】屏蔽百度搜索热点和相关软件推荐等(提高注意力)
  9. html style
  10. thrift文件服务器,Thrift功能和使用