• 3rd Person Camera (mmo style)
    4 replies, posted
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.