为什么 Unity 会忽略非静态公共字段的初始化值?

2024-02-06

我在用着InvokeRepeating() http://docs.unity3d.com/ScriptReference/MonoBehaviour.InvokeRepeating.html调用游戏中的方法。我打电话InvokeRepeating() in the Start()其中之一的方法GameObject类。要设置repeatRate参数为InvokeRepeating(),我将其传递给一个名为的公共字段secondsBetweenBombDrops.

Unity 忽略我指定的值secondsBetweenBombDrops在代码中,而是使用一些默认值(即 1)secondsBetweenBombDrops声明时不带 static 修饰符:

public float secondsBetweenBombDrops = 10f;
void Start() {
    InvokeRepeating("DropBomb", 1f, secondsBetweenBombDrops);
}

但是,一旦我添加static修饰符为secondsBetweenBombDrops,代码的行为符合预期,并且使用了正确的值 10:

public static float secondsBetweenBombDrops = 10f;
void Start() {
    InvokeRepeating("DropBomb", 1f, secondsBetweenBombDrops);
}

为什么这个字段需要static修饰符使用合适的值?

在 Unity 检查器中,脚本组件显示secondsBetweenBombDrops是 1。无论我是在游戏启动时实例化预制件还是在游戏运行时创建预制件实例,都会存在默认值 1。


连载是把双刃剑

Unity 希望让每个人都变得更轻松,包括编码知识有限的人(初学者、设计师)。

为了帮助他们解决问题,Unity 在检查器中显示数据。这使得编码人员可以通过调整值进行编码,而设计人员可以在不打开 MonoDevelop/IDE 的情况下进行设计。

有两种方法可以在检查器中显示值:

public int myVar = 10;
[SerializeField] private int myOtherVar = 0; // Can also be protected

第二种更好,因为它符合封装原则(变量是私有的/受保护的,并通过方法或属性进行修改)。

当您在编辑器中显示变量时,脚本中给定的值仅在拖动脚本时使用。然后 Unity 会序列化这些值,并且不再关心任何脚本修改。这可能会导致混乱,例如,myVar在脚本中设置为 20 后,实际上不会使用它。序列化写入场景文件中。

示例中的两行代码的工作方式完全相同。

可能的解决方案

通过按脚本组件设置轮上的 Reset,可以让 Unity 考虑脚本中的新值。这还将重置组件的所有其他变量,因此仅在需要时才执行此操作。

将变量设置为私有并省略属性[SerializeField]将禁用序列化过程,因此 Unity 将不再在场景文件中查找要显示的值 - 相反,该值将由脚本在运行时创建。

将组件添加到 Unity 时,会创建该组件类型的新对象。显示的值是该对象的序列化值。因此,只能显示成员值,而不能显示静态变量,因为它们不可序列化。 (这是一个 .NET 规范,并非严格特定于 Unity。)因为Unity不序列化静态字段 http://docs.unity3d.com/ScriptReference/SerializeField.html,这就是为什么添加static修改器似乎解决了这个问题。

解释OP

在 OP 案例中,根据评论,您的公共字段在编辑器中显示的值为 1。您认为该值是默认值,而实际上它是您最初声明该字段时最有可能赋予该字段的值。将脚本添加为组件后,您将值设置为 10,并认为它有问题,因为它仍然使用值 1。您现在应该明白它按照设计工作得很好。

Unity 序列化什么?

默认情况下,Unity 将序列化并显示值类型(int、float、enum 等)以及字符串、数组、List 和 MonoBehaviour。 (可以使用编辑器脚本修改它们的外观,但这不是主题。)

下列:

public class NonMonoBehaviourClass{
   public int myVar;
}

默认情况下不序列化。再次强调,这是 .NET 规范。 Unity 默认序列化 MonoBehaviour 作为引擎要求的一部分(这会将内容保存到场景文件中)。如果您希望在编辑器中显示“经典”类,只需这么说:

[System.Serializable]
public class NonMonoBehaviourClass{
   public int myVar = 10;
}

显然,您不能将其添加到游戏对象中,因此您需要在 MonoBehaviour 中使用:

public class MyScript:MonoBehaviour{
     public NonMonoBehaviourClass obj = new NonMonoBehaviourClass();
}

这将在检查器中显示该对象并允许修改myVar实例中的变量NonMonoBehaviourClass。再次强调,任何更改myVar该值被序列化并存储到场景后,将不再考虑脚本内的内容。

有关在检查器中显示内容的额外提示

最后,接口也不显示在检查器中,因为它们不包含任何变量 - 仅包含方法和属性。在调试模式下,默认情况下不显示属性。您可以使用检查器右上角的三行按钮更改此模式。前两个设置是正常/调试。第一个是默认变量,第二个也将显示私有变量。这对于观察它们的值很有用,但不能从编辑器中更改。

因此,如果您需要显示界面,则必须考虑抽象类,因为它提供类似的功能(多继承除外),但可以是 MonoBehaviour。

参考:

http://docs.unity3d.com/ScriptReference/SerializeField.html http://docs.unity3d.com/ScriptReference/SerializeField.html

http://docs.unity3d.com/Manual/script-Serialization.html http://docs.unity3d.com/Manual/script-Serialization.html

https://www.youtube.com/watch?v=9gscwiS3xsU https://www.youtube.com/watch?v=9gscwiS3xsU

https://www.youtube.com/watch?v=MmUT0ljrHNc https://www.youtube.com/watch?v=MmUT0ljrHNc

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Unity 会忽略非静态公共字段的初始化值? 的相关文章

  • 如何使用 ASP.NET MVC 编辑多选列表?

    我想编辑一个如下所示的对象 我希望用 UsersGrossList 中的一个或多个用户填充 UsersSelectedList 使用 mvc 中的标准编辑视图 我只得到映射的字符串和布尔值 下面未显示 我在 google 上找到的许多示例都
  • 元组在 VS2012 中如何工作?

    Visual Studio 2012 功能 tuples但不是可变参数模板 这是如何完成的 如何在不使用可变模板的情况下实现元组 简而言之 微软做了与之前在 NET 中实现类似元组的数据类型完全相同的事情 创建许多版本 每个版本都有固定数量
  • 进程退出后 POSIX 名称信号量不会释放

    我正在尝试使用 POSIX 命名信号量进行跨进程同步 我注意到进程死亡或退出后 信号量仍然被系统打开 在进程 打开它 死亡或退出后是否有办法使其关闭 释放 早期的讨论在这里 当将信号量递减至零的进程崩溃时 如何恢复信号量 https sta
  • 异常堆栈跟踪不显示抛出异常的位置

    通常 当我抛出异常 捕获它并打印出堆栈跟踪时 我会看到抛出异常的调用 导致该异常的调用 导致该异常的调用that 依此类推回到整个程序的根 现在它只向我显示异常所在的调用caught 而不是它所在的地方thrown 我不明白是什么改变导致了
  • 将 OpenCV Mat 转换为数组(可能是 NSArray)

    我的 C C 技能很生疏 OpenCV 的文档也相当晦涩难懂 有没有办法获得cv Mat data属性转换为数组 NSArray 我想将其序列化为 JSON 我知道我可以使用 FileStorage 实用程序转换为 YAML XML 但这不
  • C 中“complex”的默认类型

    根据我读过的文档 C99 和更高版本的支持float complex double complex and long double complex作为复杂类型 但是 此代码在使用时编译时不会发出警告gcc Wall Wextra inclu
  • 全局使用和 .NET Standard 2.0

    我最近意识到我可以使用 C 10 功能文件范围的命名空间在 NET Standard 2 0 项目中也可以通过设置
  • C# 编译器数字文字

    有谁知道 C 编译器数字文字修饰符的完整列表 默认情况下 声明 0 使其成为 Int32 声明 0 0 使其成为 Double 我可以在末尾使用文字修饰符 f 来确保某些内容被视为 Single 例如像这样 var x 0 x is Int
  • 有什么方法可以重载 C# 中的扩展方法吗?

    我有以下模型模式 public abstract class PARENTCLASS public class CHILD A CLASS PARENTCLASS public static class EXTENSION public s
  • 在 C# 中何时使用 ArrayList 而不是 array[]?

    我经常使用一个ArrayList而不是 正常 array 当我使用时 我感觉好像我在作弊 或懒惰 ArrayList 什么时候可以使用ArrayList在数组上 数组是强类型的 并且可以很好地用作参数 如果您知道集合的长度并且它是固定的 则
  • 如何使用递归查找数字中的最小元素 [C]

    好的 所以我正在准备我的 C 考试 当谈到递归时我有点卡住了我是大学一年级的学生 这对我来说似乎有点困难 练习要求在给定的数字中使用递归函数我需要找到最小的元素 例如 52873 是 2 程序需要打印 2 include
  • 使用 OleDbCommandBuilder 时访问 SQL 语法错误

    我要在 C 中使用 OleDbDataAdapter 在 Access 数据库中插入数据 但收到错误消息INSERT INTO 命令中的语法错误 BackgroundWorker worker new BackgroundWorker Ol
  • 将错误代码映射到 C++ 中的字符串

    将错误代码从枚举映射到字符串的更有效方法是什么 在 C 中 例如 现在我正在做这样的事情 std string ErrorCodeToString enum errorCode switch errorCode case ERROR ONE
  • 使用多线程进行矩阵乘法?

    我应该使用线程将两个矩阵相乘 有两件事 当我运行程序时 我不断得到 0 我还收到消息错误 对于每个错误 它在粗体行上显示 警告 从不兼容的指针类型传递 printMatrix 的参数1 我尝试打印输出 还要注意 第一个粗体块 这是我解决问题
  • 为什么 f(i = -1, i = -1) 是未定义的行为?

    我正在读关于违反评估顺序 http en cppreference com w cpp language eval order 他们举了一个令我困惑的例子 1 如果标量对象上的副作用相对于同一标量对象上的另一个副作用是无序的 则行为未定义
  • 在哪里可以下载没有 Visual Studio 2010 的 C# 4.0 编译器?

    我知道 CTP VS 2010 映像 但我可以只下载 NET Framework 4 0 和 C 编译器吗 AFAIK VS 2010 CTP 仅作为 VM 映像提供 我不相信 Microsoft 发布了 VS 的安装程序 其中一个绝对不适
  • Xamarin.Forms UWP 项目中标题栏和选项卡之间令人恼火的空白

    我几乎是新手Xamarin Forms我正在开发一个相当简单的跨平台应用程序 该应用程序在 Android 中显示得足够好 但在 UWP 中却出现了一个愚蠢的空白 该项目由一个 TabbedPage 组成 其中包含 4 个 Navigati
  • 如果“嵌入式”SQL 2008 数据库文件不存在,如何创建它?

    我使用 C ADO Net 和在 Server Management Studio 中创建的嵌入式 MS SQL 2008 数据库文件 附加到 MS SQL 2008 Express 创建了一个数据库应用程序 有人可以向我指出一个资源 该资
  • 这种尺寸对齐是如何工作的

    对于所提供的评论 我无法理解以下代码 这段代码的作用是什么 以及等效的代码是什么8 aligned segment size must be 4 aligned attr gt options ssize 3 Here ssize is o
  • 如何在c linux中收听特定接口上的广播?

    我目前可以通过执行以下操作来收听我编写的简单广播服务器 仅广播 hello int fd socket PF INET SOCK DGRAM 0 struct sockaddr in addr memset addr 0 sizeof ad

随机推荐

  • 如何将组内的第一个值与每个后续值进行比较,直到满足条件

    所以我有一个一般结构如下的数据框 数据框 rownum group date 1 a 2021 05 01 2 a 2021 05 02 3 a 2021 05 03 4 b 2021 05 15 5 b 2021 05 17 6 b 20
  • Scala 中并行集合的效率/可扩展性(图)

    因此 我一直在 Scala 中使用并行集合来处理我正在开发的图形项目 我已经定义了图形类的基础知识 它目前正在使用scala collection mutable HashMap关键在哪里Int其值为ListBuffer Int 邻接表 编
  • OOD / OOP 练习曲 / 代码练习

    我已经在网上搜索了一段时间了 我正在寻找用于 OOD 实践 以及一些内部 TDD 研讨会 的小样本练习 如果有一个地方可以满足这一需求 请指出它 并关闭此问题 限制条件 与语言无关的现实世界问题 小 最多需要一到两个小时才能解决的问题 或者
  • 无法在Java / C++中为外部应用程序设置always-on-top

    我正在寻找解决方案 使外部应用程序 不是像记事本或 calc exe 这样的 Windows 应用程序 在按下 Java GUI 中的按钮后始终保持在最上面 我在 C 中使用此代码来获取桌面上所有打开的窗口 并将其进程 ID PID 与发送
  • 可更新视图 - SQL Server 2008

    关于可更新数据库视图的问题 我正在阅读有关该主题的一些 MSDN 文档 并且遇到以下限制 任何修改 包括 UPDATE INSERT 和 DELETE 语句 都必须仅引用一个基表中的列 我只是想确保我理解该限制 我想在我的几个媒体评论项目中
  • 多边形中的点

    我正在尝试解决一些 SPOJ 问题https www spoj pl problems FSHEEP https www spoj pl problems FSHEEP 我们必须找出点是否在多边形内部 正如我们所看到的 它不是凸多边形 问题
  • 如何更改pairs()的轴位置?

    默认情况下 pairs 将轴放在图的所有边上 在边之间交替 但是 我将数据集之间的相关性放在上三角形中 所以我想像这样调整轴位置 我需要设置哪些参数 您可以自定义配对功能 如果你看一下代码 就会发现轴是在 2 个嵌套的 for 循环内绘制的
  • 为什么 RGB 使用 6 个十六进制数字?

    据我所知 RGB 用两个十六进制数字编码颜色 对应于红色 绿色和蓝色分量 例如 ff0000 是纯红色 据我了解 每个十六进制数字代表 0 15 之间的数字 或 4 位信息 但是如何用 32 位来表示每种颜色呢 为什么使用两位数字表示红色
  • 如何在 Mercurial 上 git reset --hard HEAD?

    我是一名 Git 用户 正在尝试使用 Mercurial 事情是这样的 我做了一个hg backout在我想恢复的变更集上 这创建了一个新头 因此 hg 指示我合并 我认为回到 默认 合并后 它告诉我我仍然必须提交 然后我注意到在解决合并中
  • Bash 脚本 - 变量内容作为命令运行

    我有一个 Perl 脚本 它给我一个定义的随机数列表 这些随机数对应于文件的行 接下来我想使用从文件中提取这些行sed bin bash count cat last queries txt wc l var perl test pl te
  • 如何通过拖动顶部的 div 来调整其大小?

    我想在拖动两个 div 之间的部分时调整 div 的大小 在搜索中我发现this http jsfiddle net gaby Bek9L 1779 但我不知道如何使这个水平而不是可用的垂直拖动 我的 div 看起来像 div div di
  • Install4j:有没有办法用包含占位符的文本覆盖欢迎消息?

    我需要覆盖install4j欢迎消息 其中包含我需要在运行时解析的占位符文本 将从属性文件中读取替换值 welcomeLabel3 Text 0 another text 1 无法向系统消息添加占位符 您必须指定整个消息 但是 您可以使用安
  • 如何从 javascript 文件(而不是 vue 组件)获取 vuex 状态

    我正在使用 vuex 2 1 1 并让事情在 vue 单文件组件中工作 然而 为了避免 vue 单文件组件中出现太多问题 我将一些函数移至utils js我将其导入到 vue 文件中的模块 在这个utils js我想阅读 vuex 状态 我
  • 初学者:AVR C++ Atmel Studio 6

    我在确定我可以访问哪些库时遇到问题 我知道我可以使用 Atmel Studio 6 IDE 用 C 对微控制器 Atmega328p 进行编程 但是 我无法弄清楚我可以访问哪些库的记录在哪里 例如 我可以使用 STL 例如向量 双端队列 吗
  • Google Maps API V3 -> 利用 MarkerCluster 但簇本身是否特定于绘制的多边形/区域?

    好吧 让我以我已经创建了很多谷歌地图的事实作为这个问题的序言 但它们是严格的标记和表示路线的折线以及一些处理程序交互 现在我希望基本上显示一张世界地图 主要是北美 我想用我拥有的一些纬度 经度将这片大陆分成我预定义的区域 使用这些区域 我想
  • CSS 面包屑箭头指向左侧

    我发现这个 css 面包屑指向右侧 我想指向左侧 相信我 我一遍又一遍地尝试 但没有成功 请有人告诉我该怎么做 div span display inline block position relative background 88b7d
  • 改造 - 更改 BaseUrl

    我有一个场景 我必须使用相同的基本 URL 调用 API 例如www myAPI com但以不同的baseUrl 我有一个 Retrofit 2 的实例 它是通过Builder return new Retrofit Builder bas
  • 将 UL 在 DIV 内垂直居中

    我有以下内容 div style background Red height 100px ul li a href Home a li ul div 我想将 ul 垂直居中在 div 中 但我不知道如何 小提琴演示 http jsfiddl
  • 如何在C++03中用sprintf正确替换sprintf_s?

    sprintf s是该函数的 Microsoft 实现sprintf他们修补了一个缺陷 添加了一个参数来获取函数限制写入的边界值 等效的引入C 11 snprintf 但在这里 我们谈论的是C 03 syntax 签名 count char
  • 为什么 Unity 会忽略非静态公共字段的初始化值?

    我在用着InvokeRepeating http docs unity3d com ScriptReference MonoBehaviour InvokeRepeating html调用游戏中的方法 我打电话InvokeRepeating