I've been recently trying to make a gamemode where the player can toggle between first person and a bird's eye view where they then get edge scrolling and can click on things... What would be the best way to do that?
Hook into [url=http://wiki.garrysmod.com/?title=Gamemode.CalcView]calcview[/url] and chage the origin to above the user and the angles so the camera faces downwards.
thanks. how do i do mouse input though?
You also need to return true in a ShouldDrawLocalPlayer hook to allow the player to be rendered. All done clientside ofcourse.
[editline]02:12PM[/editline]
[code]gui.EnableScreenClicker()[/code]
Infact, if this is for a gamemode there is no need to hook to those functions, just edit those functions instead:
[lua]function GM:CalcView(ply, origin, angles, fov)
//stuff here
end[/lua]
ok, now how do i get it to trace to where the mouse is hovering so that i can see what they're clicking on?
That one is a little difficult, GetEyeTrace will return a trace to the cursor, however, because you are using calcview to change the origin of the player's view the trace will be offset from the cursor. To fix this problem you can use this code, it is a little less efficient but will always return a trace to the cursor:
[lua]local orig = origin_of_the_view_camera --The position of the player's view.
local ang = orig + LocalPlayer():GetCursorAimVector()
local trace = util.QuickTrace(orig, ang * 1e9, LocalPlayer())[/lua]
i can't get it to work. as a test i'm trying to get it to spawn a barrel where i click and here's my code:
[lua]function GM:KeyPress(ply, key)
if ply:KeyDown(IN_ATTACK) and ply:GetNWBool("IsInBirdEye") == true then
local orig = ply:GetNWVector("CameraPos")
local ang = orig + ply:GetCursorAimVector()
local trace = util.QuickTrace(orig, ang * 1e9, ply)
barrel = ents.Create("prop_physics")
barrel:SetModel("models/props_c17/oildrum001.mdl")
barrel:SetPos(trace.HitPos)
barrel:Spawn()
end
end[/lua]
can you tell me what i'm doing wrong?
Are there any errors? If not, try printing some of the values to make sure they are what you expect.
ok, it didn't like the IN_ATTACK, i'm assuming because it's in the mouse mode, so i changed it to IN_SPEED and the messages were giving errors, so i removed them. it then started spawning the barrels, however, they appeared at the camera height and much farther away than i clicked.
and it doesn't matter where i put the mouse it always spawns in the same spot
This is probably not the reason for the bug, but you are checking for a key input in a function that supplies the key as an argument. Use this instead:
[lua]function GM:KeyPress(ply, key)
if key == IN_ATTACK and ply:GetNWBool("IsInBirdEye") == true then
local orig = ply:GetNWVector("CameraPos")
local ang = orig + ply:GetCursorAimVector()
local trace = util.QuickTrace(orig, ang * 1e9, ply)
barrel = ents.Create("prop_physics")
barrel:SetModel("models/props_c17/oildrum001.mdl")
barrel:SetPos(trace.HitPos)
barrel:Spawn()
end
end[/lua]
i think there is something wrong with my camera position which is why moving the camera doesn't change the spawn spot and why it keeps snapping back to it's original position, however, it's obviously not taking into account the mouse either, which would be a different bug...
(and it still doesn't accept IN_ATTACK)
I am currently making a gamemode which uses the exact method i gave you. It works perfectly from any view position.
[editline]05:08PM[/editline]
Is the NW vector the same as the camera position clientside?
ServerSide:
[lua]function GM:KeyPress(ply, key)
if key == IN_RELOAD and ply:GetNWBool("IsInBirdEye") == false then
ply:SetNWBool("IsInBirdEye", true)
ply:SetNWVector("CameraPos", ply:GetPos() + Vector(0,0,500))
elseif key == IN_RELOAD and ply:GetNWBool("IsInBirdEye") == true then
ply:SetNWBool("IsInBirdEye", false)
end
if key == IN_ATTACK and ply:GetNWBool("IsInBirdEye") == true then
local orig = ply:GetNWVector("CameraPos")
local ang = orig + ply:GetCursorAimVector()
local trace = util.QuickTrace(orig, ang * 1e9, ply)
barrel = ents.Create("prop_physics")
barrel:SetModel("models/props_c17/oildrum001.mdl")
barrel:SetPos(trace.HitPos)
barrel:Spawn()
end
end[/lua]
ClientSide:
[lua]function GM:CalcView( player, origin, angles, fov )
player.oldorigin = player:GetNWVector("CameraPos")
local view = {}
view.origin = player.oldorigin
view.angles = Angle(90,0,0)
if gui.MouseX() < 5 then view.origin = player.oldorigin + Vector(0,10,0) end
if gui.MouseX() > ScrW() - 5 then view.origin = player.oldorigin + Vector(0,-10,0) end
if gui.MouseY() < 5 then view.origin = player.oldorigin + Vector(10,0,0) end
if gui.MouseY() > ScrH() - 5 then view.origin = player.oldorigin + Vector(-10,0,0) end
player.oldorigin = view.origin
player:SetNWVector("CameraPos", player.oldorigin)
if player:GetNWBool("IsInBirdEye") == true then
gui.EnableScreenClicker(true)
return view
elseif player:GetNWBool("IsInBirdEye") == false then
gui.EnableScreenClicker(false)
end
end[/lua]
Setting networked variables clientside will only update it clientside, you need to use concommands to update the camera origin serverside.
i'm not very good with console commands, especially ones with arguments. could you post the code for a console command to update the camera position?
[b]SERVER[/b]
[lua]concommand.Add("UpdateViewPos", function(ply, cmd, args)
if args[1] and args[2] and args[3] then
ply:SetNWVector("CameraPos", Vector(args[1], args[2], args[3]))
end
end)[/lua]
[b]CLIENT[/b]
Instead of doing this: [i]player:SetNWVector("CameraPos", player.oldorigin) [/i], you would do
[lua]RunConsoleCommand("UpdateViewPos", player.oldorigin.x, player.oldorigin.y, player.oldorigin.z)[/lua]
now the spot it spawns changes when i move the camera, but why isn't it moving according to mouse position?
I think i see the problem, change [lua]local orig = ply:GetNWVector("CameraPos")
local ang = orig + ply:GetCursorAimVector()
local trace = util.QuickTrace(orig, ang * 1e9, ply)[/lua] to [lua]local orig = ply:GetNWVector("CameraPos")
local ang = ply:GetCursorAimVector()
local trace = util.QuickTrace(orig, orig + ang * 1e9, ply)[/lua]
If that is the problem, it is my fault entirely. I didn't read my own code properly.
ok, it works perfectly on single player but on multiplayer it spawns the barrel slightly off the top side of the screen
Strange, when i use that code it works on single player and multiplayer.
nevermind, i reloaded it after trying on single player and it worked. Thank you for all your help
You're Welcome :smile:
Sorry, you need to Log In to post a reply to this thread.