Home / Forums / Drawing ESP for Cursed Possessions & Ghost Room in Phasmophobia with ImGui

UnreliableCode Community

Developer Research, Reverse Engineering & Coding Community

Tutorial

Drawing ESP for Cursed Possessions & Ghost Room in Phasmophobia with ImGui

ParanormalDev
MelonLoader / BepInEx Dev
MEMBER
Rep: 230
Join Date: Sep 2023
Posts: 21
Thanks: 58
2y ago · Jun 14, 2024 4:30 PM
#1
Following up on @GhostHunter_x's thread, here is how to project and draw clean 3D WorldToScreen ESP markers for Cursed Possessions (Ouija Board, Tarot Cards, Haunted Mirror, Voodoo Doll, Music Box, Summoning Circle, Monkey Paw):

CPP
struct ItemESPInfo {
    Vector3 worldPos;
    const char* itemName;
    ImU32 color;
};

void DrawCursedPossessionsESP(const std::vector<ItemESPInfo>& items, const Matrix4x4& viewMatrix, int screenW, int screenH) {
    ImDrawList* drawList = ImGui::GetBackgroundDrawList();
    
    for (const auto& item : items) {
        Vector2 screenPos;
        if (WorldToScreen(item.worldPos, screenPos, viewMatrix, screenW, screenH)) {
            // Draw circle marker
            drawList->AddCircleFilled(ImVec2(screenPos.x, screenPos.y), 4.0f, item.color);
            
            // Draw item label with background contrast
            char label[128];
            float distance = GetDistance(g_LocalPlayer.position, item.worldPos);
            snprintf(label, sizeof(label), "%s [%.1fm]", item.itemName, distance);
            
            ImVec2 textSize = ImGui::CalcTextSize(label);
            ImVec2 textPos = ImVec2(screenPos.x - (textSize.x * 0.5f), screenPos.y - 18.0f);
            
            drawList->AddRectFilled(ImVec2(textPos.x - 3, textPos.y - 2), ImVec2(textPos.x + textSize.x + 3, textPos.y + textSize.y + 2), IM_COL32(0, 0, 0, 160), 4.0f);
            drawList->AddText(textPos, IM_COL32(255, 255, 255, 255), label);
        }
    }
}


Pro-Tip for Unity Cameras:
In Unity IL2CPP, read
CPP
Camera.main.worldToCameraMatrix
and
CPP
Camera.main.projectionMatrix
or multiply them into a combined view-projection matrix for the WorldToScreen calculation!
ParanormalDev | MelonLoader & ImGui Modding
The following users thanked ParanormalDev for this post:
GlowShader
Shader & Overlay Artist
MEMBER
Rep: 185
Join Date: Oct 2023
Posts: 36
Thanks: 46
2y ago · Jun 14, 2024 6:45 PM
#2
Clean label background padding! Adding
CPP
float distance = GetDistance(...)
helps a ton on large maps like Sunny Meadows or Prison.
GlowShader | Shaders, Stencils & DirectX DrawLists
VectorByte
Graphics & DirectX Dev
VIP
Rep: 420
Join Date: Aug 2022
Posts: 39
Thanks: 115
2y ago · Jun 15, 2024 9:12 AM
#3
In Unity, you can also use
CPP
Camera.WorldToScreenPoint()
directly if you are calling internal engine methods, but calculating it with your own C++ SIMD matrix multiplication is much faster when drawing 50+ item entities.
VectorByte | DirectX 11/12 Hooking & ImGui Overlays
Quote
Math is the language of game engines.