[英]C#: How can I rewrite my code for managing Game Data Serialization using an Array instead of a List in Unity?
我是編碼的新手,目前正在創建腳本以將數據序列化到硬盤。 我設法使其與類型為“游戲”的列表一起使用。 Game類保存可以序列化的數據。 我一直在嘗試編寫此代碼以使用大小為3的數組來代替。不幸的是,在運行程序並嘗試使用GUI時遇到了麻煩。 我只需要在正確的方向上推動如何重寫我的代碼。 我知道從開始:
public static Game[] savedGames = new Game[3];
但是,如何使用數組而不是列表來使用定義。
//<SaveLoad.cs>
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System;
public static class SaveLoad {
// Note: [ 07 / 20 / 2018]
// 1. Make an array of game saves index of 3. (To replace list)
// 2. Create definition for overwritesave()??
// 3. Rewrite definitions Save/Load/Delete to work with an array
// 4. Start working on custom GUI
public static List<Game> savedGames = new List<Game>(3);
public static void Save()
{
savedGames.Add(Game.current);
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(Application.persistentDataPath +
"/savedGames.gd");
Debug.Log("The file is saved at " + Application.persistentDataPath);
bf.Serialize(file, savedGames);
file.Close();
}
public static void Load()
{
if (File.Exists(Application.persistentDataPath + "/savedGames.gd"))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath +
"/savedGames.gd", FileMode.Open);
Debug.Log("The File is loaded from " +
Application.persistentDataPath);
savedGames = (List<Game>)bf.Deserialize(file);
file.Close();
}
}
public static void DeleteSave(int index) {
if (File.Exists(Application.persistentDataPath + "/savedGames.gd"))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath +
"/savedGames.gd", FileMode.Open);
savedGames = (List<Game>)bf.Deserialize(file);
file.Close();
}
savedGames.RemoveAt(index);
// Removes element in List from the passed Index
BinaryFormatter bf2 = new BinaryFormatter();
FileStream file2 = File.Create(Application.persistentDataPath +
"/savedGames.gd"); //you can call it anything you want
Debug.Log("Save file has been Updated at " +
Application.persistentDataPath);
bf2.Serialize(file2, savedGames); // Saves Changes to Data
file2.Close();
}
}
這是我的GUI腳本。 我目前在列表中使用它,但是在將其與數組一起使用時也遇到了麻煩。 我需要幫助,找到一種從菜單傳遞索引值來修改數組的方法。
//<MainMenu.cs>
using UnityEngine;
using System;
using UnityEngine.SceneManagement;
public class MainMenu : MonoBehaviour {
int index = 0;
public enum Menu {
MainMenu,
NewGame,
Continue,
delete,
caution
}
public Menu currentMenu;
void OnGUI () {
GUILayout.BeginArea(new Rect(0,0,Screen.width, Screen.height));
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.BeginVertical();
GUILayout.FlexibleSpace();
if(currentMenu == Menu.MainMenu) {
GUILayout.Box("THE EIGHT");
GUILayout.Space(10);
if(GUILayout.Button("New Game")) {
Game.current = new Game();
currentMenu = Menu.NewGame;
}
if(GUILayout.Button("Continue")) {
SaveLoad.Load();
currentMenu = Menu.Continue;
}
if(GUILayout.Button("Delete Save")) {
SaveLoad.Load();
currentMenu = Menu.delete;
}
if(GUILayout.Button("Quit")) {
Application.Quit();
}
}
else if (currentMenu == Menu.NewGame) {
GUILayout.Box("Name Your Characters");
GUILayout.Space(10);
GUILayout.Label("Some Strange Boy");
Game.current.Nestor.name =
GUILayout.TextField(Game.current.Nestor.name, 20);
GUILayout.Label("Some Strange Girl");
Game.current.SomeGirl.name =
GUILayout.TextField(Game.current.SomeGirl.name, 20);
GUILayout.Label("Some Strange Friend");
Game.current.SomeBro.name =
GUILayout.TextField(Game.current.SomeBro.name, 20);
if(GUILayout.Button("Save")) {
//Save the current Game as a new saved Game
SaveLoad.Save();
//Move on to game...
SceneManager.LoadScene(2);
}
GUILayout.Space(10);
if(GUILayout.Button("Cancel")) {
currentMenu = Menu.MainMenu;
}
}
else if (currentMenu == Menu.Continue) {
GUILayout.Box("Select Save");
GUILayout.Space(10);
foreach(Game g in SaveLoad.savedGames) {
if(GUILayout.Button(g.Nestor.name + " - " + g.SomeGirl.name + " - " + g.SomeBro.name)) {
Game.current = g;
//Move on to game...
SceneManager.LoadScene(2);
}
}
GUILayout.Space(10);
if(GUILayout.Button("Cancel")) {
currentMenu = Menu.MainMenu;
}
}
else if (currentMenu == Menu.delete)
{
GUILayout.Box("Select Save to Delete");
GUILayout.Space(10);
foreach (Game g in SaveLoad.savedGames)
{
if (GUILayout.Button(g.Nestor.name + " - " + g.SomeGirl.name + "
- " + g.SomeBro.name))
{
index = SaveLoad.savedGames.IndexOf(g);
Debug.Log(index);
currentMenu = Menu.caution;
}
}
GUILayout.Space(10);
if (GUILayout.Button("Cancel"))
{
currentMenu = Menu.MainMenu;
}
}
else if(currentMenu == Menu.caution) {
GUILayout.Box("Are you sure?");
GUILayout.Space(10);
if (GUILayout.Button("Yes")) {
Debug.Log(index);
SaveLoad.DeleteSave(index);
currentMenu = Menu.MainMenu;
}
GUILayout.Space(10);
if (GUILayout.Button("No")) {
currentMenu = Menu.delete;
}
}
GUILayout.FlexibleSpace();
GUILayout.EndVertical();
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.EndArea();
}
}
您幾乎只需要將List<Game>
演員List<Game>
替換為Game[]
。 這是一些(未處理錯誤)示例代碼基礎結構,可幫助您入門。 提示一下,將文件/序列化代碼包裝在try
,使用IOException
和SerializationException
catch
應該可以避免普通用戶案例場景的沖擊。 可能只想弄清楚.bin
文件,看看會發生什么並測試代碼的各種特殊情況,這是值得的。
void Awake() {
//this is an object initializer, pass your Game[] in place of this
Save(new[] {
new Game { propertyStub = 0 },
new Game { propertyStub = 1 },
new Game { propertyStub = 2 }
});
var gA = Load();
if(gA == null || gA.Length > 3) throw new SerializationException("Serialize error");
foreach (var g in gA) Debug.Log(g);
}
public static void Save(Game[] gA) {
using (var f = File.Create(Directory.GetCurrentDirectory() + "\\sample.bin")) new BinaryFormatter().Serialize(f, gA);
}
public static Game[] Load() {
using (var f = File.Open(Directory.GetCurrentDirectory() + "\\sample.bin", FileMode.Open)) return (new BinaryFormatter().Deserialize(f)) as Game[];
}
//Stub class used for testing purposes
[Serializable]
class Game {
public int propertyStub { get; set; }
public override string ToString() {
return "propertyStub value: " + propertyStub;
}
}
另外,值得一提的是, .net Binary序列化程序在一般情況下與其他常見序列化方法相比非常慢 ,因此,建議不要在最終版本中使用它。 其他眾所周知的序列化方法(如XML和JSON)會生成易於閱讀的輸出,並且在您不關心最終文件大小或序列化速度時也能很好地工作。 如果您確實想要速度和大小,則Google協議緩沖區(Protobuf)是一個很好的起點。
我給您的所有鏈接都包含樣板代碼復制和粘貼代碼,盡管它們最終都會序列化動態數組列表。 就像我在上面說的,簡單地將顯式強制轉換為數組不會引起任何麻煩。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.