为了保存,我在状态类中创建了结构:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
[Serializable]
public class SaveState
{
public struct Position
{
public float x;
public float y;
public float z;
public void Fill(Vector3 v3)
{
x = v3.x;
y = v3.y;
z = v3.z;
}
public Vector3 V3 { get { return new Vector3(x, y, z); } set { Fill(value); } }
}
public struct Rotation
{
public float x;
public float y;
public float z;
public float w;
public void Fill(Quaternion Quat)
{
x = Quat.x;
y = Quat.y;
z = Quat.z;
w = Quat.w;
}
public Quaternion Qua { get { return new Quaternion(x, y, z, w); } set { Fill(value); } }
}
public struct Scale
{
public float x;
public float y;
public float z;
public float w;
public void Fill(Vector3 v3)
{
x = v3.x;
y = v3.y;
z = v3.z;
}
public Vector3 V3 { get { return new Vector3(x, y, z); } set { Fill(value); } }
}
public SaveState(Vector3 pos, Quaternion rot, Vector3 sca)
{
Position position = new Position();
position.V3 = pos;
Rotation qua = new Rotation();
qua.Qua = rot;
Scale scale = new Scale();
scale.V3 = sca;
}
}
然后在管理器脚本中:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System;
using System.IO;
public class SaveManager : MonoBehaviour
{
public static void Save(SaveState player)
{
BinaryFormatter formatter = new BinaryFormatter();
string path = Application.persistentDataPath + "/player.bin";
FileStream stream = new FileStream(path, FileMode.Create);
formatter.Serialize(stream, player);
stream.Close();
}
public static SaveState Load()
{
string path = Application.persistentDataPath + "/player.bin";
if (File.Exists(path))
{
BinaryFormatter formatter = new BinaryFormatter();
FileStream stream = new FileStream(path, FileMode.Open);
SaveState data = formatter.Deserialize(stream) as SaveState;
stream.Close();
return data;
}
else
{
Debug.LogError("Save file not found in " + path);
return null;
}
}
}
和测试脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SaveTest : MonoBehaviour
{
private void Update()
{
if(Input.GetKeyDown(KeyCode.T))
{
var player = GameObject.Find("Player");
SaveState saveState = new SaveState(player.transform.position, player.transform.rotation,player.transform.localScale);
SaveManager.Save(saveState);
}
if(Input.GetKeyDown(KeyCode.L))
{
var player = GameObject.Find("Player");
}
}
}
保存部分似乎还可以,但是我不确定加载部分。 我不确定Load函数的编写是否正确,也不确定如何在L键输入中使用它。
编辑:
更新后我的类和脚本:
保存状态:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
[Serializable]
public class SaveState
{
public struct SerializableVector3
{
public float X;
public float Y;
public float Z;
public SerializableVector3(Vector3 v)
{
X = v.x;
Y = v.y;
Z = v.z;
}
// And now some magic
public static implicit operator SerializableVector3(Vector3 v)
{
return new SerializableVector3(v);
}
public static implicit operator Vector3(SerializableVector3 sv)
{
return new Vector3(sv.X, sv.Y, sv.Z);
}
}
public struct SerializableQuaternion
{
public float X;
public float Y;
public float Z;
public float W;
public SerializableQuaternion(Quaternion q)
{
X = q.x;
Y = q.y;
Z = q.z;
W = q.w;
}
public static implicit operator SerializableQuaternion(Quaternion q)
{
return new SerializableQuaternion(q);
}
public static implicit operator Quaternion(SerializableQuaternion sq)
{
return new Quaternion(sq.X, sq.Y, sq.Z, sq.W);
}
}
public SerializableVector3 position;
public SerializableQuaternion rotation;
public SerializableVector3 scale;
public SaveState(Vector3 pos, Quaternion rot, Vector3 sca)
{
position = pos;
rotation = rot;
scale = sca;
}
public void ApplyToPlayer(Transform player)
{
player.position = position;
player.rotation = rotation;
player.localScale = scale;
}
}
经理:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System;
using System.IO;
public class SaveManager : MonoBehaviour
{
public static void Save(SaveState player)
{
BinaryFormatter formatter = new BinaryFormatter();
string path = Application.persistentDataPath + "/player.bin";
FileStream stream = new FileStream(path, FileMode.Create);
formatter.Serialize(stream, player);
stream.Close();
}
public static SaveState Load()
{
string path = Application.persistentDataPath + "/player.bin";
if (File.Exists(path))
{
BinaryFormatter formatter = new BinaryFormatter();
FileStream stream = new FileStream(path, FileMode.Open);
SaveState data = formatter.Deserialize(stream) as SaveState;
stream.Close();
return data;
}
else
{
Debug.LogError("Save file not found in " + path);
return null;
}
}
}
测试脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SaveTest : MonoBehaviour
{
private void Update()
{
if (Input.GetKeyDown(KeyCode.T))
{
var player = GameObject.Find("Player");
SaveState saveState = new SaveState(player.transform.position, player.transform.rotation, player.transform.localScale);
SaveManager.Save(saveState);
}
if (Input.GetKeyDown(KeyCode.L))
{
var player = GameObject.Find("Player");
var playerInfo = SaveManager.Load();
playerInfo.ApplyToPlayer(player.transform);
}
}
}
答案 0 :(得分:1)
Load()
似乎还可以。
通过这种方式,您还可以使用FileStream stream = File.Open(path, FileMode.Open);
使用它没什么特别的,只是:SaveState save = SaveManager.Load();
答案 1 :(得分:1)
您当前在班级中没有任何字段!
仅类型定义。您将需要一些类似的东西
public Position position;
public Rotation rotation;
public Scale scale;
您使用的只是局部方法变量,不会存储在任何地方!
然后在构造函数中分配这些
public SaveState(Vector3 pos, Quaternion rot, Vector3 sca)
{
// Since structs are never null
// you don't need to create new ones
position.V3 = pos;
rotation.Qua = rot;
scale.V3 = sca;
}
然后我通常会在您的类中寻找一种方法,例如
public void ApplyToPlayer(Transform player)
{
player.position = position.V3;
player.rotation = rotation.Qua;
player.localScale = scale.V3;
}
,然后在您的L
块中
var player = GameObject.Find("Player").transform;
var playerInfo = SaveManager.Load();
playerInfo.ApplyToPlayer(player);
最后一步:
对于您的结构,我什至建议编写implicit operator
转换作为一个示例:
[Serializable]
public struct SerializableVector3
{
public float X;
public float Y;
public float Z;
public SerializableVector3(Vector3 v)
{
X = v.x;
Y = v.y;
Z = v.z;
}
// And now some magic
public static implicit operator SerializableVector3 (Vector3 v)
{
return new SerializableVector3 (v);
}
public static implicit operator Vector3 (SerializableVector3 sv)
{
return new Vector3 (sv.X, sv.Y, sv.Z);
}
}
这使您现在可以像希望使用的那样简单地互换使用这两种类型
public SerializableVector3 position;
// This type is your homework
public SerializableQuaternion rotation;
public SerializableVector3 scale;
然后您可以直接将其分配为
player.position = someSaveStat.position;
还有
someSaveStat.position = player.position;
因此您可以将构造函数更改为例如
public SaveState(Vector3 pos, Quaternion rot, Vector3 sca)
{
position = pos;
rotation = rot;
scale = sca;
}
,应用方法将变为
public void ApplyToPlayer (Transform player)
{
player.position = position;
player.rotation = rotation;
player.localScale = scale;
}
注意:我在智能手机上键入内容,但我希望这个主意能弄清楚。