Unreal插件開發(fā)的一些技巧

閱讀此文章之前捞高,建議先看下入門版:http://www.reibang.com/p/ec0ae889f417
首先跟衅,UE本身提供了很多拓展接口攀芯,基本可以滿足日常插件開發(fā)的需要蒸殿,我舉些例子:

  1. LevelEditorModule.GetToolBarExtensibilityManager()可以拓展關(guān)卡編輯器的工具欄,GetMenuExtensibilityManager()可以拓展菜單欄
  2. GEditor->GetEditorSubsystem<UAssetEditorSubsystem>()->OnAssetOpenedInEditor(),可以監(jiān)聽UE中终畅,任意編輯器打開的事件籍胯。
  3. FCoreUObjectDelegates::OnObjectPropertyChanged可以監(jiān)聽任意Object,任意屬性的變化事件离福。
    UE中類似上述三個示例的接口還有茫茫多杖狼,歡迎大家繼續(xù)自行探索,不再贅述妖爷。

但是蝶涩,上述這些正道接口,也只能覆蓋90%的開發(fā)需求絮识。那么剩下10%如何處理呢子寓?

技巧一: 插件中include UE的Private頭文件

public目錄中頭文件引用方法太入門栈妆,本文不再贅述冠句。

private目錄中的頭文件引用方法,例如:Unreal\Engine\Source\Editor\AnimationBlueprintEditor\Private\AnimationBlueprintEditor.h

首先八秃,在當前插件模塊的build.cs文件中添加Private目錄:

var EngineDir = Path.GetFullPath(Target.RelativeEnginePath);

PrivateIncludePaths.AddRange(
    new string[] {
      Path.Combine(EngineDir, "Source/Editor/AnimationBlueprintEditor/Private/"),
   }
);

然后在某個源碼文件垃它,直接include:

// 用尖括號也可以
#include "AnimationBlueprintEditor.h"

使用private頭文件后鲜屏,virtual或inline函數(shù),你都可以直接調(diào)用了国拇。

其他函數(shù)可能會報鏈接錯誤洛史。咋辦呢?
很簡單酱吝,把這個函數(shù)的實現(xiàn)copy到你的cpp里即可也殖。

技巧二:訪問private或protected變量的官方辦法。

UE官方其實提供了一種訪問private變量的方法:所有標記了UPROPERTY的變量都是可以通過正道訪問的务热。
例如, FAnimLinkableElement的SlotIndex變量:

USTRUCT()
struct FAnimLinkableElement
{
    GENERATED_USTRUCT_BODY()
    protected:

    /** The slot index we are currently using within LinkedMontage */
    UPROPERTY(EditAnywhere, Category=AnimLink)
    int32 SlotIndex;
};

訪問SlotIndex的方法如下:

int32* GetSlotIndex(void *pAnimLinkableElement) {
    static UScriptStruct* Struct = FindObjectSafe<UScriptStruct>(ANY_PACKAGE, TEXT("AnimLinkableElement"));
    auto Prop = Struct->FindPropertyByName(TEXT("SlotIndex"));
    check(Prop);
    return Prop->ContainerPtrToValuePtr<int32>(pAnimLinkableElement);
}

另外忆嗜,不標記UPROPERTY的私有變量,其實也可以訪問的崎岂,前提是變量的offset計算正確捆毫,這個太黑,就不提了冲甘。

技巧三: 實時替換虛函數(shù)

我業(yè)余時間绩卤,寫了個運行時,替換virtual函數(shù)的程序江醇,鏈接在此:https://github.com/xiaoyaoliu/vimrc/tree/master/documents/cpp_samples/ReplaceVirtualFunction

例如濒憋,在動畫藍圖中的Slot動畫節(jié)點的右鍵菜單中添加新的UI入口。

    #include <ReplaceVirtualFunction/ReplaceVirtualFunction.h>
    // 開始替換
    {
    // Register command list
        auto obj = UAnimGraphNode_Slot::StaticClass()->GetDefaultObject();
        // Add context menu for UAnimGraphNode_Slot. 用插件中的GetNodeContextMenuActions_AnimNodeSlot方法陶夜,替換unreal的UAnimGraphNode_Slot::GetNodeContextMenuActions
        ReplaceVirtualWithNonVirtualMember(obj, UAnimGraphNode_Slot::GetNodeContextMenuActions, FHookAnimBlueprintEditor::GetNodeContextMenuActions_AnimNodeSlot);
    }
    
    // 取消替換
    {
        RecoverReplace(FHookAnimBlueprintEditor::GetNodeContextMenuActions_AnimNodeSlot);
    }

// 函數(shù)聲明: HookAnimBlueprintEditor.h
struct FHookAnimBlueprintEditor
{
void GetNodeContextMenuActions_AnimNodeSlot(class UToolMenu* Menu, class UGraphNodeContextMenuContext* Context);
};
    
// 函數(shù)實現(xiàn): HookAnimBlueprintEditor.cpp
void FHookAnimBlueprintEditor::GetNodeContextMenuActions_AnimNodeSlot(class UToolMenu* Menu, class UGraphNodeContextMenuContext* Context)
{
    UAnimGraphNode_Slot* slot = (UAnimGraphNode_Slot*)(this);
    // 調(diào)用下被替換掉的函數(shù)凛驮。從而保證只增加,不刪除原有邏輯律适。
    SuperVirtualCall(slot->GetNodeContextMenuActions(Menu, Context));
    if (!Context->bIsDebugging)
    {
        // add an option to Play Animation Asset In Slot 
        {
            FToolMenuSection& Section = Menu->AddSection("AnimGraphNodeSlot", LOCTEXT("SlotHeading", "Slot"));
        
        }
    }

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辐烂,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子捂贿,更是在濱河造成了極大的恐慌纠修,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件厂僧,死亡現(xiàn)場離奇詭異扣草,居然都是意外死亡,警方通過查閱死者的電腦和手機颜屠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門辰妙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人甫窟,你說我怎么就攤上這事密浑。” “怎么了粗井?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵尔破,是天一觀的道長。 經(jīng)常有香客問我浇衬,道長懒构,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任耘擂,我火速辦了婚禮胆剧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘醉冤。我一直安慰自己秩霍,他們只是感情好,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布蚁阳。 她就那樣靜靜地躺著前域,像睡著了一般。 火紅的嫁衣襯著肌膚如雪韵吨。 梳的紋絲不亂的頭發(fā)上匿垄,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機與錄音归粉,去河邊找鬼椿疗。 笑死,一個胖子當著我的面吹牛糠悼,可吹牛的內(nèi)容都是我干的届榄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼倔喂,長吁一口氣:“原來是場噩夢啊……” “哼铝条!你這毒婦竟也來了靖苇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤班缰,失蹤者是張志新(化名)和其女友劉穎贤壁,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體埠忘,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡脾拆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了莹妒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片名船。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖旨怠,靈堂內(nèi)的尸體忽然破棺而出渠驼,到底是詐尸還是另有隱情,我是刑警寧澤鉴腻,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布渴邦,位于F島的核電站,受9級特大地震影響拘哨,放射性物質(zhì)發(fā)生泄漏谋梭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一倦青、第九天 我趴在偏房一處隱蔽的房頂上張望瓮床。 院中可真熱鬧,春花似錦产镐、人聲如沸隘庄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丑掺。三九已至,卻和暖如春述雾,著一層夾襖步出監(jiān)牢的瞬間街州,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工玻孟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留唆缴,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓黍翎,卻偏偏與公主長得像面徽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容

  • UE中的插件趟紊,重點在.Build.cs文件和.uplugin文件氮双,如果在這兩者中,再分主次的話霎匈,那我選.Build...
    Mr_約科閱讀 5,298評論 0 2
  • 本文章轉(zhuǎn)載自 智傷帝的個人博客 - 原文鏈接 前言 ??上個月的這個時候我寫了一篇文章關(guān)于如何嵌入 PySide ...
    智傷帝閱讀 693評論 0 0
  • 前言 在前倆篇文章中戴差,我與大家分享了 UE4 開發(fā)如何配置 Xcode 的調(diào)試環(huán)境以及如何實現(xiàn) UE4 引擎的按鈕...
    iOS發(fā)呆君閱讀 1,810評論 0 0
  • 16宿命:用概率思維提高你的勝算 以前的我是風險厭惡者,不喜歡去冒險唧躲,但是人生放棄了冒險造挽,也就放棄了無數(shù)的可能碱璃。 ...
    yichen大刀閱讀 6,049評論 0 4
  • 公元:2019年11月28日19時42分農(nóng)歷:二零一九年 十一月 初三日 戌時干支:己亥乙亥己巳甲戌當月節(jié)氣:立冬...
    石放閱讀 6,879評論 0 2