【BUG】在【执行读取】后,读取次数越多,声音越大 / 在多个保存节点下随机会出现保存失败的现象

只是想告知您,我正在调查此事,并致力于寻找一种能保持您现有设置不变的可行解决方案或变通方法。对象设置提供了很大帮助,因为需要考虑更多因素,例如动画、多个存档点相互修正等。一旦找到可行的方案,我会在此回复。我的目标是构建一个系统,使所有存档点共用一个对象,并在触发存档点时自动“清理”自身。当然,我会严格遵循您当前的逻辑(尽管结构可能略有调整)。

1 个赞

关于保存失效这个问题,想请问一下baz先生,目前制作组那边有所行动调查到原因了么,目前几个重大BUG困扰它也是其中一个 :rofl:

你好 S.C!

我一直在研究这个问题,现在有一个模块供你尝试。这就是我之前提到的系统,它由一个对象来处理所有的存档点,并在触发存档点时自动清理自身。

首先,我想提一下,我不太明白为什么你要分别设置存档点 A 和存档点 B。我做了一些调整,发现只用一个存档点就能正常运行,希望这样可以。我采用了存档点 A,在其中添加了一个 ChangeAction(更改动作),并重新调整了一些设置。你可以在模块中看到所有细节。

以下是模块的安装和使用方法:

  1. 下载模块。revamped_save_a.tres (9.8 KB)
  2. 打开“模块列表”窗口。它位于输出调试器窗口附近。
  3. 点击文件夹图标,然后点击“在文件管理器中打开我的模块位置”。
  4. 将下载的模块放入该文件夹中。
  5. 回到 AGMaker,点击“重新加载模块列表”(就在文件夹图标旁边)以刷新。
  6. 现在你应该能看到改进后的 Save A。将其拖入存档点 A 的可视化脚本中。
  7. 删除其中旧的逻辑状态。
  8. 将初始状态设置为正确的状态。有时会出现混乱,所以请务必仔细检查。

接下来,进入游戏场景 2,将蜡烛之间的间距稍微拉大一些。如果它们靠得太近,会同时触发存档,从而导致逻辑问题。这是由于对象距离设置为 25 所致。我想你实际上也不会把它们放得那么近,所以稍微分开一点即可。

要让 A 和 B 同时正常工作在技术层面更复杂一些。当所有 ChangeAction 都设置为 A 时,运行效果很好。但如果同时存在 B 和 A,A 会在 B 切换到该状态之前就被激活。所以,如果你能只用一个存档点,我认为那样会更好。这只是这些动作和条件的工作机制决定的。

请测试一下,并告诉我们结果如何。如果你确实需要同时使用存档点 A 和存档点 B,请告诉我为什么需要两个,我会重新考虑方案。

感谢baz回复,使用A和B两个存档点的主要原因是为了让变回蜡烛的动画不割裂。

如你所见我的关卡场景里有可能在同一个画面里出现两个存档点。这时候如果保存第一个时,看到另外一个也跟随一起改变动画演出这非常奇怪。所以我最后决定使用A和B,这样即便它们在同一个摄像机下,也能分别演出各自的动画

这样的形式是否更容易被接受?
agm.windows.editor.x8664vFcppJnjJV|视频

貌似视频失效了无法查看到~ 切换成英文模式可以看到了。

游戏里的所有动画帧都是我自己绘制的,就是希望可以让整个游戏的动画演出更加流畅。如果出现卡顿跳帧的状况我作为创作者难以接受 :sweat_smile:

我会继续努力优化视觉效果,并随时向您汇报。

非常非常感谢您!

请问A和B同时存在导致的保存失败问题是开发团队已经确认无法在引擎里修复的问题么?
必须另外想方法去解决这道难关?

纠正一下,这不是一个 bug,而是视觉脚本或设计设置的问题。需要说明的是,让存档/读取功能感觉流畅且精致,是较难掌握的部分之一,PGM 中也是如此。存档/读取系统被刻意设计得简单可靠。真正的工作在于用协调的视觉效果来包装它(例如:同一时间只点亮一个点、不重复的收回动画等)。

一种设计解决方案是调整关卡布局,确保在同一视口中无法同时看到多个存档点。这将是最简单快捷的方法。

那这个怎么样?

动画与逻辑之间的冲突太多,所以我把它们稍微分离了一下。有一个脚本专门负责动画,而 VS 则纯粹处理逻辑。


你觉得怎么样?

这看起来相当不错,非常感谢baz先生的优化,虽然我还没理解它的逻辑,看来需要发一份工程研究一下!

昨天被告知这个不是BUG后,我想到一个比较简单的方式解决这个存档失败的问题。就是把A和B的保存替换成变量开关。 在场景里另外生成一共空对象,当开关打开时就触发一次保存。 这样也可以实现整个游戏里只有一个保存对象的方式 :rofl:

哦好的,你已经解决了。如果你想要这个版本的话告诉我一声,不然我就继续处理其他事情了。

请务必发我一份这个版本,我不知道如何实现单独一个对象可以在动画实现不同步的效果,这看起来很厉害,希望可以学习!

设置(按顺序在存档点 A 中操作)

  1. 添加脚本。 在存档点 A 上,添加一个子节点并附加 save_point_driver.gd
    save_point_driver.gd (16.5 KB)

  2. 添加开关。 在开关设置中,添加以下三个。名称必须与脚本匹配——如果希望使用不同的名称,请在两处同时重命名。

  3. 拖入模块。 打开视觉脚本,拖入存档点模块。AGMaker 会对其分组并重新编号节点 ID——这是正常的。它会自动构建所有状态和连接。custom_save_method.tres (5.9 KB)

  4. 如果模块损坏或缺失, 请使用下方的逻辑部分手动构建状态机。

  5. 将您的存档点 A 对象 放置在玩家应该能够存档的任何位置。

  6. 删除所有存档点 B 并替换为存档点 A。完成。

开关说明

名称 可存档 原因
request_save 关闭 一次性“立即存档”信号。如果可存档,文件将存储 true 并在每次加载时重新触发 → 导致循环。
request_load 关闭 加载时的相同情况。
current_save_point 开启 游戏必须记住加载后哪个存档点是激活的。

视觉脚本逻辑

双方如何通信:

  • 脚本在玩家存档时将 request_save 设为 开启 → 视觉脚本执行存档操作,然后将其重新设为 关闭
  • 脚本在加载后(仅在激活点)将 request_load 设为 开启 → 视觉脚本执行加载操作,然后将其重新设为 关闭
  • current_save_point 仅由脚本管理。视觉脚本忽略该开关。

共 4 个状态加上一个任意状态。起始状态:wait wait 本身不执行任何操作——它只是监听两个开关。

存档流程: wait → on save setup → save → wait

  • wait → on save setup —— 当 request_save 变为 开启 时(开关变量已更改,监听 request_save)。
  • on save setup 执行:播放音频(存档音效)· 设置 request_save = false · 恢复玩家生命值(目标 = P1)。
  • on save setup → save —— 自动触发,无需条件。
  • save 执行:保存游戏数据。
  • save → wait —— 自动触发。

加载流程: wait → on load → wait

  • wait → on load —— 当 request_load 变为 开启 时(开关变量已更改,监听 request_load)。
  • on load 执行:更改动作(重置玩家,P1)· 设置 request_load = false · 恢复玩家生命值(P1)。
  • on load → wait —— 自动触发。

两个分支都会恢复生命值——这就是为什么每次存档和每次加载都会治愈玩家的原因。

快速视觉脚本流程:

  • 起始状态为 wait
  • wait → on save setuprequest_save 触发时执行
  • on save setup:播放音效,设置 request_save = false,恢复生命值
  • save:执行保存游戏数据
  • save → wait 是自动的
  • wait → on loadrequest_load 触发时执行
  • on load:重置动作,设置 request_load = false,恢复生命值
  • on load → wait 是自动的
  • request_saverequest_load 不可存档
  • current_save_point 可存档
1 个赞

这非常酷,原来可以在vs节点下用作子节点添加GD,学习胜多,非常感谢baz的热心指点!

1 个赞

让您久等了。
当相机靠近时,我们已在版本1.3.0中修复了对象加载时的泄漏问题,请您确认。

谢谢,您回复错了帖子。应该是这条才对

还有想咨询关于子节点 GameObject 的复活位置依赖于父节点位置的问题
在最新版本里依然有很多谜之问题,比如选择摄像机复活后,移动过去偶尔复活,偶尔不复活。
而且子节点复活后不会附属在父节点之下执行,会被脱离出来变成独立节点。
请问目前是否有在修复中?

我可以确认已为此问题创建了工单。目前尚无预计完成时间。