2017-10-13 162 views
2

我在虚幻引擎4中编写游戏。引擎为您提供了几个课程。在这个问题中,我将更多地关注类的关系而不是它们的目的。例如A - > B意味着A继承自B):
ACharacter - > APawn - > AActor - > ... - >这个引擎的类是这样的(例如A→B意味着A继承自B)
UObject
“...”只是未发布的类。
UObject类是引擎的主类,几乎引擎中的每个类都在我的游戏中最终继承了UObject形式,此外它还提供了许多我需要的功能。
继承是而不是虚拟继承。这对未来很重要。我无法编辑任何引擎的类。更好的课堂设计

在我的游戏中有3个主要类: 建筑,生活和实体。
大厦继承 AActor和实体
生活继承和压低的实体

enter image description here

我已经创建了涉及建筑或生活没有复制我的代码的实体类。例如,生活类需要提供攻击另一个生活或建筑物的功能。所以我可以创建两个具有活动目标参数的“AttackLiving”函数和一个具有Building对象参数的函数“AttackBuilding”,这两个函数都具有完全相同的功能。相反,我创建了实体类,这样我只需要一个函数 - “AttackEntity”。当然这只是一个例子,我在整个代码中都使用了Entity类,所以我可以在一个镜头中引用Living和Building。

问题始于实体类。我在一年前犯了一个错误,当时我真的创造了它,我没有想到这一点。问题是实体不能从UObject继承。同样,UObject类是引擎的主类,它提供了我需要的许多功能。因为实体不从UObject继承,所以我不能访问我需要的任何函数。

我不能让UObject或AActor的实体继承,因为虚拟继承在这里不起作用。 (再次引擎类继承不是虚拟继承)

我曾想到可能的解决方案的数量。其中之一是,我总是可以将实体建立到建筑或生活取决于实体的类型,而且我可以使用UObject的功能。但这是一个非常难看的解决方案,它与实体的精髓形成鲜明对比 - 与生活和建筑的个性无关。

另外我曾经想过在UObject类的实体中有一个指针,但这是一个非常丑陋的解决方案,它并不能解决所有的问题。对于Entity的另一个问题(它也不能从UObject继承):有一个名为“TWeakObjectPtr”的模板类,它在模板中获取一个类,为它创建一个指针并检查指针是否在其他地方没有释放由发动机。

TWeakObjectPtr<Entity> entityPointer; 

的问题是,TWeakObjectPtr检查,在从UObject模板inherites给出,类,当然它不是,所以我不能用TWeakObjectPtr。

总而言之,主要问题是实体不是来自UObject的继承。但我确实需要它,所以我可以将生活和建筑联系在一起。

如果您可以使用保留实体的解决方案,我很乐意。提前致谢!

+0

UObject是UE4的基类。一切都必须从UObject继承。我建议重做你的实体类来实现这个目的,否则我不相信它会工作。 –

+0

此外,您可以在游戏开发论坛中获得更多帮助:https://gamedev.stackexchange.com/ –

+0

@ethancodes我知道这一点,但我无法使其继承UObject,因为虚拟继承不起作用这里。你对这个问题有任何实际的解决方案吗? – user2203448

回答

1

我从来没有使用虚幻引擎,但希望下面的一些想法可以有用无论如何。改善情况

的方法之一就是要打破两个Object层次之间的继承链接 - 你和发动机:

UOjbect <-- AActor <-- APawn <-- ACharacter 
       |     | 
+------+  *     | 
|  |<-- Building    | 
|Entity|       * 
|  |<------------------------ Living 
+------+ 

*--指聚集(或组成)。 您的类不会继承引擎类,而是聚合适当的引擎对象。

Entity可以具有虚拟方法getUnreal(),将返回UObject,和亚类将返回AActorACharacter对象 适当。 因此,无论您使用何种方式Entity,您都可以获取引擎对象,但不是直接使用,而是使用entiry->getUnreal()调用。

周围的其他方法,你可以从引擎类继承你的类,使“实体”是一个聚合的行为,而不是基类:

UOjbect <-- AActor <-- APawn <-- ACharacter 
      ^    ^
+------+  |     | 
|  |--* Building    | 
|Entity|       | 
|  |------------------------* Living 
+------+ 

在这里,你会用你的Building/Living在那里你需要引擎对象,但是当你想引用你自己的逻辑时,你会使用类似building->getEntity()的东西。 你可能有不同的Entity子类来实现BuildingLiving的行为。

另外,我可以推荐检查Design Patterns: Elements of Reusable Object-Oriented Software书,Structural Patterns章可以帮助您找到更多的想法。

+0

嘿鲍里斯,谢谢你的回答, 第一个解决方案没有解决问题 - 实体需要从UObject继承。我不明白聚合如何解决这个问题。 对于第二种解决方案 - 我不认为你有实体的目的 - 实体是建筑和生活的接口,如果他们将它聚合而不是从它继承,实体的整个想法就是毫无意义。 我会看看这本书。谢谢。 – user2203448