2017-10-13 7 views
2

私はUnreal Engine 4でゲームをプログラミングしています。エンジンはあなたにいくつかのクラスを提供します。質問では、クラスの目的ではなく、クラスの関連性にもっと焦点を当てます。
ACharacter - > APawn - > AActor - > ... - >:( " - - >" が継承するために関し例えばA> Bは、AがBから継承することを意味する)より良いクラスデザイン

エンジンのクラスは次のようですUObject
"..."は、単にクラスを解除しないクラスです。
UObjectクラスはエンジンのメインクラスであり、エンジンのほとんどすべてのクラスとゲームでは最終的にフォームUObjectを継承します。さらに、必要な多くの機能を提供します。
継承はない仮想継承です。これは将来にとって重要なことです。エンジンのクラスは編集できません。 Buidling、リビングとエンティティ:

私のゲームでは3つの主なクラスがあります。
ビルから 生活が両方 ACharacterとエンティティ

enter image description here

から継承両方 AActorとエンティティ
を継承し、私は私のコードを複製することなく、ビルや生活を関係するエンティティクラスを作成しました。例えば、Livingクラスは別のLivingまたはBuildingを攻撃する機能を提供する必要があります。だから私はちょうど2つの "AttackLiving"の機能を作成することができます。これはLivingターゲットパラメータと "Target AttackBuilding"機能を持ち、両方の機能が全く同じ機能を持ちます。代わりにEntityクラスを作成したので、「AttackEntity」という1つの関数しか持たないでしょう。もちろん、これは単なる一例です。私はEntityクラスをコード全体に使用しているので、LivingとBuildingの両方をワンショットで参照できます。

問題はEntityクラスから始まります。私は実際にそれを作成したときに1年前に間違いを犯しました。私はこれを考えていません。問題は、エンティティがUObjectから継承しないことです。ここでも、UObjectクラスはエンジンのメインクラスであり、必要な多くの機能を提供します。エンティティはUObjectから継承しないので、必要な関数にアクセスすることはできません。

仮想継承は、ここでは動作しませんので、私はUObjectまたはAActorからのエンティティーinheritesをすることはできません。私は可能な解決策の数で考えている

(再びエンジンクラスの継承は、仮想継承ではありません)。そのうちの1つは、エンティティの種類に依存してビルドまたはリビングにエンティティをキャストすることができ、UObjectの機能を使用することができるということでした。しかし、これは非常に醜い解決策であり、エンティティのパープルを対照しています - リビングとビルディングの個性には関係しません。

また、UObjectクラスのエンティティにポインタを置くことを考えましたが、これは非常に醜い解決策であり、すべての問題を解決するわけではありません。 Instanceの別の問題(これはUObjectから継承しない): "TWeakObjectPtr"と呼ばれるテンプレートクラスがあり、これはテンプレートにクラスを取得し、それに対するポインタを作成し、ポインタが他の場所で解放されていないことを確認しますエンジンによって。

TWeakObjectPtr<Entity> entityPointer; 

問題はTWeakObjectPtrはクラスがUObjectからテンプレートinheritesに与えられたことを確認し、そしてもちろん、それは私がTWeakObjectPtrを使用することはできませんではないということです。

結論として、主な問題は、エンティティがUObjectの継承ではないということです。しかし、私はそれが必要なので、私は一緒に生活と建物を関連付けることができます。

エンティティを保持するソリューションを提供できるのであれば、私は大好きです。前もって感謝します!

+0

UObjectは、UE4の基本クラスです。すべてがUObjectから継承する必要があります。これを実現するためにEntityクラスを再作成することをお勧めします。それ以外の場合は、これまでどおり動作するとは思われません。 –

+0

また、Game Developmentフォーラムでは、これに関する多くの助けが得られるかもしれません:https://gamedev.stackexchange.com/ –

+0

@ethancodes私はそれを知っていますが、仮想継承が機能しないため、UObjectから継承できませんここに。この問題の実際の解決策はありますか? – user2203448

答えて

1

私は一度もunrealエンジンを使ったことはありませんが、下のアイデアのいくつかはとにかく役に立つと思っています。状況を改善する

1つの方法は、2つのオブジェクト階層間の継承のリンクを解除することです - あなたとエンジンの:*--集約(または組成物)を意味

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

。 クラスはエンジンクラスを継承しません。代わりに、適切なエンジンオブジェクトを集約します。

EntityUObjectを返し、サブクラスが適切AActor又はACharacterオブジェクト が返される仮想メソッドgetUnreal()を有することができます。 Entityを使用すると、エンジンオブジェクトを直接取得することはできますが、entiry->getUnreal()を呼び出すことで取得できます。

周りの他の方法は、エンジンクラスから自分のクラスを継承し、「エンティティ」は集約された行動の代わりに、基本クラスにすることができます:ここでは

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

どこにあなたのBuilding/Livingを使用しますエンジンオブジェクトが必要ですが、独自のロジックを参照する場合は、building->getEntity()のようなものを使用します。 異なるEntityサブクラスを使用して、BuildingおよびLivingの動作を実装することができます。

また、Design Patterns: Elements of Reusable Object-Oriented Software本を確認することをお勧めします。Structural Patternsの章は、より多くのアイディアを見つけるのに役立ちます。

+0

ちょっとボリス、ありがとう、 最初の解決策は問題を解決しません - エンティティはUObjectから継承する必要があります。集約がこの問題をどのように解決するかはわかりません。 第2の解決策については、私はEntityの目的をundrestoodしているとは思わない - EntityはBuilding and Livingのインターフェースです。Entityのアイデア全体が無意味になるだけでなく、Inheriteの代わりに集計するとします。 この本を見ていきます。ありがとうございました。 – user2203448