C#、Unity - 在场景之间保留/访问/修改值的最方便快捷的方法?

2023-12-20

我寻找答案,但仍然不知所措。我有一些角色生成器,它创建然后保存玩家角色变量。它们被保存到一个新的脚本“PlayerCharacterData”中,它是对象CharacterData的一个组件。该对象具有DontDestroyOnLoad,因此它会保留到其他场景。生成角色后,游戏将角色数据加载到该脚本中,当我切换场景时,数据会从二进制文件(之前序列化)正确加载。

但现在我有了这个核心,我需要大量的 UI 对象从“PlayerCharacterData”类加载数据,因此 UI 可以填充所有字段等。稍后整个游戏将取决于“PlayerCharacterData”中的变量值。

这是我的 PlayerCharacterData 脚本的一部分:

public class PlayerCharacterData : MonoBehaviour {

   void Awake(){
       DontDestroyOnLoad (this); // keeps the object when changing scenes
   }

   // below we have data stored in variables. It was loaded by another script.    
   public string characterName;
   public int characterSpeed;
   public List<Weapon>characterInvWeapon;
   // etc, more variables x50-70
   }

现在这是我的公共类 UIPlayerCharacterData 的示例。我在 Unity 编辑器中向对象 CharacterData 添加了一个标签,以使“查找”速度更快:

public class UIPlayerCharacterData : PlayerCharacterData {

    public void NameToCharacterDataUI() {
       // this would be required to make it work: PlayerCharacterData playerCharacterData = GameObject.FindGameObjectWithTag("CharacterData").GetComponent<PlayerCharacterData>();
       Text_ch_sh_char_name_string.text = playerCharacterData.characterName;
   }
   // etc, more functions like that x50-70    

   void Awake () {
      PlayerCharacterData playerCharacterData = GameObject.FindGameObjectWithTag("CharacterData").GetComponent<PlayerCharacterData>();
      NameToCharacterDataUI();
      // etc, calling more functions x50-70 
   }
}

问题是,这些类位于不同的对象上。第一个是从第一个场景持续存在的 CharacterData 对象的组件,第二个是第二个场景中主要 UI 面板的组件。第二类有很多 UI 字段需要填写,只是向您展示了其中之一。每个都从第一类(CharacterData 对象上的组件)获取数据。因此,UI 大约有 50-70 个变量可以从中提取数据。

这只是一个开始,因为整个游戏都需要获取和修改 PlayerCharacterData 脚本中的数据。

现在,我发现函数 NameToCharacterData() 不起作用,因为它在playerCharacterSheet 变量中没有引用:“对象引用未设置为对象的实例”。以为它已经在 Awake() 中解决了 - 我错了。 所以看来我们需要设置PlayerCharacterData playerCharacterData = GameObject.Find("CharacterData").GetComponent<PlayerCharacterData>();

...在填充 UI 字段的 50-70 个函数中。 更不用说游戏中的所有其他系统也需要这样做。 另外,每次玩家打开 UI 时,都需要重新生成这些 UI 字段。

有没有一些更快、更方便的方法呢? 我正在考虑将所有 PlayerCharacterData 变量设为静态 - 这会快如闪电,但我更愿意让我们的引擎为多人游戏(1 到 200 名玩家)做好准备。所以不确定。

另外,将角色数据变量保存到一些没有 Monobehaviour 的脚本中不是更好吗,这样就不会连接到游戏对象,也许我们可以使用PlayerCharacterData playerCharacterData = new PlayerCharacterData();从该类中获取值?我只是需要能够从任何地方快速访问这些值。

此时确实正在考虑使用静态变量,但如果有更好的解决方案,或者有更好的方法为多人游戏创建静态变量,请告诉我。


我不清楚您要在哪里存储 PlayerCharacterData 引用,但由于您在 Awake() 内部本地声明了它,因此在该方法之外将不可用。我也不清楚 Awake() 如何不足以存储此引用,但即使在这种情况下,您也可以将对它的所有访问包装在“安全”方法中以避免空引用。也许是这样的?

public class UIPlayerCharacterData : PlayerCharacterData {

    PlayerCharacterData playerCharacterData;

    public void NameToCharacterDataUI() {
       Text_ch_sh_char_name_string.text = GetPlayerCharacterData().characterName;
   }
   // etc, more functions like that x50-70    

   void Awake () {
      PlayerCharacterData playerCharacterData = GetCharacterData();
      NameToCharacterDataUI();
      // etc, calling more functions x50-70 
   }

   PlayerCharacterData GetPlayerCharacterData() {
       if (playerCharacterData == null) {
           playerCharacterData = GameObject.FindGameObjectWithTag("CharacterData").GetComponent<PlayerCharacterData>();
       }
       return playerCharacterData;
   }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C#、Unity - 在场景之间保留/访问/修改值的最方便快捷的方法? 的相关文章

  • 静态只读字符串数组

    我在我的 Web 应用程序中使用静态只读字符串数组 基本上数组有错误代码 我将所有类似的错误代码保存在一个数组中并检查该数组 而不是检查不同常量字符串中的每个错误代码 like public static readonly string m
  • 使用 lambda 表达式注册类型

    我想知道如何在 UnityContainer 中实现这样的功能 container RegisterType
  • 如何填充 ToolStripComboBox?

    我发现它很难将数据绑定到ToolStripComboBox 好像没有这个ValueMember and DisplayMember特性 怎么绑定呢 访问toolstripcombobox中包装的组合框并访问其ValueMember Disp
  • 从同一个类中的另一个构造函数调用构造函数

    我有一个带有两个构造函数的类 C 这是代码片段 public class FooBar public FooBar string s constructor 1 some functionality public FooBar int i
  • 使用 GCP 的数据存储区时如何区分代码是在模拟器中运行还是在 GKE 中运行

    按照中给出的说明进行操作后 我不确定是否遗漏了任何内容https cloud google com datastore docs tools datastore emulator https cloud google com datasto
  • 在Linux中,找不到框架“.NETFramework,Version=v4.5”的参考程序集

    我已经设置了 Visual studio 来在我的 Ubuntu 机器上编译 C 代码 我将工作区 我的代码加载到 VS 我可以看到以下错误 The reference assemblies for framework NETFramewo
  • 使用valgrind进行GDB远程调试

    如果我使用远程调试gdb我连接到gdbserver using target remote host 2345 如果我使用 valgrind 和 gdb 调试内存错误 以中断无效内存访问 我会使用 target remote vgdb 启动
  • 为什么这个二维指针表示法有效,而另一个则无效[重复]

    这个问题在这里已经有答案了 这里我编写了一段代码来打印 3x3 矩阵的对角线值之和 这里我必须将矩阵传递给函数 矩阵被传递给指针数组 代码可以工作 但问题是我必须编写参数的方式如下 int mat 3 以下导致程序崩溃 int mat 3
  • 在mysql连接字符串中添加应用程序名称/程序名称[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我正在寻找一种解决方案 在连接字符串中添加应用程序名称或程序名称 以便它在 MySQL Workbench 中的 客户端连接 下可见 SQL
  • 高效列出目录中的所有子目录

    请参阅迄今为止所采取的建议的编辑 我正在尝试使用 WinAPI 和 C 列出给定目录中的所有目录 文件夹 现在我的算法又慢又低效 使用 FindFirstFileEx 打开我正在搜索的文件夹 然后我查看目录中的每个文件 使用 FindNex
  • 检测到严重错误 c0000374 - C++ dll 将已分配内存的指针返回到 C#

    我有一个 c dll 它为我的主 c 应用程序提供一些功能 在这里 我尝试读取一个文件 将其加载到内存 然后返回一些信息 例如加载数据的指针和内存块的计数到 c Dll 成功将文件读取到内存 但在返回主应用程序时 程序由于堆损坏而崩溃 检测
  • WPF DataGridTemplateColumn 组合框更新所有行

    我有这个 XAML 它从 ItemSource 是枚举的组合框中选择一个值 我使用的教程是 http www c sharpcorner com uploadfile dpatra combobox in datagrid in wpf h
  • 使 Guid 属性成为线程安全的

    我的一个类有一个 Guid 类型的属性 该属性可以由多个线程同时读写 我的印象是对 Guid 的读取和写入不是原子的 因此我应该锁定它们 我选择这样做 public Guid TestKey get lock testKeyLock ret
  • WebBrowser.Print() 等待完成。 。网

    我在 VB NET 中使用 WebBrowser 控件并调用 Print 方法 我正在使用 PDF 打印机进行打印 当调用 Print 时 它不会立即启动 它会等到完成整个子或块的运行代码 我需要确保我正在打印的文件也完整并继续处理该文件
  • C++ new * char 不为空

    我有一个问题 我在 ASIO 中开发服务器 数据包采用尖头字符 当我创建新字符时 例如char buffer new char 128 我必须手动将其清理为空 By for int i 0 i lt 128 i buffer i 0x00
  • OpenGL:仅获取模板缓冲区而没有深度缓冲区?

    我想获取一个模板缓冲区 但如果可能的话 不要承受附加深度缓冲区的开销 因为我不会使用它 我发现的大多数资源表明 虽然模板缓冲区是可选的 例如 排除它以利于获得更高的深度缓冲区精度 但我还没有看到任何请求并成功获取仅 8 位模板缓冲区的代码
  • 为boost python编译的.so找不到模块

    我正在尝试将 C 代码包装到 python 中 只需一个类即可导出两个函数 我编译为map so 当我尝试时import map得到像噪音一样的错误 Traceback most recent call last File
  • 如何减少具有多个单元的 PdfPTable 的内存消耗

    我正在使用 ITextSharp 创建一个 PDF 它由单个 PdfTable 组成 不幸的是 对于特定的数据集 由于创建了大量 PdfPCell 我遇到了内存不足异常 我已经分析了内存使用情况 我有近百万个单元格的 1 2 在这种情况下有
  • 是否可以在不连接数据库的情况下检索 MetadataWorkspace?

    我正在编写一个需要遍历实体框架的测试库MetadataWorkspace对于给定的DbContext类型 但是 由于这是一个测试库 我宁愿不连接到数据库 它引入了测试环境中可能无法使用的依赖项 当我尝试获取参考时MetadataWorksp
  • 如何使用 C++11 using 语法键入定义函数指针?

    我想写这个 typedef void FunctionPtr using using 我该怎么做呢 它具有类似的语法 只不过您从指针中删除了标识符 using FunctionPtr void 这是一个Example http ideone

随机推荐