UE4,UE5 世界坐标转屏幕坐标
#include "pch.h"
#include "世界坐标转屏幕坐标.h"
#include"TGame.h"
//-----------项目代码-------------------
#pragma once
ULONG64 offset_OwningGameInstance = 0x290;
ULONG64 offset_ULocalPlayer = 0x38;//本地角色
ULONG64 offset_UPlayerController = 0x30;//角色控制器
bool WorldToScreenEx(IN FVector3 WorldLocation, OUT FVector3* Screenlocation);
//
//UINT_PTR TGame::GetGWorld()
//{
// return RP(GetPByPdbName("GWorld") + 0);
//}
UINT_PTR TGame::GetGameInstance()
{
//[+0x290]
return RP(GetGWorld() + offset_OwningGameInstance);
}
UINT_PTR TGame::GetLocalPlayer()
{
// [[[[+0x290]+38]+30]+0*8]
returnRP(RP(GetGameInstance() + offset_ULocalPlayer) + 0x00);
}
// 函数类型指针 type_ProjectWorldLocationToScreen
typedef bool(__thiscall* type_ProjectWorldLocationToScreen)(
UINT_PTR vrcx_this, // PlayerController*
FVector3* WorldLocation, // IN 待转换的世界坐标
FVector3* ScreenLocation, // OUT 返回转换后的屏幕坐标
bool bPlayerViewportRelative //IN是否相对玩家视口 false
);
//需要主线程 里调用 bool WorldToScreenEx(IN FVector3 WorldLocation, OUT FVector3& Screenlocation)
//void TGame::WorldToScreen(IN float* worldpos3, OUT float* screenpos2, bool bPlayerViewportRelative,BOOL isEx)
void TGame::WorldToScreen(IN FVector3* worldpos3, OUT FVector3* screenpos2, bool bPlayerViewportRelative, BOOL isEx)
{
if (isEx)
{
WorldToScreenEx(*worldpos3, screenpos2);
return;
}
printf("内置 pcall_worldtoScreen line=%d \r\n", __LINE__);
type_ProjectWorldLocationToScreen pcall_worldtoScreen = (type_ProjectWorldLocationToScreen)GetPByPdbName("APlayerController::ProjectWorldLocationToScreen");
//获取 PlayerController
UINT_PTR vrcx_PlayerController = TGame::GetPlayerController();
//printf("pcall_worldtoScreen=%p,GetPlayerController()=%zX \r\n", pcall_worldtoScreen, vrcx_PlayerController);
//LogFileW("c:\\log\\遍历怪物数组draw.txt", L"pcall_worldtoScreen=%zX,GetAPlayerController()=%zX \r\n", pcall_worldtoScreen, vrcx_PlayerController);
if (pcall_worldtoScreen && vrcx_PlayerController)
{
//需要主线程调用
pcall_worldtoScreen(
vrcx_PlayerController, // PlayerController指针
worldpos3,// IN 待转换的世界坐标
screenpos2,// OUT 返回转换后的屏幕坐标
bPlayerViewportRelative);//=false);
}
else
{
//MessageBoxA(0, __FILE__, "世界坐标转屏幕坐标 错误", MB_OK);
printf("错误 pcall_worldtoScreen=%p,GetAPlayerController()=%zX \r\n", pcall_worldtoScreen, vrcx_PlayerController);
}
}
/*
PlayerController.h
typedef bool (__thiscall* type_ProjectWorldLocationToScreen)(
UINT_PTR vrcx_this,
float* WorldLocation, // IN 待转换的世界坐标
float* ScreenLocation, // OUT 返回转换后的屏幕坐标
bool bPlayerViewportRelative //IN是否相对玩家视口
);
bool PlayerController::ProjectWorldLocationToScreen(FVector WorldLocation, FVector2D& ScreenLocation, bool bPlayerViewportRelative = false) const;
UGameInstance::GetFirstLocalPlayerController
00007FF649ADDA60 | 48:895C24 08 | mov qword ptr ss:,rbx | gameinstance.cpp:555,
00007FF649ADDA65 | 48:897424 10 | mov qword ptr ss:,rsi |
00007FF649ADDA6A | 57 | push rdi |
00007FF649ADDA6B | 48:83EC 30 | sub rsp,30 |
00007FF649ADDA6F | 8B71 40 | mov esi,dword ptr ds: | gameinstance.cpp:556
00007FF649ADDA72 | 48:8BF9 | mov rdi,rcx |[+0x290]
00007FF649ADDA75 | 33DB | xor ebx,ebx | gameinstance.cpp:556
00007FF649ADDA77 | 3BDE | cmp ebx,esi |
00007FF649ADDA79 | 74 6C | je shootergame.7FF649ADDAE7 |
00007FF649ADDA7B | 8B57 40 | mov edx,dword ptr ds: |
00007FF649ADDA7E | 33C9 | xor ecx,ecx |
00007FF649ADDA80 | 3BDA | cmp ebx,edx |
00007FF649ADDA82 | 0F9CC1 | setl cl |
00007FF649ADDA85 | 33C0 | xor eax,eax |
00007FF649ADDA87 | 85DB | test ebx,ebx |
00007FF649ADDA89 | 0F99C0 | setns al |
00007FF649ADDA8C | 85C8 | test eax,ecx |
00007FF649ADDA8E | 75 28 | jne shootergame.7FF649ADDAB8 |
00007FF649ADDA90 | 895424 28 | mov dword ptr ss:,edx |
00007FF649ADDA94 | 4C:8D0D 65C61201 | lea r9,qword ptr ds:[<L"Array index out of bounds: %i fr"...>] | 00007FF64AC0A100:L"Array index out of bounds: %i from an array of size %i"
00007FF649ADDA9B | 48:8D0D CEC61201 | lea rcx,qword ptr ds:[<"(Index >= 0) & (Index < ArrayNum"...>] | 00007FF64AC0A170:"(Index >= 0) & (Index < ArrayNum)"
00007FF649ADDAA2 | 48:8D15 D7BF1201 | lea rdx,qword ptr ds:[<"F:\\build\\LostIsland\\Engine\\Sourc"...>] | 00007FF64AC09A80:"F:\\build\\LostIsland\\Engine\\Source\\Runtime\\Core\\Public\\Containers\\Array.h"
00007FF649ADDAA9 | 41:B8 3C020000 | mov r8d,23C |
00007FF649ADDAAF | 895C24 20 | mov dword ptr ss:,ebx |
00007FF649ADDAB3 | E8 A8DE84FF | call <shootergame.public: static void __cdecl FDebug::AssertFailed(char const *, char |
00007FF649ADDAB8 | 48:8B47 38 | mov rax,qword ptr ds: | [[+0x290]+38]
00007FF649ADDABC | 48:63CB | movsxd rcx,ebx |
00007FF649ADDABF | 48:8B04C8 | mov rax,qword ptr ds: //player 数组? [[[+0x290]+38]+0*8]
00007FF649ADDAC3 | 48:85C0 | test rax,rax | gameinstance.cpp:558
00007FF649ADDAC6 | 74 07 | je shootergame.7FF649ADDACF |
00007FF649ADDAC8 | 48:8378 30 00 | cmp qword ptr ds:,0 |
00007FF649ADDACD | 75 04 | jne shootergame.7FF649ADDAD3 |
00007FF649ADDACF | FFC3 | inc ebx | gameinstance.cpp:556
00007FF649ADDAD1 | EB A4 | jmp shootergame.7FF649ADDA77 |
00007FF649ADDAD3 | 48:8B40 30 | mov rax,qword ptr ds: | rax = [[[[+0x290]+38]+0*8]+30]
00007FF649ADDAD7 | 48:8B5C24 40 | mov rbx,qword ptr ss: | gameinstance.cpp:567
00007FF649ADDADC | 48:8B7424 48 | mov rsi,qword ptr ss: |
00007FF649ADDAE1 | 48:83C4 30 | add rsp,30 |
00007FF649ADDAE5 | 5F | pop rdi |
00007FF649ADDAE6 | C3 | ret |
00007FF649ADDAE7 | 48:8B5C24 40 | mov rbx,qword ptr ss: |
00007FF649ADDAEC | 48:8B7424 48 | mov rsi,qword ptr ss: |
00007FF649ADDAF1 | 33C0 | xor eax,eax |
00007FF649ADDAF3 | 48:83C4 30 | add rsp,30 |
00007FF649ADDAF7 | 5F | pop rdi |
00007FF649ADDAF8 | C3 | ret |
APlayerController* UGameInstance::GetFirstLocalPlayerController(const UWorld* World) const
{
if (World == nullptr)
{
for (ULocalPlayer* Player : LocalPlayers)
{
// Returns the first non-null UPlayer::PlayerController without filtering by UWorld.
if (Player && Player->PlayerController)
{
// return first non-null entry
return Player->PlayerController;
}
}
}
else
{
// Only return a local PlayerController from the given World.
for (FConstPlayerControllerIterator Iterator = World->GetPlayerControllerIterator(); Iterator; ++Iterator)
{
APlayerController* PC = Iterator->Get();
if (PC && PC->IsLocalController())
{
return PC;
}
}
}
// didn't find one
return nullptr;
}
*/
#include"pch.h"
#include<Windows.h>
#include"世界坐标转屏幕坐标.h"
#define PI 3.14159265358979323846264338327950288419716939937510
//矩阵
D3DXMATRIX Matrix(FVector3 rot, FVector3 origin = FVector3(0, 0, 0))
{
float radPitch = (rot.x * float(PI) / 180.f);
float radYaw = (rot.y * float(PI) / 180.f);
float radRoll = (rot.z * float(PI) / 180.f);
float SP = sinf(radPitch);
float CP = cosf(radPitch);
float SY = sinf(radYaw);
float CY = cosf(radYaw);
float SR = sinf(radRoll);
float CR = cosf(radRoll);
D3DMATRIX matrix;
matrix.m = CP * CY;
matrix.m = CP * SY;
matrix.m = SP;
matrix.m = 0.f;
matrix.m = SR * SP * CY - CR * SY;
matrix.m = SR * SP * SY + CR * CY;
matrix.m = -SR * CP;
matrix.m = 0.f;
matrix.m = -(CR * SP * CY + SR * SY);
matrix.m = CY * SR - CR * SP * SY;
matrix.m = CR * CP;
matrix.m = 0.f;
matrix.m = origin.x;
matrix.m = origin.y;
matrix.m = origin.z;
matrix.m = 1.f;
return matrix;
}
/*
//相机坐标
AShooterPlayerController=[[[[+290]+38]+0]+30]
PlayerCameraManager =
// [[[[+290]+38]+0]+30]+4F0
+480 //3、FOV视角 float [[[[[+290]+38]+0]+30]+4F0]+480 真实视角 修改有效
+4D8 //1、相机坐标float pos3 FVector3 [[[[[+290]+38]+0]+30]+4F0]+4D0+8
+4E4 //2、相机旋转坐标 float pos [[[[[+290]+38]+0]+30]+4F0]+4D0+8+C
+500 //2、相机旋转坐标 float pos
+500 //3、FOV视角 float [[[[[+290]+38]+0]+30]+4F0]+4D0+8+28 可读
+C40 //3、FOV视角 float [[[[[+290]+38]+0]+30]+4F0]+C40 可读
+FE8 //3、FOV视角 float [[[[[+290]+38]+0]+30]+4F0]+FE8 可读
*/
// UGameInstance::GetFirstLocalPlayerController//PlayerController::ProjectWorldLocationToScreen
UINT_PTR TGame::GetPlayerController()
{
UINT_PTR ULocalPlayer = GetLocalPlayer();
//[[[[+0x290]+38]+0*8]+30]
return RP(ULocalPlayer + offset_UPlayerController);
}
UINT_PTR TGame::GetPlayerCameraManager()
{// [[[[[+290]+38]+0]+30]+4F0]
//return RP(RP(RP(RP(RP(GetGWorld() + 0x290) + 0x38) + 0x00) + 0x30) + 0x4F0);
return RP(GetPlayerController() + 0x4F0);
}
FVector3 TGame::GetCameraRotation()
{
//[[[[[+290]+38]+0]+30]+4F0]+4D8
UINT_PTR pbase = GetPlayerCameraManager() + 0x4D8;
FVector3 Rotation = RP<FVector3>(pbase);
return Rotation;
}
FVector3 TGame::GetCameraLocation()
{
//[[[[[+290]+38]+0]+30]+4F0]+4E4
UINT_PTR pbase = GetPlayerCameraManager() + 0x4E4;
FVector3 Rotation = RP<FVector3>(pbase);
return Rotation;
}
float TGame::GetFov()
{ //FOV弧度
//+500 //3、FOV视角 float [[[[[+290]+38]+0]+30]+4F0]+4D0+8+28 可读
float Fov = 0;
UINT_PTR pbase = GetPlayerCameraManager() + 0x500;
Fov = RP<float>(pbase);
return Fov;
}
/*
GSystemResolution
+00 分辩率宽度 x int
+04 分辩率高度 y int
*/
INT64 GetResolution(OUT int& x, int& y)
{
UINT_PTR pbase_GetResolution = GetPByPdbName("GSystemResolution");
INT64 pos = RP<INT64>(pbase_GetResolution + 0x00);
//y = RP<int>(pbase_GetResolution+0x04);
x = pos && 0xFFFFFFFF;
y = pos >> 32;
return pos;
}
INT64 TGame::GetResolution(OUT int& x, int& y)
{
UINT_PTR pbase_GetResolution = GetPByPdbName("GSystemResolution");
INT64 pos = RP<INT64>(pbase_GetResolution + 0x00);
//y = RP<int>(pbase_GetResolution+0x04);
x = GetResolutionWidth();
y = GetResolutionHeight();
return pos;
}
//判断坐标是否在屏幕内
INT64 TGame::在屏幕内(int x, int y)
{
int w, h;
GetResolution(w, h);
if((abs(x) <= w) && (abs(y) <= h))
{
return true;
}else
{
return false;
}
}
int TGame::GetResolutionWidth()
{
UINT_PTR pbase_GetResolution = GetPByPdbName("GSystemResolution");
int pos = RP<int>(pbase_GetResolution + 0x00);
return pos;
}
int TGame::GetResolutionHeight()
{
UINT_PTR pbase_GetResolution = GetPByPdbName("GSystemResolution");
int pos = RP<int>(pbase_GetResolution + 0x04);
return pos;
}
int TGame::窗口客户端中心X()
{
int pos = GetResolutionWidth();
return pos / 2;
}
int TGame::窗口客户端中心Y()
{
int pos = GetResolutionHeight();
return pos / 2;
}
/*
//本地角色 APlayerController* UShooterLocalPlayer= [[[+290]+38]+0]
//这个接口 可以重点关注
bool APlayerController::ProjectWorldLocationToScreen(
FVector WorldLocation, // IN 待转换的世界坐标
FVector2D& ScreenLocation, // OUT 返回转换后的屏幕坐标
bool bPlayerViewportRelative //IN是否相对玩家视口
)
{
return UGameplayStatics::ProjectWorldToScreen(this, WorldLocation, ScreenLocation, bPlayerViewportRelative);
}
*/
//世界坐标转屏幕坐标
bool TGame::WorldToScreenEx(IN FVector3 WorldLocation, OUT FVector3* Screenlocation)
{
//获取相机旋转坐标
FVector3 Rotation = GetCameraRotation();
D3DMATRIX tempMatrix = Matrix(Rotation);
FVector3 vAxisX, vAxisY, vAxisZ;
vAxisX = FVector3(tempMatrix.m, tempMatrix.m, tempMatrix.m);
vAxisY = FVector3(tempMatrix.m, tempMatrix.m, tempMatrix.m);
vAxisZ = FVector3(tempMatrix.m, tempMatrix.m, tempMatrix.m);
//世界矩阵-相机矩阵
FVector3 vDelta = WorldLocation - GetCameraLocation();
FVector3 vTransformed = FVector3(vDelta.Dot(vAxisY), vDelta.Dot(vAxisZ), vDelta.Dot(vAxisX));
if (vTransformed.z < 1.f)
return 0;
float FovAngle = GetFov();
//Screenlocation.x = g_Game->窗口客户端中心X + vTransformed.x * (g_Game->窗口客户端中心X / tanf(FovAngle * (float)PI / 360.f)) / vTransformed.z;
//Screenlocation.y = 窗口客户端中心Y() - vTransformed.y * (g_Game->窗口客户端中心X / tanf(FovAngle * (float)PI / 360.f)) / vTransformed.z;
int 窗口客户端中心X = TGame::窗口客户端中心X();
int 窗口客户端中心Y = TGame::窗口客户端中心Y();
Screenlocation->x = 窗口客户端中心X + vTransformed.x * (窗口客户端中心X / tanf(FovAngle * (float)PI / 360.f)) / vTransformed.z;
Screenlocation->y = 窗口客户端中心Y - vTransformed.y * (窗口客户端中心X / tanf(FovAngle * (float)PI / 360.f)) / vTransformed.z;
Screenlocation->z = 0.0f;
return 1;
}
UINT_PTR TGame::Get_UMatrix()
{
/*
*/
ULONG64offset_UMatrixXbase = GetPByPdbName("GetCanvasByName") + 0x21;
UINT_PTR offset_UMatrix = offset_UMatrixXbase + 7 + RP<DWORD>(offset_UMatrixXbase + 3);
return offset_UMatrix;
}
//Rm(Rm(Rm(g_Game->GameBase + g_Game->offset_UMatrix) + 0x20) + 0xB0, tempMatrix, 64);
bool TGame::WorldToScreenRect(IN FVector3 WorldLocation, OUT FVector4& Rect)
{
float View{}, Top{}, Lift{}, BoxY{}, BoxH{};
float tempMatrix{};
// Rm(Rm(Rm(base+offset_UMatrix) + 0x20) + 0xB0, tempMatrix, 64);
RM(R8(R8(Get_UMatrix()+0) + 0x20) + 0xB0,OUT tempMatrix);
View =
tempMatrix * WorldLocation.x +
tempMatrix * WorldLocation.y +
tempMatrix * WorldLocation.z +
tempMatrix;
if (View < 1.f)
return false;
View = 1 / View;
Top = 窗口客户端中心X() + (
tempMatrix * WorldLocation.x +
tempMatrix * WorldLocation.y +
tempMatrix * WorldLocation.z +
tempMatrix
) * View * 窗口客户端中心X();
Lift = 窗口客户端中心Y() - (
tempMatrix * WorldLocation.x +
tempMatrix * WorldLocation.y +
tempMatrix * WorldLocation.z +
tempMatrix
) * View * 窗口客户端中心Y();
BoxY = 窗口客户端中心Y() - (
tempMatrix * WorldLocation.x +
tempMatrix * WorldLocation.y +
tempMatrix * (WorldLocation.z + 75.0f) +
tempMatrix
) * View * 窗口客户端中心Y();
Rect.h = Lift - BoxY;
Rect.w = Rect.h * (float)0.6015625;
Rect.x = Top - Rect.w / 1.4f;
Rect.y = BoxY;
Rect.w *= 1.5f;
Rect.h *= 2.3f;
return true;
}
//"TGame.h"
#pragma once
#include"世界坐标转屏幕坐标.h"
typedef UINT_PTR AActor;
typedef UINT32 SIZE32;
//typedef struct _FVector3
//{
// float x;
// float y;
// float z;
// float w; //??
// float h; //??
//}FVector3;
class TGame
{
public:
static HWND GetHwnd();
static UINT_PTR GetGameBase();
static INT64 GetResolution(OUT int& x, int& y); //获取游戏分辩率
static int GetResolutionWidth();
static int GetResolutionHeight();
static int 窗口客户端中心X();
static int 窗口客户端中心Y();
static INT64 在屏幕内( int x,int y); //判断坐标是否在屏幕内
static DWORD GetMainThreadID();
static BOOL IsMainThread();
static UINT_PTR GetGWorld();
static UINT_PTR GetUlevel();
static UINT_PTR GetAActorArray();
static SIZE32 GetAActorArraySize(); //[+F8]+88+4
static SIZE32 GetAActorArraySizeMax();//[+F8]+88+4+4 最大容量
static AActor*GetAActor(UINT32 index); // [[+F8]+88]+8*下标]
static UINT_PTRGetGameInstance(); //[+0x290]
static UINT_PTRGetLocalPlayer(); //[[[[+0x290]+38]+30]+0*8]
static UINT_PTRGetPlayerController(); //[[[[+0x290]+38]+0*8]+30]
static UINT_PTRGetPlayerCameraManager(); //[[[[[+290]+38]+0]+30]+4F0]
static FVector3GetCameraLocation(); //[[[[[+290]+38]+0]+30]+4F0]+4E4
static FVector3GetCameraRotation(); //[[[[[+290]+38]+0]+30]+4F0]+4D8
static float GetFov(); //[[[[[+290]+38]+0]+30]+4F0]+4D0+8+28 可读
//static void WorldToScreen(IN float* worldpos3, OUT float* screenpos2, bool bPlayerViewportRelative=false);
static UINT_PTR Get_UMatrix();
static void WorldToScreen(IN FVector3* worldpos3, OUT FVector3* screenpos2, bool bPlayerViewportRelative, BOOL isEx);
static bool WorldToScreenRect(IN FVector3 WorldLocation,OUT FVector4& Rect);
static bool WorldToScreenEx(IN FVector3 WorldLocation, OUT FVector3* Screenlocation);
};
页:
[1]