我最近遇到了一些问题,只是在我正在制作的游戏中传递对象/敌人的引用,我想知道我是否使用了错误的方法。
我遇到的主要问题是处置敌人和物体,当其他敌人或玩家可能仍然有链接时。
例如,如果你有一只兔子和一只狼,狼可能会选择兔子作为它的目标。我正在做的是,狼有GameObject Target = null;
,当它决定它是饥饿时,目标成为兔子。
如果兔子死了,比如另一只狼杀了它,它就无法从游戏中正确移除,因为这只狼仍然有参考它。
此外,如果您使用的是解耦方法,兔子可能会被闪电击中,将其健康状况降至零以下。当它下次更新时,它意识到它已经死亡,并从游戏中移除......但是没有办法更新对它感兴趣的所有内容。
如果你给每个敌人一个唯一的ID,你可以简单地使用对它的引用,并使用一个处理它的中央查找类。如果怪物死了,查找类可以从它自己的索引中删除它,随后任何试图访问它的东西都会被告知它已经死了,然后它们就可以采取相应的行动了。
对此有何想法?
答案 0 :(得分:7)
一种可能的方法是让对象向他们正在跟踪的对象注册兴趣。因此,被跟踪对象可以动态地通知跟踪器状态变化。例如Wolf向Rabbit注册(其中包含一系列感兴趣的参与者),当状态发生变化时,Rabbit会通知这些参与者。
这种方法意味着每个对象都知道它的客户端,并且该状态直接与该对象相关联(而不是在某些第三方管理器类中)。
这基本上是Observer pattern。
答案 1 :(得分:2)
你听起来合理,为什么不呢?在散列映射中注册所有对象不应该太昂贵。然后,您可以使用某种事件总线,其中对象可以注册不同的事件。
除此之外,我还有另一种方法。你可以让兔子直接暴露事件并让狼注册。
第二种方法很有吸引力,但它会将事件发布者与订阅者联系起来。第一种方法在技术上更复杂,但也可以允许其他类型的查找。
答案 2 :(得分:2)
在实践中,我几乎找不到需要从其他游戏对象持有游戏对象的引用或指针的情况。但是,有一些例如您提供的定位示例,以及那些唯一ID号工作良好的情况。
我想你可以使用观察者模式来确保在必要时清除引用,但是如果每个对象需要多于1个引用,我认为这将开始变得混乱。您可能有一个目标游戏对象,您可能在当前组中有游戏对象,您可能正在关注游戏对象,与一个对话,对抗一个等等。这可能意味着您的观察对象需要具有单一的清理功能,可以检查所有传出对象引用并重置它们。
我个人认为使用ID并在使用时验证对象的持续存在会更容易,尽管价格是一些样板代码来执行此操作以及每次查找的性能成本。
答案 3 :(得分:1)
仅当设计保持单一时,引用才起作用。
首先,将引用传递给其他模块(特别是脚本)会导致安全性和技术问题。
其次,如果您想通过在新模块中实现某些行为和相关属性来扩展现有对象 - 您将不会在所有场合都有一个引用。