3D Arrow on Screen

Hello. I’m trying to draw a 3D Arrow on the player’s screen, more like the ‘Floating Baby’ from MelonRacer ( Clientside, that is ). I’ve managed to spawn the arrow and place it in front of the player, but I can’t seem to find how to position it locally, on the screen, rather than in the world. ( …because it’s moving with the player and its movement is jerky! I want it to stay on a certain position, on the screen, like w * 0.5 and y * 0.2 let’s say ).

I’m not sure about how to do this myself, but did you look at the MelonRacer code to see how Garry did it? Reading other people’s scripts is a great way to learn about different technologies and how they’re applied.

It seems the MelonRacer code is gone from my Garry’s Mod gamemodes directory. I’ve looked into the .gcf files, still nothing.

Make it a ClientsideModel() and draw it using the cam library.

[lua]
local Arrow
local function DrawSupplyArrow()

if Arrow == nil then
	Arrow = ClientsideModel ( "models/props/arrow.mdl" )
	Arrow:SetModelScale ( Vector ( 0.2,0.2,0.2 ) )
end
	
cam.Start3D( EyePos(), EyeAngles() )
	if Arrow then
		Arrow:DrawModel()
		Arrow:SetPos ( EyePos() + LocalPlayer():GetAimVector() * 15 + Vector ( 0,0,5 ) ) // .. not good
	end
cam.End3D()

end
hook.Add ( “HUDPaint”, “DrawArrow”, DrawSupplyArrow )
[/lua]

May I ask, how to position it properly ?

Adjust values until it is right.

Thank you. Anybody know where can I find the Melon Racer code? (It’s not in the game anymore)

[lua]
local PANEL = {}

/---------------------------------------------------------
Init
---------------------------------------------------------
/
function PANEL:Init()

self:SetModel( "models/props_c17/doll01.mdl" )

self.Visible = false
self:SetPos( ScrW()-1, 0 )

self:PerformLayout()

end

/---------------------------------------------------------
Think
---------------------------------------------------------
/
function PANEL:Think()

end

/---------------------------------------------------------
LayoutEntity
---------------------------------------------------------
/
function PANEL:LayoutEntity( Entity )

if (!IsValid(LocalPlayer())) then return end

self:SetCamPos( Vector( 0, 20, 0 ) )
self:SetLookAt( Vector( 0, 0, 0 ) )

local TargetDir = LocalPlayer():GetNWVector( "CPDir", Vector(0,0,0) )

if ( TargetDir == Vector(0,0,0) && self.Visible ) then
	self:MoveTo( ScrW()-1, 0, 1, 0, 0.5 )
	self.Visible = false
elseif ( TargetDir != Vector(0,0,0) && !self.Visible ) then
	self:MoveTo( ScrW()-self:GetWide(), 0, 1, 0, 2 )
	self.Visible = true
end

local TargetDir = (LocalPlayer():EyePos() - TargetDir)
TargetDir.z = 0

local DIR = TargetDir:Angle()
local EYEANGLE = LocalPlayer():EyeAngles()

EYEANGLE.pitch = 0
local DIR = DIR - EYEANGLE

Entity:SetPos( Vector( 0, 0, 0 ) )
Entity:SetAngles( DIR + Angle( 70, 90, 0 ) )

end

/---------------------------------------------------------
PerformLayout
---------------------------------------------------------
/
function PANEL:PerformLayout()

self:SetSize( ScrW()*0.3, ScrW()*0.3 )

end

if ( Compass ) then Compass:Remove() end
Compass = vgui.CreateFromTable( vgui.RegisterTable( PANEL, “DModelPanel” ) )[/lua]

Now that’s what I call a brilliant idea! Thanks, Lex.

You could make a cheap model draw it clientside and make it’s material $ignorez?

It’s not the most elegant solution, but it’ll work.

What, copy the file from melonracer? :v:

No, Garry’s Idea :stuck_out_tongue: :V

EDIT: I would like to ask another question based on this : How should I set it to correctly indicate a position in the world ? I am currently using an arrow model ( I spawned it in the world and made it point to myself and it didn’t need any offset angle ) along with the code above ( MyEyePos - TargetPos ) : Angle () - MyEyeAngles(). The problem is that the arrow isn’t correctly pointing to the specified location. I’m not very good at math, but this should work … What am I doing wrong?