为啥要使用 SerializeField?
Posted
技术标签:
【中文标题】为啥要使用 SerializeField?【英文标题】:Why should I use SerializeField?为什么要使用 SerializeField? 【发布时间】:2018-11-07 14:58:22 【问题描述】:刚开始学习C#和Unity,有一点不习惯:
为什么以及何时应该使用[SerializeField]
?
尽管使用了 [SerializeField]
并且在我的统一界面中有更多文本框,但将变量硬编码是不是很糟糕?
【问题讨论】:
【参考方案1】:为什么以及何时应该使用 [SerializeField]?
使用 SerializeField
属性会导致 Unity 序列化任何 private
变量。这不适用于 C# 中的静态变量和属性。
当您需要变量为private
但又希望它显示在编辑器中时,您可以使用SerializeField
属性。
例如,这个不会显示在编辑器中:
private float score;
这是因为它是一个 private
变量,但下面的变量应该显示在编辑器中:
[SerializeField]
private float score;
那是因为您对其应用了SerializeField
,并告诉 Unity 对其进行序列化并在编辑器中显示它。
请注意,private
变量与 C# 的关系比 Unity 更多。还有公共变量变量。标记变量private
意味着您不希望其他脚本能够访问该变量。还有public
限定符。标记变量public
意味着您希望其他脚本能够访问该变量。
有时,您希望其他脚本能够从另一个脚本访问您的变量,但您不希望 public
变量显示在编辑器中。您可以使用[HideInInspector]
属性隐藏public
变量。
这将显示在编辑器中:
public float score;
此不会显示在编辑器中:
[HideInInspector]
public float score;
尽管使用了 [SerializeField],但仍然对变量进行硬编码是不是很糟糕 并在我的统一界面中有更多文本框?
是的,这对新用户来说尤其不利。对于长期以来的 Unity 和 C# 程序员来说,这应该没什么大不了的。这不好的原因是当你有下面的代码时:
[SerializeField]
private float score = 5f;
编辑器中的默认值为5
。保存脚本后,此变量现在在编辑器中更新为 5。问题是您可以将其从编辑器更改为 14
。一旦你从编辑器中更改它,脚本中的值仍然是5
,但是当你运行它时,Unity 将使用你在编辑器中设置的值14
。这可能会导致您花费大量时间来解决甚至不是问题的问题,因为在编辑器中设置了不同的值,而您期望使用脚本中设置的默认值。
将score
变量重置为默认的5
变量的唯一方法是将变量重命名为其他名称或从编辑器重置它。即使您将脚本中的值从5
更改为3
,它也不会改变。它必须从编辑器中重命名或重置。值得了解,但是当您习惯了 Unity 后,您将不必担心这一点。
【讨论】:
另外值得注意的是,SerializeField
不仅在 Inspector 中显示了该值,更重要的是还使其被序列化 => 保存(如 Draco18s mentioned)
@derHugo 我不会真的用“保存”这个作品来描述它。甚至doc 也没有。一旦变量被标记为[SerializeField]
,它会使它看起来像,在运行时通过代码更改它,它会自我保存,这并不完全正确。我只是提到当public
或标记为[SerializeField]
时,新值在编辑器中,它会覆盖代码中的值,除非重命名或重置,否则永远不会改变
没有“序列化”这个词。我的意思是通常的private int
将例如不被保存意味着它不会出现,例如保存后在统一场景文件中。你可能会从编辑器脚本中设置一个私有值,但如果它没有被序列化,它将毫无用处,并且始终具有它的默认值。
@derHugo 你能详细说明一下这个解释吗?我刚刚开始团结,这让我很困惑。我到处看,定义说它使某些东西“可序列化”或“它被序列化......”。这实际上意味着什么?
@AyushKoul checkout Unity Manual - Script Serialization 这应该可以解释。简而言之,基本上:序列化 = 将 c# 实例和值转换为文件格式 => 存储。反序列化 = 读取这样的文件 => 将文件内容转换为 c# 实例、值等。所以基本上文件 Example.unity
是包含您在 Unity 示例场景中看到的所有信息的序列化文件;)【参考方案2】:
[SerializeField] 属性用于将 非公共 字段标记为可序列化:以便 Unity 可以保存和加载这些值(所有公共字段默认被序列化),即使它们不是公共的.
就是这样。你想用的时候就用它。
【讨论】:
它还使该变量在 Inspector 中可见/可调整。 您也可以通过将检查器设置为debug
来做到这一点。所以我不建议使用它来检查值。
是的,但您可能想要更改/设置私有变量的值。我就是这个意思
谁能解释一下什么是序列化?即使在定义中,它也说它使某些东西“可序列化”或“它被序列化......”。这实际上意味着什么?
@AyushKoul 有时您可能希望将所有类数据转储到文件或字符串中,例如 JSON 或二进制文件,以便之后从此类文件中加载它(可能是因为您进行了保存将来要加载的文件,例如)。序列化/反序列化是将原始数据转换为任意格式并返回的行为。见docs.unity3d.com/Manual/JSONSerialization.html以上是关于为啥要使用 SerializeField?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 pandas.Series.std() 与 numpy.std() 不同?
为啥我会收到 ValueError:Series 的真值不明确。使用 a.empty、a.bool()、a.item()、a.any() 或 a.all()