2017-10-13 161 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