How to draw text on top of players?

So I have a script for DarkRP to draw text on players when I look at them



local localplayer
function DrawEntityDisplay()
	ent = localplayer:GetEyeTrace().Entity
	for k, v in pairs(player.GetAll()) do
		if ent:IsPlayer() == true then
			print(ent)
			local pos = ent:EyePos()
			draw.DrawText(ent:Nick(), "DermaDefault", pos.x, pos.y + 15, Color(255,255,255,255))
		else return end
	end
end

function GM:HUDPaint()
    localplayer = localplayer and IsValid(localplayer) and localplayer or LocalPlayer()
    if not IsValid(localplayer) then return end

    DrawEntityDisplay()

    self.Sandbox.HUDPaint(self)
end


It prints that its a player but it doesnt draw the text. Any help is appreciated. There are also no errors in the console.

Firstly, you shouldn’t be overwriting HUDPaint for this. That’s what

hook.Add is for.

Secondly, wtf are you doing with this:


  localplayer = localplayer and IsValid(localplayer) and localplayer or LocalPlayer() 

Edit: Here, just take this. I’m sorry but you made a mistake like fucking everywhere. That thing you wrote won’t get you very far.

Edit #2: Found this code on wiki somewhere.



function DrawName( ply )
 
	if !ply:Alive() then return end
 
	local offset = Vector( 0, 0, 85 )
	local ang = LocalPlayer():EyeAngles()
	local pos = ply:GetPos() + offset + ang:Up()
 
	ang:RotateAroundAxis( ang:Forward(), 90 )
	ang:RotateAroundAxis( ang:Right(), 90 )
 
	cam.Start3D2D( pos, Angle( 0, ang.y, 90 ), 0.25 )
		draw.DrawText( ply:GetName(), "Default", 2, 2, Color( 200, 200, 200, 255 ), TEXT_ALIGN_CENTER )
	cam.End3D2D()
 
end
hook.Add( "PostPlayerDraw", "DrawName", DrawName )


Where did you find this code?

Why are you looping through the players? There’s absolutely no need for any sort of loop.

I think he/she wrote that. I don’t see how you could just stumble upon that.

Detouring gamemode hudpaint is not something someone that wrote the top function would do :V

The problem is you’re drawing 3D text in a 2D context. You should be using a 3D render hook.

Yeah it kinda is.

At least cite that you took it from the wiki…

draw.DrawText is a 2D rendering function. HUDPaint is a 2D rendering hook.

Yea, ig. Looked at some examples on the wiki to see if maybe he/she found it on wiki, but I didn’t find anything. (Although I’m sure I saw something like that in the past)

He’s using the other player’s EyePos though, which means he’s trying to do world-coord drawing. He’s just using the wrong function and hook.

My bad, didn’t realize I did. I copied and pasted that from a game mode I made a while back while testing something.

Here, straight from my gamemode, modified for your purpose.



local trace = LocalPlayer():GetEyeTrace()

if IsValid(trace) && IsValid(trace.Entity) then
    local ent = trace.Entity
    if !ent:IsPlayer() then return; end
    if ent:InVehicle() then return; end
    if !ent:Alive() then return; end
    
    local hPos = ent:GetBonePosition(ent:LookupBone("ValveBiped.Bip01_Head1")) + Vector(0, 0, 18) //gets a pos right above their head, in world coordinates
    local x = hPos:ToScreen().x
    local y = hPos:ToScreen().y - 20

    local col = team.GetColor(ent:Team())

    draw.SimpleTextOutlined(ent:Nick(), "WHATEVERFONTYOUWANT", x, y, col, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 2, Color(25, 25, 25))
end


Put that in a hook and you’ll be golden. This is simple, however. A more advanced script would determine if the player is close enough to display the text, etc… but I’ll leave that one up to you.

That only works if the player’s model has a head bone (and will actually error if it doesn’t). I personally would use the model bounds multiplied by the scale.

For sure, but if he’s using DarkRP, he shouldn’t have a problem with players not having heads. :stuck_out_tongue:

It’s model based, not gamemode, so if a player doesn’t download a custom model or the custom model doesn’t have the head properly named/doesn’t have the bone then it will error, not just silently fail.

So I did this



local function hudPaint()
local trace = LocalPlayer():GetEyeTrace()
if IsValid(trace) && IsValid(trace.Entity) then
    local ent = trace.Entity
    if !ent:IsPlayer() then return; end
    if ent:InVehicle() then return; end
    if !ent:Alive() then return; end
    
    local hPos = ent:GetBonePosition(ent:LookupBone("ValveBiped.Bip01_Head1")) + Vector(0, 0, 18)
    local x = hPos:ToScreen().x
    local y = hPos:ToScreen().y - 20

    local col = team.GetColor(ent:Team())

    draw.SimpleTextOutlined(ent:Nick(), "DermaDefault", x, y, col, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 2, Color(25, 25, 25))
end
end
hook.Add("HUDPaint", "DarkRP_Mod_Thing_HUDPaint", hudPaint)


Doesnt seem to do anything

IsValid(trace) will always return false, it’s a table.

Whoopsies, code_gs is correct. Go ahead and remove IsValid(trace) from the if statement.