0

我正在创建一个以洞穴为主要环境的 3-D 游戏。洞穴由大量环形段组成,一个连接另一个,因此形成了一个目前很小的隧道系统。

如果玩家在洞穴内,则只有一小部分片段可见。我认为实际上隐藏不可见的部分可以节省大量的 gpu 时间,我需要其他对象,如建筑物或敌人。

所以我首先尝试做的是隐藏整个洞穴,然后通过将“node.isHidden”设置为真和假来取消隐藏可见部分。通过它们的名称找到和访问特定节点:“Node.childnode(withName:“XYZ003”,递归:false)。isHidden = true'(或 false)。

它可以工作到段未被隐藏的地步,但是一旦我试图隐藏以前未隐藏的段,渲染器就会崩溃并出现 EXC_BAD_ACCESS。

对隐藏的对象进行隐藏(当然没用,但有助于理解问题)很好,取消隐藏未隐藏的片段也是如此。

根据另一个线程的提示,我将例程移到渲染器委托中,因此不会在错误的时间进行切换,而是在应该发生此类更改的阶段进行切换,但这没有帮助。作为替代方案,我通过 SCNActions 进行了隐藏(和取消隐藏),但我收到了相同的结果,这真的让我感到困惑,因为这将是一种“官方方式”来做到这一点......

我还使用了“递归”布尔值,得到了相同的结果(适用于取消隐藏,在 isHidden = true 时崩溃)。

然后我尝试改变节点的不透明度或其他属性——效果很好。另一方面,尝试从父节点中删除节点也会导致上述崩溃。

我需要它来工作,因为旧硬件永远无法应付几千个节点(尝试这个,帧速率下降到 10fps,即使周围没有敌人)。一旦敌人出现,更新的硬件可能会崩溃......

我的想法是指针在某种程度上被第一次取消隐藏(以及因此的 BAD_ACCESS 错误)弄乱了,所以可能是一个额外的绑定(通常在 spritekit-routines 中看到)或另一种获取节点指针的方法可能是解决方案。另一方面,如果指针损坏,为什么我仍然可以访问所有其他属性?也许是子节点导致了问题——每个节点都有 20 个子节点,它们也应该改变可见性。

有没有人在我之前遇到过这种行为?我在谷歌搜索期间找不到任何东西......

4

1 回答 1

0

经常隐藏和取消隐藏节点本身通常不是问题。您可以隐藏一个主节点,主节点的任何子节点都会自动隐藏自己,因此您不必单独循环它们。

我不是调试专家,也不知道您的技能水平,但 BAD_ACCESS 可能意味着您尝试将 msg 发送到无法执行消息的内存块或应用程序尝试延迟损坏的指针时。搜索“什么是 EXC_BAD_ACCESS 以及如何调试它”以获取有关处理它的一些选项的体面教程。

我也在渲染委托中进行更改,但根据更改的数量和所需的时间,我有时会使用计时器来控制在一定时间内可以进行的更改量。这样,经过一些调整,我很确定我不会让它陷入失控的地步。

结构可能很重要 - 个人喜好,但我尝试设置一个创建单个节点(和子节点)的类数组,因此可以直接访问它们。这样我就不会遍历整个节点结构或按名称查找节点。有时在我真的必须对节点本身进行修改之前发生了很多事情,因此我可以在采取涉及显示的操作之前遍历我的类数组、检查值、比较等。这也让我有机会在需要移除节点时移除粒子系统、移除动作、设置 geometry = nil 并更新逻辑计数器。

我敢肯定意见会有所不同,但这对我来说效果很好。一旦我标准化了结构,我就会不断重复这个模式。

希望有帮助

于 2020-02-19T17:55:43.137 回答