Unreal Mode模式調(diào)用堆棧

此文章感凤,主要是為了記錄,在開發(fā)模式的插件(無圖標(biāo))中粒督,遇到的一些問題陪竿,調(diào)用堆棧過程中查看的函數(shù)層級(jí)關(guān)系。模式這塊的坑是比較大的屠橄,從模式的注冊(cè)族跛、激活、保存關(guān)卡后模式的激活狀態(tài)锐墙、新建關(guān)卡后模式的激活狀態(tài)礁哄、切換關(guān)卡后模式的激活狀態(tài)等各種各樣的情況。那么接下來會(huì)從模式的注冊(cè)與激活兩方面來闡述贮匕,其他的情況視每個(gè)人的開發(fā)功能背景而定姐仅。

Mode模式

1. 注冊(cè)Mode

Engine\Source\Editor\UnrealEd\Public\EditorModeRegistry.h

/**
 * 編輯器模式和工廠注冊(cè)表
 */
class FEditorModeRegistry

來看看具體的注冊(cè)函數(shù)

void FEditorModeRegistry::RegisterMode(FEditorModeID ModeID, TSharedRef<IEditorModeFactory> Factory)
{
    check(ModeID != FBuiltinEditorModes::EM_None);
    check(!ModeFactories.Contains(ModeID));

    ModeFactories.Add(ModeID, Factory);

    OnModeRegisteredEvent.Broadcast(ModeID);
    RegisteredModesChanged.Broadcast();
}

其中主要的關(guān)鍵點(diǎn)在于 往 ModeFactories 添加 模式的ID 和 工廠信息, 這里留一個(gè)彩蛋, 因?yàn)檫@個(gè)Map類型, 我們?cè)诩せ钅J降臅r(shí)候也會(huì)使用到.

注意:一般注冊(cè)模式會(huì)放在模塊的 StartupModule() 中。
需要注意的是注冊(cè)自定義的Mode的時(shí)間節(jié)點(diǎn)不一定就會(huì)比UE本身的Mode注冊(cè)的時(shí)間結(jié)點(diǎn)晚刻盐;畢竟我剛開始認(rèn)為掏膏,我自己定義的模式,注冊(cè)總在UE本身的Mode注冊(cè)之后敦锌,后來打斷點(diǎn)調(diào)用堆棧瞅了瞅馒疹,原來是自己錯(cuò)了。

2. 激活Mode

說到激活Mode乙墙,不得不說一個(gè)UE中強(qiáng)大的基礎(chǔ)頭文件颖变,那就是Editor.h,為什么說它呢听想?見下函數(shù)
Engine\Source\Editor\UnrealEd\Public\Editor.h

/**
 * 提供對(duì)關(guān)卡編輯器的FEditorModeTools的訪問
 */
UNREALED_API class FEditorModeTools& GLevelEditorModeTools();

GLevelEditorModeTools()函數(shù) new了一個(gè)FEditorModeTools 對(duì)象腥刹,并且將創(chuàng)建的對(duì)象作為返回值返回。那么這個(gè)FEditorModeTools類又可以干什么呢汉买?來看看它的定義:
Engine\Source\Editor\UnrealEd\Public\EditorModeManager.h

/**
 * 一個(gè)幫助程序類衔峰,用于存儲(chǔ)各種編輯器模式的狀態(tài)
 */
class UNREALED_API FEditorModeTools : public FGCObject, public FEditorUndoClient

一起看看在這個(gè)FEditorModeTools類中,有哪些函數(shù)

/*激活編輯器模式*/
void ActivateMode( FEditorModeID InID, bool bToggle = false );
/*禁用編輯器模式*/
void DeactivateMode(FEditorModeID InID);
/*如果傳入的編輯器模式處于活動(dòng)狀態(tài)蛙粘,則返回true*/
bool IsModeActive( FEditorModeID InID ) const;

再來看看類中有哪些屬性

/**活動(dòng)編輯器模式的列表*/
TArray< TSharedPtr<FEdMode> > ActiveModes;
/**我們可能會(huì)回收的先前活動(dòng)的編輯器模式列表*/
TMap< FEditorModeID, TSharedPtr<FEdMode> > RecycledModes;

看到這些成員函數(shù)和成員屬性, 顧名思義,這個(gè)類的功能有: 模式的激活垫卤、模式的禁用、判斷模式是否被激活出牧、激活模式的列表穴肘、激活模式的回收等等。

廢話說了這么多舔痕,目的就是為了要說评抚,在UE中豹缀,一般都是通過下面的方式去激活模式的:

GLevelEditorModeTools().ActivateMode(FEditorModeID);

下面就聊聊激活的兩種方式

(1)點(diǎn)擊圖標(biāo)激活

對(duì)于點(diǎn)擊圖標(biāo)而言,必定是要有圖標(biāo)的慨代,也就是說在模式那塊耿眉,存在自己定義的模式圖標(biāo),如上圖所示鱼响,那么就需要注冊(cè)一個(gè)有圖標(biāo)的模式,在注冊(cè)的時(shí)候组底,傳入 FSlateIcon 等參數(shù) 丈积,即可:
具體方法如下:

FEditorModeRegistry::Get().RegisterMode<自定義的Mode類名>(FEditorModeID, LOCTEXT(" ", " "), FSlateIcon(), true);

點(diǎn)擊圖標(biāo)激活的話,會(huì)經(jīng)過 點(diǎn)擊 Click事件债鸡,然后激活點(diǎn)擊的模式江滨。具體調(diào)用層級(jí)結(jié)構(gòu)如下:


(2)手動(dòng)激活

對(duì)于手動(dòng)激活而言,必定是沒有圖標(biāo)的厌均,也就是說在模式那塊唬滑,沒有自己定義的模式圖標(biāo),如上圖所示棺弊。那么如何去注冊(cè)一個(gè)沒有圖標(biāo)的模式呢晶密?在注冊(cè)的時(shí)候财松,直接省略 FSlateIcon 等參數(shù)邑时,使用注冊(cè)函數(shù)的默認(rèn)參數(shù)。具體方法如下:

注冊(cè)函數(shù)的默認(rèn)參數(shù)
FEditorModeRegistry::Get().RegisterMode<自定義的Mode類名>(FEditorModeID);

手動(dòng)激活的話锋边,就返回到剛剛在第二點(diǎn)中說的侈净,在 Editor.h 中的 GLevelEditorModeTools()函數(shù) 返回類型 FEditorModeTools 的 ActivateMode 函數(shù)尊勿,在想要激活的位置,去手動(dòng)調(diào)用一下這個(gè)函數(shù)即可畜侦。例如:

GLevelEditorModeTools().ActivateMode(FEditorModeID);

這兩種激活的方式元扔,其實(shí)都會(huì)調(diào)用到FEditorModeTools 的 ActiveMode函數(shù)。

那就來看看 旋膳,這個(gè)函數(shù)里到底有多少料吧澎语,當(dāng)然我不會(huì)把函數(shù)體全部搬過來,只說我認(rèn)為的一些關(guān)鍵代碼

  • ①是否是前面激活的回收模式溺忧,主要是為了 從A模式切換到B模式做準(zhǔn)備
  • ②開篇說的彩蛋 Map咏连,主要是判斷此模式是否是已經(jīng)注冊(cè)過的
  • ③bool值判斷 共同存活,欲激活的模式是否與其他的模式共同存在
  • ④ActiveModes 和 RecycledModes 的Add
  • ⑤CreatMode 與 構(gòu)造 還有 Enter 調(diào)用到了自定義模式的 構(gòu)造函數(shù) 和 Enter函數(shù)

3. 多種模式共同激活

我們可以看到 在ActiveMode 函數(shù)中鲁森,調(diào)用了 具體Mode的 IsCompatibleWith() 這樣的一個(gè)函數(shù)祟滴,查看這個(gè)函數(shù)的翻譯,這個(gè)函數(shù)就是為了讓多種模式共同存在而服務(wù)的歌溉。


Engine\Source\Editor\UnrealEd\Public\EdMode.h

virtual bool IsCompatibleWith(FEditorModeID OtherModeID) const { return false; }

如果想要共同存活垄懂,我們可以在繼承類中骑晶,重寫這個(gè)函數(shù),返回 true即可草慧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末桶蛔,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子漫谷,更是在濱河造成了極大的恐慌仔雷,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舔示,死亡現(xiàn)場(chǎng)離奇詭異碟婆,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)惕稻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門竖共,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人俺祠,你說我怎么就攤上這事公给。” “怎么了蜘渣?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵淌铐,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我蔫缸,道長(zhǎng)匣沼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任捂龄,我火速辦了婚禮释涛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘倦沧。我一直安慰自己唇撬,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布展融。 她就那樣靜靜地躺著窖认,像睡著了一般。 火紅的嫁衣襯著肌膚如雪告希。 梳的紋絲不亂的頭發(fā)上扑浸,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音燕偶,去河邊找鬼喝噪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛指么,可吹牛的內(nèi)容都是我干的酝惧。 我是一名探鬼主播榴鼎,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼晚唇!你這毒婦竟也來了巫财?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤哩陕,失蹤者是張志新(化名)和其女友劉穎平项,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悍及,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡葵礼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了并鸵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡扔涧,死狀恐怖园担,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情枯夜,我是刑警寧澤弯汰,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站湖雹,受9級(jí)特大地震影響咏闪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜摔吏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一鸽嫂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧征讲,春花似錦据某、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至滤祖,卻和暖如春筷狼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背匠童。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工埂材, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人汤求。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓楞遏,卻偏偏與公主長(zhǎng)得像茬暇,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子寡喝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348