[英]What's the best way to store a finite number of "stats"?
这可能是个愚蠢的问题。 但我相当确定必须有更好的方法来获取和设置有限数量的统计数据的值,以便它们可以轻松地显示在列表中。
所以我有一个游戏,我想显示“统计名称”+“统计值”的列表(或子列表),其中统计名称需要本地化,值可以是整数、浮点数或字符串。
所以这是我的代码示例。 在 C# 中(对于 Unity)
[Serializable]
public enum GameStatisticsEnum
{
TimesGameOpened,
TimePlayed,
TimeBattling,
VersusBattleCount,
VersusRoundCount,
SpellCastCount,
DeathCount,
}
[Serializable]
public class GameStatistics
{
[SerializeField] public int TimesGameOpened;
[SerializeField] public float TimePlayed;
[SerializeField] public float TimeBattling;
[SerializeField] public int VersusBattleCount;
[SerializeField] public int VersusRoundCount;
[SerializeField] public int SpellCastCount;
[SerializeField] public int DeathCount;
[SerializeField] public ZoneStats[] ZonesStats;
[SerializeField] public CharacterStats[] CharactersStats;
public string GetStatLocalizationID(GameStatisticsEnum stat)
{
return "GameStat_"+stat.ToString();
}
public float GetStatValue(GameStatisticsEnum stat)
{
switch (stat) {
case GameStatisticsEnum.TimesGameOpened:
return TimesGameOpened;
case GameStatisticsEnum.TimePlayed:
return TimePlayed;
case GameStatisticsEnum.TimeBattling:
return TimeBattling;
case GameStatisticsEnum.VersusBattleCount:
return VersusBattleCount;
case GameStatisticsEnum.VersusRoundCount:
return VersusRoundCount;
case GameStatisticsEnum.SpellCastCount:
return SpellCastCount;
case GameStatisticsEnum.DeathCount:
return DeathCount;
default:
throw new ArgumentOutOfRangeException(nameof(stat), stat, null);
}
}
public void SetStat(GameStatisticsEnum stat, float value)
{
switch (stat) {
case GameStatisticsEnum.TimesGameOpened:
TimesGameOpened = (int)value;
break;
case GameStatisticsEnum.TimePlayed:
TimePlayed = value;
break;
case GameStatisticsEnum.TimeBattling:
TimeBattling = value;
break;
case GameStatisticsEnum.VersusBattleCount:
VersusBattleCount = (int)value;
break;
case GameStatisticsEnum.VersusRoundCount:
VersusRoundCount = (int)value;
break;
case GameStatisticsEnum.SpellCastCount:
SpellCastCount = (int)value;
break;
case GameStatisticsEnum.DeathCount:
DeathCount = (int)value;
break;
default:
throw new ArgumentOutOfRangeException(nameof(stat), stat, null);
}
}
}
通过这种方法,我基本上使用枚举作为键来获取本地化 ID 和统计值。
但它似乎过于冗长。 特别是如果我最终有 50-70 个统计数据要跟踪。
这里的主要目标是能够序列化统计数据,以便将它们写入磁盘,并且可以通过也可以序列化的密钥轻松访问它们(在这种情况下,我使用的是枚举,但任何东西都可以做)。
我对枚举的主要担心是我需要小心不要对元素重新排序,以防我为 UI 序列化枚举值。 如果我添加或删除统计信息,这可能是个问题(这是一个迭代过程)
我正在考虑使用 ScriptableObjects 作为键......但我想知道这是否真的是一种更好的方法。 否则我可以使用字符串……但那很容易出错……除非我制作一个自定义属性抽屉,让我下拉预定义字符串。
对此有什么想法吗?
通常当你有这么长的枚举时,它会尖叫着添加另一个抽象级别。我想我就是这种情况,你可能正在寻求通过一种称为“策略模式”的技术来利用多态性。 有很多资源你可以谷歌。 希望这些关键字可以帮助您入门。
基本上,您创建了一个名为 Stat 的抽象类。
所有 stat 子类都可以从这个基类继承它们的序列化/反序列化方法。 统计数据本身会自行保存/加载,并且可以自行找到合适的值。
要使用统计数据,请说死亡人数。 你可以做这样的事情[伪代码]
你加载它:
DeathCountStat deathCount = new DeathCountStat();
if File.Exists(deathcountsavefile):
deathCount.Load(deathcountsavefile);
deathCountUI.DeathCount= deathCount.Value
更新
deathCount.Value += 1;
deathCountUI.DeathCount= deathCount.Value;
保存
deathCount.Save(deathcountsavefile);
因为所有统计数据都继承自相同的基类,所以您的游戏可以以相同的方式处理和显示它们。 例如,你可以有一个包含 20 个不同统计数据的窗口,你可以只说
List<Stat> stats
stats.Add(deathCount);
stats.Add(killCount);
stats.Add(timePlayed);
Then
Foreach(var stat in stats):
DisplayStat(stat); //same method for all
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.