在Adventure Creator中保存场景对象的状态只需将正确的“Remember”脚本附加到其中即可。Adventure Creator提供了几个这样的脚本,每个脚本都保存不同类型的场景数据。例如,将RememberHotspot脚本附加到任何Hotspot将保存该热点的打开/关闭状态,以及其中每个Interaction的状态。

然而,在更复杂的游戏中,可能需要保存比标准Remember脚本允许的更多数据。幸运的是,可以编写可以附加到场景对象的自定义脚本来保存您想要的任何内容。

这将是一个相当复杂的教程,需要对脚本实践有很好的了解。在其中,我们将编写一个新的Remember脚本,用于保存附加到的任何灯光组件的打开/关闭状态。

创建一个名为RememberLight的新C#脚本。使用AC namespace,并从Remember派生类。它还需要Light 组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
using UnityEngine;
using System.Collections;

namespace AC
{

[RequireComponent (typeof (Light))]
public class RememberLight : Remember
{

}

}

这是一个MonoBehaviour脚本,这意味着它可以附加到GameObjects。然而,我们必须将数据本身存储在单独的类中。在RememberLight类下,创建一个名为LightData的新类,从RemembertData派生它,并将其赋予System.Serializable特性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using UnityEngine;
using System.Collections;

namespace AC
{

[RequireComponent (typeof (Light))]
public class RememberLight : Remember
{

}

[System.Serializable]
public class LightData : RememberData
{

}

}

LightData类只需要一个变量:一个名为isOn的布尔值,它由附加的Light组件的启用状态控制。也给它一个默认构造函数:

1
2
3
4
5
6
[System.Serializable]
public class LightData : RememberData
{
public bool isOn;
public LightData () {}
}

我们现在只需要向RememberLight类添加两个override函数。第一个是SaveData,它返回一个字符串:

1
2
3
4
5
6
7
8
9
[RequireComponent (typeof (Light))]
public class RememberLight : Remember
{

public override string SaveData ()
{
}

}

此函数将基于附加的Light组件创建LightData的新实例:

1
2
3
4
5
public override string SaveData ()
{
LightData lightData = new LightData ();
lightData.isOn = GetComponent <Light>().enabled;
}

LightData派生自RememberData,它有一个名为objectID的整数变量。这必须设置为constantID的值,它是Remember中的一个整数变量,RememberLight从中派生:

1
2
3
4
5
6
public override string SaveData ()
{
LightData lightData = new LightData ();
lightData.isOn = GetComponent <Light>().enabled;
lightData.objectID = constantID;
}

也就是说添加RememberLight脚本后,AC会自动赋予当前脚本对象一个Constant ID,这个ID会一并保存。

这是因为脚本也是Assets资产,能在各个Scene当中复用,使用Constant ID就能快速定位当前场景的物体应该用哪个存档文件。

可以使用Serializer.SaveScriptData函数将此数据自动转换为序列化字符串。。函数调用中必须使用数据的类名(在本例中为LightData):

1
2
3
4
5
6
7
8
public override string SaveData ()
{
LightData lightData = new LightData ();
lightData.isOn = GetComponent <Light>().enabled;
lightData.objectID = constantID;

return Serializer.SaveScriptData <LightData> (lightData);
}

我们必须添加的第二个覆盖函数是LoadData,它需要一个字符串:

1
2
public override void LoadData (string stringData)
{}

我们将使用Serializer.LoadScriptData反序列化字符串。并相应设置灯光组件的状态。注意:为了防止在同一个游戏对象上放置多个“Remember”脚本时可能出现的问题,我们还必须检查加载的数据是否存在:

1
2
3
4
5
6
public override void LoadData (string stringData)
{
LightData data = Serializer.LoadScriptData <LightData> (stringData);
if (data == null) return;
GetComponent <Light>().enabled = data.isOn;
}

我们完成的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using UnityEngine;
using System.Collections;

namespace AC
{

[RequireComponent (typeof (Light))]
public class RememberLight : Remember
{

public override string SaveData ()
{
LightData lightData = new LightData ();
lightData.isOn = GetComponent <Light>().enabled;
lightData.objectID = constantID;

return Serializer.SaveScriptData <LightData> (lightData);
}


public override void LoadData (string stringData)
{
LightData data = Serializer.LoadScriptData <LightData> (stringData);
if (data == null) return;
GetComponent <Light>().enabled = data.isOn;
}

}

[System.Serializable]
public class LightData : RememberData
{
public bool isOn;
public LightData () {}
}

}

RememberLight脚本现在可以添加到场景中的任何光源,它将自动保存并恢复其打开/关闭状态。

通过将LightSwitch脚本附加到光源上,并使用Object:Send message Action向其发送消息TurnOn和TurnOff,可以在游戏中更改光源的打开/关闭状态。

Remember Light脚本

该组件将自动提供UI来管理分配给它所附加的游戏对象的Constant ID号。但是,请注意,如果要向其中添加其他字段或控件,则需要编写自定义Inspector。

以下是RememberLight组件的示例编辑器脚本,允许插入其他字段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using UnityEditor;

namespace AC
{

[CustomEditor (typeof (RememberLight), true)]
public class RememberLightEditor : ConstantIDEditor
{

public override void OnInspectorGUI ()
{
RememberLight _target = (RememberLight) target;
// Custom fields here
SharedGUI ();
}

}

}