游戏如何删除数据库中的对象但同时对其进行动画处理
Posted
技术标签:
【中文标题】游戏如何删除数据库中的对象但同时对其进行动画处理【英文标题】:How games delete an object in the database but animate it out at the same time 【发布时间】:2018-02-06 05:44:04 【问题描述】:我想知道当您执行删除项目等操作时,动画等异步操作如何工作,因此想出了这种思考过程,并希望得到反馈,看看从行业最佳实践的角度来看它是否有意义。
有两层:
反应层。 渲染层。反应层立即发生,可以通过传统的事件分派来完成。
这是您创建和删除数据的地方,这一切都是即时发生的。
状态机会收到这些即时反应更改的通知。
然后状态机“转换”。这个过程会在一段时间内发生,假设发生了一些异步的事情(动画、网络请求等)。这就是人们所说的“动作队列”的意思。
然后渲染层从动作队列中提取内容并渲染它。这种方式对底层的即时反应层有一种延迟反应。
我的问题是反应层是否也需要处理异步。例如,删除某些内容。
假设某个项目已被删除,并且您想为其制作动画。有几种方法可以做到这一点:
-
将删除操作排队,然后首先对其进行动画处理。动画完成后,进行实际删除。如果动画被中断(取消删除),则永远不会执行删除。
立即删除项目(反应层)。动画层保持对周围项目的引用,因此即使从全局位置删除它仍然可以执行其动画。如果动画被取消,那么您将不得不做一个更复杂的“撤消”之类的事情。
如果 (1) 是要走的路,那么就没有反应层,所有的实现都考虑到了一种动作队列。这使得编写可重用代码变得更加困难,因为一切都与动作队列的想法相关。
如果(2)是要走的路,那么数据有两个副本,全局副本和本地副本,它们异步保持同步。这使得拥有可重用代码更容易,但推理起来更复杂。
想知道这是否有意义,以及这些方法中的任何一种在行业中是否是更好的做法(或者是否有更有意义的替代方案我没有解决)。
换句话说,主要有两种方法:
-
渴望:现在删除它,好吧,我们已经删除它的每个人,是时候回到里面了。并等待一切恢复正常,然后将其称为“完成”。
小心:宣布“我们将删除它”,然后等到一切都完成后返回内部进行实际删除。
想知道游戏和应用等如何处理这类事情。
更新
换个角度想,或许更像是海带在海里的摇曳:
https://www.youtube.com/watch?v=gIeLCzR8EgA
我的意思是,有一个即时的基础层(创建/删除),然后是一些中间层,其中包含发生的所有事务(创建/删除)的副本,渲染层用于动画创建/删除。因此原始数据始终是同步的,但渲染层使用了一种旧版本的数据,其中包含发生的所有更改的链。
反应层->事务层->渲染层。
另一个选项是标记为删除,然后只有在动画完成后才真正执行删除,但这似乎很hacky。
更新
另一个版本:
反应版本 始终拥有最新数据。 (一) 渲染版本 具有最后一个数据 (b),以及导致 (a) 的一系列更改。 渲染完成后,它将更改应用于 (b),因此最终类似于 (a)。【问题讨论】:
我会用第二种方法。不是因为它更容易,而是因为用户希望它立即被删除。可选地,可以添加一个“灰色”状态来锁定某些元素的使用。如果删除成功则完全删除,否则再次解锁 【参考方案1】:根据我作为 Unity 游戏开发者的经验,正确的决定是在中间,因为游戏引擎中的物理是近似的,因为半完美事物的感觉就像是完美的事物一样。
解释是因为你的目标越真实,你需要的资源就越多,不仅是 CPU 和 GPU,还有现金。
在我为标志选项引用这个奇怪的序言之后,应用的方法与普通的垃圾收集器没有太大区别,你标记一个不再有用的项目,当垃圾收集器来时,他释放了这个对象使用的内存空间,所以这个新空间可以重复使用。
很多引擎都完成了同样的过程,销毁操作在渲染计算之前进行。
最终目标始终是达到一个良好的中间解决方案。
在引擎计算过程的每一刻都有可能强制即时销毁,但这种解决方案总是被弃用。
对于动画,您通常使用的方式是在动画结束或最后几帧中销毁(设置要销毁的标志)。 至少你可以使用一些技巧来让淡入淡出更有趣(比如粒子)。
真正的问题是当你必须通过网络摧毁物体时(多人游戏),在这种情况下你必须建立更容易参与的机器并选择它来计算物理和交互,这台机器总是服务器或至少是主机(取决于游戏类型)。
我知道这个问题被标记为 javascript 问题,但我忍不住回答。
我还附上了统一文档中有关 Destruct 功能的页面,解释了他们如何从游戏环境中删除项目:
https://docs.unity3d.com/ScriptReference/Object.Destroy.html
祝你有美好的一天!和良好的编码。
【讨论】:
很多人错过了float t = 0.0F
部分:public static void Destroy(Object obj, float t = 0.0F);
- 这意味着您可以设置时间偏移,何时删除。不需要协程。
我从没谈过协程 :)
并且在我最后发布的链接中也写了“实际对象销毁总是延迟到当前更新循环之后,但总是在渲染之前完成。”以上是关于游戏如何删除数据库中的对象但同时对其进行动画处理的主要内容,如果未能解决你的问题,请参考以下文章