Смещение рендеринга при отдаление и приближение к игроку

demonvir

Участник
Автор темы
22
3
Версия MoonLoader
.026-beta
Хотел сделать отображение рангов над головой игрока, но столкнулся с таким нюансом рендеринга: чем дальше ты отходишь от игрока, тем ниже опускается текст. Хочу узнать, можно ли как-то это огранить чтобы, тест не наслайвался?
1786520502866.png

Отошёл — и стало так:
1786520566173.png

Рендерю через sampCreate3dText. Знаю, что есть ещё renderFontDrawText, но эта функция, даже не знаю, как сказать, слишком сильно движется за камерой, и при её движении выглядит не очень. А с sampCreate3dText такого эффекта я не заметил.
 
Решение
Lua:
local function getPlayerNick3DCoords(serverId)
    if not sampIsPlayerConnected(serverId) then return nil, nil end
    local exists, ped = sampGetCharHandleBySampPlayerId(serverId)
    if not exists or not doesCharExist(ped) then return nil, nil end

    local px, py, pz = getCharCoordinates(ped)
    if not isPointOnScreen(px, py, pz, 0) then return nil, nil end

    local cx, cy, cz = getActiveCameraCoordinates()
    local dist = getDistanceBetweenCoords3d(cx, cy, cz, px, py, pz)
    if dist > 50.0 then return nil, nil end

    local sx, sy = convert3DCoordsToScreen(px, py, pz + 0.8)
    local pixelOffset = math.max(18, 120 / dist)
    local finalY = sy - pixelOffset

    if sy <= 0 or finalY <= 0 then return nil, nil end...

Joce

Известный
97
34
Lua:
local function getPlayerNick3DCoords(serverId)
    if not sampIsPlayerConnected(serverId) then return nil, nil end
    local exists, ped = sampGetCharHandleBySampPlayerId(serverId)
    if not exists or not doesCharExist(ped) then return nil, nil end

    local px, py, pz = getCharCoordinates(ped)
    if not isPointOnScreen(px, py, pz, 0) then return nil, nil end

    local cx, cy, cz = getActiveCameraCoordinates()
    local dist = getDistanceBetweenCoords3d(cx, cy, cz, px, py, pz)
    if dist > 50.0 then return nil, nil end

    local sx, sy = convert3DCoordsToScreen(px, py, pz + 0.8)
    local pixelOffset = math.max(18, 120 / dist)
    local finalY = sy - pixelOffset

    if sy <= 0 or finalY <= 0 then return nil, nil end

    return sx, finalY
end

Пример реализации в скрипте
Lua:
local font = renderCreateFont('Arial', 11, 5)
local target = { id = nil, text = nil }

function main()
    while not isSampAvailable() do wait(100) end
   
    sampRegisterChatCommand("text", function(arg)
        local id, text = arg:match("^(%d+)%s+(.+)%s*$")
        if id and text and sampIsPlayerConnected(tonumber(id)) then
            target.id, target.text = tonumber(id), text
        else
            target.id, target.text = nil, nil
        end
    end)

    while true do
        wait(0)
        if target.id then
            local exists, ped = sampGetCharHandleBySampPlayerId(target.id)
            if exists and doesCharExist(ped) then
                local px, py, pz = getCharCoordinates(ped)
               
                if isPointOnScreen(px, py, pz, 0) then
                    local cx, cy, cz = getActiveCameraCoordinates()
                    local dist = getDistanceBetweenCoords3d(cx, cy, cz, px, py, pz)
                   
                    if dist <= 50.0 then
                        local sx, sy = convert3DCoordsToScreen(px, py, pz + 0.8)
                        local pixelOffset = math.max(18, 120 / dist)
                        local finalY = sy - pixelOffset
                       
                        if sy > 0 and finalY > 0 then
                            local len = renderGetFontDrawTextLength(font, target.text)
                            renderFontDrawText(font, target.text, sx - (len / 2), finalY, 0xFFFFFFFF)
                        end
                    end
                end
            else
                if not sampIsPlayerConnected(target.id) then target.id = nil end
            end
        end
    end
end