UE4中,玩家的表示通常涉及以下幾個類:
-
APlayerController: 代表玩家的控制邏輯,處理輸入等。
-
APawn: 代表玩家在世界中的實體(比如一個角色、一輛車)。APlayerController?控制一個?APawn。
-
ACharacter:?APawn?的一個特化子類,用于可動的人形角色。
-
APlayerState: 存儲玩家的網絡同步狀態信息,如玩家名、得分等。
-
ULocalPlayer: 代表本地玩家的實例,通常在?UGameInstance?中。
以下是從?UWorld?出發找到當前玩家信息的幾條常見路徑:
主要路徑建議:
路徑 1: 通過?UGameInstance?和?ULocalPlayer?(最常用)
這是獲取本地玩家信息最直接和常用的方式。
-
UWorld?->?OwningGameInstance?(所屬游戲實例):
-
UWorld?對象內部會有一個指向其所屬?UGameInstance?的指針。你需要在這個內存查看器中找到?UWorld?的?OwningGameInstance?成員。它的類型通常是?UGameInstance*。
-
記下這個?UGameInstance*?的地址。
-
-
UGameInstance?->?LocalPlayers?(本地玩家數組):
-
跳轉到上一步得到的?UGameInstance?地址,查看其成員。
-
UGameInstance?有一個名為?LocalPlayers?的?TArray<ULocalPlayer*>?成員。這是一個?ULocalPlayer?指針的數組。
-
對于單人游戲或第一個本地玩家,通常是?LocalPlayers[0]。記下這個?ULocalPlayer*?的地址。
-
-
ULocalPlayer?->?PlayerController?(玩家控制器):
-
跳轉到?ULocalPlayer?地址,查看其成員。
-
ULocalPlayer?對象有一個指向?APlayerController*?的成員,通常就叫?PlayerController。記下這個?APlayerController*?的地址。
-
-
APlayerController?->?Pawn?或?Character?(玩家實體):
-
跳轉到?APlayerController?地址,查看其成員。
-
APlayerController?有一個指向其當前控制的?APawn*?的成員。這個成員變量的名字可能是?Pawn,或者在更新的版本/特定情況下是?AcknowledgedPawn。
-
如果這個?Pawn?是一個角色,它的實際類型會是?ACharacter*?(或其子類)。
-
-
從?APawn/ACharacter?獲取信息:
-
位置 (Location):
-
APawn?->?RootComponent?(類型?USceneComponent*) ->?RelativeLocation?(相對坐標,?FVector) 或通過其?ComponentToWorld?Transform 獲取世界坐標。
-
在內存查看器中,你需要先找到?RootComponent?指針,然后跳轉到該組件的內存,再找到位置相關的成員。
-
-
生命值 (Health):
-
這通常是游戲自定義的變量,可能直接在?APawn、ACharacter?或?APlayerState?中。你需要查找名為?Health,?CurrentHealth,?HP?之類的浮點型或整型成員。
-
-
其他信息: 速度、朝向等也可以從?APawn?或其組件中找到。
-
路徑 2: 通過?GameState?(適用于獲取所有玩家狀態,包括本地玩家)
-
UWorld?->?GameState:
-
UWorld?對象有一個成員指向當前的?AGameStateBase*?(或其子類,如?AGameState*)。在你的截圖中,這個成員沒有直接顯示偏移量,但它肯定是?UWorld?的一個成員。你需要找到它。
-
記下?AGameStateBase*?的地址。
-
-
AGameStateBase?->?PlayerArray:
-
跳轉到?AGameStateBase?地址,查看其成員。
-
它有一個?PlayerArray?成員,這是一個?TArray<APlayerState*>,包含了游戲中所有玩家的?APlayerState。
-
-
APlayerState?->?PawnPrivate?或?PlayerController:
-
從?PlayerArray?中取出你關心的玩家的?APlayerState*?(比如?PlayerArray[0]?如果是第一個玩家)。
-
APlayerState?有一個?PawnPrivate?成員,它是一個?APawn*,指向該玩家狀態對應的Pawn。
-
或者,APlayerState?的?Owner?通常是對應的?APlayerController。從?APlayerController?再獲取?Pawn。
-
-
從?APawn?獲取信息: (同路徑1的步驟5)
-
從?APlayerState?獲取信息:
-
玩家名 (PlayerName):?APlayerState?通常有?PlayerName?(類型?FString) 或?GetPlayerName()?相關的成員/函數。
-
分數 (Score):?Score?(通常是?float)。
-
其他網絡同步的狀態。
-
路徑 3: 通過?UWorld?的?PersistentLevel?中的?Actors?數組 (較繁瑣)
你的截圖顯示了?+0030 ULevel* PersistentLevel。
-
UWorld?->?PersistentLevel:
-
從?UWorld?的地址(0x505998D0)加上偏移量?+0x0030,得到?PersistentLevel?的地址。
-
-
ULevel?->?Actors:
-
跳轉到?PersistentLevel?的地址,查看其成員。
-
ULevel?有一個?Actors?成員,它是一個?TArray<AActor*>,包含了該關卡中所有的 Actor。
-
-
遍歷?Actors?數組:
-
你需要遍歷這個?Actors?數組。對每個?AActor*:
-
檢查其類型是否為?APlayerController?(或游戲特定的玩家控制器子類)。這可能需要查看對象的虛函數表 (vtable) 或其他類型信息。
-
如果是?APlayerController,再檢查它是否是本地玩家的控制器 (例如,通過?IsLocalController()?對應的成員變量或標志位)。
-
-
一旦找到目標?APlayerController,后續步驟同路徑1的步驟4和5。
-
建議步驟:
-
首選路徑1或路徑2,因為它們更直接。你需要耐心地在內存查看器中展開指針,尋找我上面提到的成員變量名。
-
注意UE4的?TArray?結構。它通常包含一個指向數據塊的指針、數組當前的元素數量 (ArrayNum) 和數組分配的容量 (ArrayMax)。你需要先找到數據塊的指針,然后才能訪問數組元素。
-
變量名可能會因UE版本或游戲特定修改而略有不同,但基本概念(如?PlayerController?控制?Pawn)是不變的。