第八章 游戏中的数据(Data in Game)
在之前的章节中,我们进行地图对象的生成,移动等操作。
这一章本来可以进行战斗的编写,不过数据缺失是一个问题。
所以这一章我们先来建立一些数据,以及如何编辑它们,是否需要生成配置文件等。
二 创建数据(Create Data)
这一节,我们主要来简单的创建一些必要的数据,这些数据为数据编辑器做准备。这些数据并不完整,在之后制作游戏中也会一直进行添加。
这些数据存储在文件中,所以要选择文件的对应类型。 这里我将台词类的文本专门放入一个txt
文件中(这样的好处是容易进行大范围修改),其它需要读取的数据采用xml
类型。其它类型也是类似的。
1 Xml文件基类(BaseXmlConfig.cs)
对于xml
文件,我们用于人物信息,职业信息或物品信息等类型数据的存储。读取数据时需要一个key
值来确保唯一性。它们的功能都包括:
-
存储每一条信息;
-
能够读取每一条信息;
基于以上,我们在存储数据时可以使用一个字典。为了能够获得数据的key
值,我们来建立一个接口。
namespace DR.Book.SRPG_Dev.Models
{
public interface IConfigData<TKey>
{
TKey GetKey();
}
}
这样我们每一条的信息都继承接口IConfigData<TKey>
来实现。
之后我们来建立主类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using UnityEngine;
namespace DR.Book.SRPG_Dev.Models
{
using DR.Book.SRPG_Dev.Framework;
[Serializable]
public abstract class BaseXmlConfig<TKey, TData> : XmlConfigFile
where TData : class, IConfigData<TKey>
{
// TODO
}
}
除了之前说的需要字典外,我们最好能够序列化它,它包含的功能:
-
能够被序列化;
-
一个字典用于存储与读取数据;
基于以上,填充属性:
/// <summary>
/// 能够序列化的数据
/// </summary>
[XmlArray, XmlArrayItem]
public TData[] datas;
/// <summary>
/// 读取后存储的数据
/// </summary>
private Dictionary<TKey, TData> m_DataDict = new Dictionary<TKey, TData>();
/// <summary>
/// 键值读取数据
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
[XmlIgnore]
public TData this[TKey key]
{
get
{
TData data;
if (!m_DataDict.TryGetValue(key, out data))
{
Debug.LogErrorFormat("{0} -> Key `{1}` was not found.", GetType().Name, key);
return null;
}
return data;
}
}
你会看到,我将字典与序列化的数据分开了,你也可以不这么做。直接使用数组也可以。或者,你也可以继承IXmlSerializable
直接对字典进行序列化与反序列化。
直接使用数组:
[XmlArray, XmlArrayItem] public TData[] datas; public TData this[TKey key] { get { TData data = Array.Find(datas, d => d.GetKey().Equals(key)); if (data == null) { Debug.LogErrorFormat("{0} -> Key `{1}` was not found.", GetType().Name, key); } return data; } }
最后,我们需要重写一些方法, 其中文件名称和类名保持一致,读取方式采用WWW
:
/// <summary>
/// 文件信息构造
/// </summary>
/// <param name="info"></param>
protected override void ConstructInfo(ref Info info)
{
base.ConstructInfo(ref info);
info.name = GetType().Name + ".xml";
info.loadType = LoadType.WWW;
}
/// <summary>
/// 格式化数据
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
protected override XmlConfigFile FormatBuffer(XmlConfigFile buffer)
{
// 如果直接使用数组或字典序列化,可以直接返回buffer
// return buffer;
BaseXmlConfig<TKey, TData> config = buffer as BaseXmlConfig<TKey, TData>;
foreach (TData data in config.datas)
{
if (m_DataDict.ContainsKey(data.GetKey()))
{
Debug.LogWarningFormat("{0} -> Key `{1}` is exist. PASS.", GetType().Name, data.GetKey());
continue;
}
m_DataDict.Add(data.GetKey(), data);
}
return this;
}
2 修改移动消耗信息类(Modify Move Consumption Info)
我们已经有了xml
的基类,这里要做的工作:
-
让
MoveConsumptionInfo
继承IConfigData
,将ClassType
作为key
;