-
Notifications
You must be signed in to change notification settings - Fork 6
Live Funcs zh TW
以「行為」為基礎的 UFunction 探索工具 — 掛勾 UObject::ProcessEvent,統計遊戲在一段錄製視窗內實際派發的每個 UFunction,讓真正的入口函式浮上檯面。
這是一個 Live ProcessEvent Call Profiler。它會掛勾 UObject::ProcessEvent,並在你按下 Start/Stop 的錄製視窗內,統計遊戲派發的每一個 UFunction。
它是 Interesting Functions 分頁(以「名稱」評分)的「行為」評分對應版本:與其靠函式名稱去猜,你在遊戲裡實際「執行一個動作」(開商店、衝刺、攻擊),本分頁就會顯示哪些 UFunction 真的被觸發,並加以排名,讓造成該動作的因果入口浮到最上方。它能找到那些名稱根本無從猜起、遊戲專屬的函式。
按下開始錄製會強制安裝 game-thread 的 ProcessEvent 掛勾,因此不需要事先做任何 invoke。
- Set Baseline — 先按 Start,靜置不動幾秒,按 Stop,然後點 Set Baseline。這會擷取一份「閒置」參考基準並開啟 Diff 模式。
- 錄製動作 — 按 Start,ALT-TAB 切回遊戲,只執行「一個」動作,ALT-TAB 切回來,按 Stop。
- 判讀差異 — 只在動作期間才觸發的列會被標記為 NEW(綠色);開啟 New/changed only 可隱藏每幀都會跑的 Tick 雜訊。
- Hide UI widgets — 開啟選單/商店會「建立」它的 widget,於是該 widget 自己的所有方法會同時觸發,把清單灌爆(在 Kind 欄標記為 "UI")。把它們隱藏後,剩下的是那個常駐的「開啟者」(位於 PlayerController/某個 UI-manager subsystem/某個 interaction component 上)。
- Hide events/delegates — On*/callback 類函式(在 Type 欄標記為 Event/Deleg)是引擎「對」遊戲觸發的反應,而不是你去「呼叫」以促成該動作的函式。把它們隱藏後,剩下的是命令式的 "Call" 函式。
- Earliest first — 一個動作的入口點會「早於」它所觸發的那些反應被呼叫,因此依呼叫順序(Order 欄,遞增)排序會讓真正的開啟者浮到最上方。這就是那個與名稱無關的因果訊號。
- 動手 — 對某一列點 Live,即可在 Live Walker 中以一個 live instance 開啟該函式(若無 live instance 則退回 Class Struct),你可以在那裡對它做 invoke;Name 則複製函式名稱。
上面的流程能找出某個一次性動作背後的函式。反過來,則能找出以重複 timer 觸發的函式——驅動冷卻、重生、持續傷害(DoT)tick,或週期性 AI 決策的那個 callback。
- 進入你想檢查的狀態(例如站在持續傷害的區域裡,或某個數值會依 timer 回復的地方)。
- 按 Start,然後靜置不動約 15–20 秒——長到足以讓你關注的最慢 timer 至少觸發 ~4 次。
- 按 Stop,然後開啟 Periodic only。
留下來的,就是在每幀 Tick 範圍之外、以規律節奏觸發的函式——在 Kind 欄標記為 Timer,並在 Period 欄顯示測得的間隔。本分頁會量測每個函式到達間隔的規律性,因此每幀的 Tick(以及不規律、由輸入驅動的函式)都會被濾掉。實際例子:在某款 UE4 遊戲上做一次閒置錄製,從 ~90 個函式中標記出一個 Blueprint 的 TryAttackEnable,其穩定維持在 ~325 ms——一個真正的 ~3 Hz timer。
限制: 只有綁定 UFUNCTION 的 timer 才看得到(一個 Blueprint 的 Set Timer by Event / Function Name,或一個 dynamic-delegate timer)。native C++ 的 SetTimer(this, &UClass::Method) 會直接呼叫它的 callback 並繞過 ProcessEvent,因此永遠不會出現在這裡——與本分頁其餘部分相同的根本限制。
- Order — 第一次觸發時在呼叫串流中的位置(越小=越早=越可能是入口點)
- Calls — 觸發次數
- Δ vs base — NEW,或當它比 baseline 觸發得更頻繁時顯示 +N
- Type — Event/Deleg/Call/native(取自 FunctionFlags)
- Kind — "Timer" 標記一個週期性 timer 節奏的 callback;"UI" 標記一個短命 widget 的方法
- Class
- Function
- Params
-
Period — 對週期性函式,測得的觸發間隔(例如
325 ms、1 s);否則留空
ProcessEvent 掛勾「只」能觀察到透過反射/Blueprint 派發的呼叫。一個 native C++ → native C++ 的呼叫對它是「不可見」的。
如果開啟 Hide events/delegates 後清單變空,代表該動作真正的入口點是 native(或是面板尚未完全出現 — 請持續錄製到它出現在畫面上為止)。這是以行為為基礎之探索的根本限制,不是 bug。
對大多數 UE 遊戲(以 Blueprint 驅動的玩法)而言,動作對應的函式可以直接被找到。實際例子:某款遊戲是透過 native C++ 呼叫開啟商店,因此只看得到它的 Blueprint 事件 callback(On*);另一款遊戲的商店則是一個以串流方式載入的選單關卡,能乾淨俐落地被找出來。
如果 Start 回報 PE 掛勾無法安裝(遊戲明明在跑,計數卻一直停在 0),代表 MinHook 無法在此行程中於 ProcessEvent 附近放置它的 trampoline。請切換到另一張地圖/場景後再按一次 Start — 關卡重新載入會重新洗牌記憶體,幾乎總能空出所需的空間。若問題持續,請重新啟動遊戲並重新注入。
這與遊戲是否受支援無關;同一款遊戲在一個全新/載入方式不同的行程中通常都能正常掛勾。再次點 Start 也會重試安裝。
錄製為選擇性啟用,閒置時幾乎沒有成本;離開本分頁會自動停止任何進行中的錄製。本分頁僅走 pipe(沒有 CE Lua/.CT)。清單上方有一個關鍵字篩選框(space = AND,同時比對 function 與 class 名稱)可縮小清單範圍。
- Interesting Functions & Properties — 以名稱為基礎的對應版本
- Live Walker — 對一個 live instance 呼叫已找到的函式
- Console — UFUNCTION(exec) 指令探索