我在Unity中使用序列化有问题(使用C#)。
我有以下类(箭头表示继承):
Vehicle
(摘要)< - Car
(摘要)< - Sedan
和
Vehicle
(摘要)< - MotorBike
车辆类继承自MonoBehavior
。
我有一些游戏对象(预制件),我将其归类于。我只使用非抽象类(即MotorBike
和Sedan
)。
我的问题是:
我想序列化这些类中存储的数据,以便能够保存/加载。 (我为此使用BinaryFormatter
。)问题是,MonoBehavior
不可序列化。
我想要的是序列化车辆类中的数据,并且(在加载数据时)将其传递给我的Vehicle Factory类,以使用反序列化的数据重新实例化预制件。所以,我对MonoBehavior部分中存储的内容并不感兴趣。
到目前为止我尝试过的事情:
使用单独的Data类,但这会导致各种problems,我需要为每个Vehicle类创建一个子数据类。我需要使Vehicle类Generic,以指示它需要使用哪个Data类,这将要求我在每个使用Vehicle类型的地方使用Generic Type。
此外,我尝试为MonoBehaviour制作一个SerializationSurrogate,但这并没有成功,因为还有许多其他类型需要代理。由于我对MonoBehaviour并不感兴趣,只是在车辆类和它的儿童课程中,这似乎太复杂了,无法尝试。
所以,我的问题是:有人知道处理这个问题的方法吗?
答案 0 :(得分:3)
我总是很难找到继承类中的保存数据。您的数据类不应继承或派生自任何东西。另一个班级里面的班级完全没问题。这里的目标是为每辆车提供两个班级。一个派生自MonoBehaviour
(对象),另一个派生不(数据)。
您可以使用对象类对车辆执行操作,例如移动,碰撞决策等。您可以使用数据类来存储有关每辆车/车辆的信息。
以下示例使用Sedan来演示我的意思:
将SedanObject.cs
附加到Sedan Prefab。
class SedanObject : MonoBehaviour
{
float fuel;
public void setFuel(float fuel)
{
this.fuel = fuel;
}
public float getFuel(float fuel)
{
return this.fuel;
}
void Start()
{
}
void Update()
{
}
}
Sedan的数据类:
[Serializable]
public class MotorBike
{
}
[Serializable]
public class Sedan
{
public float fuel;
}
[Serializable]
public class Cars
{
public List<Sedan> sedan;
public Cars()
{
sedan = new List<Sedan>();
}
}
[Serializable]
public class Vehicles
{
public Cars cars;
public MotorBike motorBike;
public Vehicles()
{
cars = new Cars();
motorBike = new MotorBike();
}
}
在游戏结束时,保存车辆设置。车辆内的每个课程/脚本都将被保存。
//Save on Exit
Vehicles vehicles = new Vehicles();
string vehicleJson = JsonUtility.ToJson(vehicles);
PlayerPrefs.SetString("vehicles", vehicleJson);
PlayerPrefs.Save();
当游戏开始时,从磁盘加载车辆信息,然后根据列表中的轿车数量实例化Sedan Prefab。
//Load on Startup
string loadVehicleJson = PlayerPrefs.GetString("vehicles");
Vehicles loadVehicles;
loadVehicles = JsonUtility.FromJson<Vehicles>(loadVehicleJson);
//Process and instantiate sedan based on the loaded data amount/count
for (int i = 0; i < vehicles.cars.sedan.Count; i++)
{
GameObject tempObjt = Instantiate(sedanPrefab);
SedanObject sd = tempObjt.GetComponent<SedanObject>();
//Send loaded settings to each vehicle script
sd.setFuel(vehicles.cars.sedan[i].fuel);
}
如果你想稍后添加更多的Sedans:
//Create 3 Sedans
vehicles.cars.sedan.Add(new Sedan());
vehicles.cars.sedan.Add(new Sedan());
vehicles.cars.sedan.Add(new Sedan());
这只是一个基本的解决方案,可以扩展。您可以在for循环期间将每个轿车数据脚本的实例传递给SedanObject
,就像我将加载的燃料传递给每个实例一样。通过传递每个实例,可以在运行时从SedanObject
脚本的每个实例修改数据脚本中的信息。这也可以通过xml来完成。