Hi coders
I've come up with this code here that gives a 3rd person style camera like some mmo's. (courtesy of Blasphemy for some of the code) I was hoping you might be able to help me with a couple of issues:
-I'd like presses of the A and D keys to turn the player rather than strafe while in this mode
-fix the issue where the camera moves wrong when the player has turned, rather than strafed, while in this mode
-the first function in the below code is not returning true when chat is open
-the hook "ContextScreenClick" is not being called while in this mode (should it be?)
Thanks for any help you can offer
Clientside:
[CODE]
--returns true if no GUIs/menus are visible
local function NoMenu()
return (!gui.IsConsoleVisible() and !gui.IsGameUIVisible())
end
--stores the current view which gets offset based on edge detection
local angLookAround = Angle()
--third person mode
local function ThirdPersonUmsg( data )
if( LocalPlayer().ThirdPerson == nil ) then
LocalPlayer().ThirdPerson = true
else
LocalPlayer().ThirdPerson = !LocalPlayer().ThirdPerson
end
gui.EnableScreenClicker(LocalPlayer().ThirdPerson)
if !LocalPlayer().ThirdPerson then angLookAround = Angle() end
end
usermessage.Hook( "ThirdPerson", ThirdPersonUmsg )
--adjust the default zoom distance for third person mode
local dist = 100
function ThirdpersonFreecam()
if !NoMenu() or !LocalPlayer().ThirdPerson then return end
local x, y = input.GetCursorPos()
local percentage = 1
if x <= (ScrW() / 100) * percentage then
angLookAround = angLookAround + Angle(0, 0.6, 0)
elseif x >= ScrW() - (ScrW() / 100) * percentage then
angLookAround = angLookAround + Angle(0, -0.6, 0)
end
if y <= (ScrH() / 100) * percentage then
angLookAround = angLookAround + Angle(0.3, 0, 0)
elseif y >= ScrH() - (ScrH() / 100) * percentage then
angLookAround = angLookAround - Angle(0.3, 0, 0)
end
end
hook.Add( "Think", "ThirdpersonFreecam:Think", ThirdpersonFreecam)
local iMinDistance = 50
local iMaxDistance = 500
local wp = vgui.GetWorldPanel()
wp:SetCursor("crosshair")
wp:MouseCapture(false)
function wp:OnMouseWheeled(delta)
if delta > 0 then
dist = math.Clamp(dist + 5, iMinDistance, iMaxDistance)
elseif delta < 0 then
dist = math.Clamp(dist - 5, iMinDistance, iMaxDistance)
end
end
local iDistanceTemp = 0
local function DrawThirdPerson(objPl, vecView, angView, iFOV)
--Uncomment below line and modify the * 15 to another number if you want more or less "up" offset
--vecView = vecView + LocalPlayer():GetUp() * 15
if LocalPlayer().ThirdPerson then
local vecOffset = LocalPlayer():GetAimVector()
vecOffset:Rotate(angLookAround)
local data = {}
data.start = vecView
data.endpos = vecView - vecOffset * dist
data.filter = LocalPlayer()
local tr = util.TraceLine(data)
iDistanceTemp = math.Approach(iDistanceTemp, -tr.HitPos:Distance(vecView), FrameTime() * 2000)
local tblView = {}
tblView.origin = vecView + vecOffset * (iDistanceTemp + 25)
tblView.angles = (LocalPlayer():EyePos() - tr.HitPos):Angle()
return tblView
end
end
hook.Add("CalcView", "ThirdPerson", DrawThirdPerson)
--draws player model while in 3rd person
local function ThirdPersonSDLP()
if LocalPlayer().ThirdPerson then
return true
end
end
hook.Add( "ShouldDrawLocalPlayer", "ThirdPersonSDLP", ThirdPersonSDLP )
[/CODE]
Serverside:
[CODE]--toggles third person view when the user presses F2
function ToggleThirdPerson( ply )
umsg.Start( "ThirdPerson", ply )
umsg.End()
end
hook.Add( "ShowTeam", "ToggleThirdPerson", ToggleThirdPerson )
[/CODE]
I'd recommend doing certain things in a CreateMove hook for camera positioning with mouse-wheel, pressing buttons, etc etc. instead of in a Think hook.
Anyone able to offer any insight into the issues I'm having? :(
I might look in to this later, but for A and D you could probably do something with the console command +right, -right, +left, and -left.
Use CreateMove, the argument is for CMD - you can get IN keys with it, plus mouse-wheel. You'd only need to use those two hooks to do exactly what you want to do.
I may work on an example but as of right now I believe my processor is nearing the end of its life. Can't boot into windows because it freezes; already tested for faulty drivers, memory, psu, etc. Motherboard looks good, has solid-state caps so those are harder to tell if they popped but from what I can tell they're fine. Windows locking up after a few minutes is a symptom of cpu dying, and I've seen one die once before with similar weird symptoms like what I'm experiencing.
Anyways:
I use: hook.Add( "CalcView", "ThirdpersonFreecam:CalcView", function( ply, origin, angles, fov, znear, zfar )
and
hook.Add( "CreateMove", "ThirdpersonFreecam:CreateMove", function( _cmd )
For the CalcView, I grab a local flag set from CreateMove which handles moving the camera; CreateMove handles everything I need:
[lua]hook.Add( "CreateMove", "ThirdpersonFreecam:CreateMove", function( _cmd )
//
// ThirdPerson Free-Camera System
//
local _p = LocalPlayer( );
// Flag to see if they're in thirdperson
if ( _p:GetFlag( "thirdperson", false, true ) ) then
// Grabs the change in movement for x and y; I commented out y because I'm not using it, and I reduce x because otherwise it moves too quick; this should be based on sensitivity...
local _dMx = _cmd:GetMouseX( ) / 25;
-- local _dMy = _cmd:GetMouseY( );
// This is where I get the current camera angles set to the player, and the view distance
local _cameraAngles = _p:GetFlag( "view_angle", Angle( 0, 0, 0 ), true );
local _cameraDistance = _p:GetFlag( "view_dist", 100, true );
// Here's where I change them; I make sure that roll stays 0 until I implement a system to always lerp it towards 0 so that when you fall it will roll
_cameraAngles.y = math.NormalizeAngle( _cameraAngles.y - _dMx );
_cameraAngles.r = 0;
// Update the view-angle
_p:SetFlag( "view_angle", _cameraAngles, true );
// If the player is holding the ALT / WALK key, then allow them to use zoom-in and zoom-out; clamped to a certain limit
if ( _p:KeyDown( bit.bor( IN_WALK ) ) ) then
// Grab the current distance
local _dist = _p:GetFlag( "view_dist", 100, true );
// Update the distance with the mouse-wheel; it'll return either -1, 0 or 1 depending on which way you scroll
_p:SetFlag( "view_dist", math.Clamp( _dist - _cmd:GetMouseWheel( ) * 5, 50, 150 ), true );
end
// Return so that the character doesn't move.
return true;
end
end );[/lua]
You could easily set up view_angles for zooming in and out with view-dist with just the scroll wheel to make it come in at a curve, ie zoomed all the way out looking directly down, and as you zoom into your character arc it so you are looking at around a 45 degree angle between the ground and the player.
For setting up the camera position, you'd just need to use a new variable for view_position and manipulate that with WASD... Alternatively, you could use PlayerBindPress to detect the WASD keys by looking up the bind; but why do that when all of the logic can be done in CreateMove where you can properly detect mouse movement, and scroll, etc??
Sorry, you need to Log In to post a reply to this thread.