You’re over-thinking and over-complicating a problem.
CalcView and CreateMove are used.
In CreateMove with one argument _cmd, if thirdperson is enabled, assign _dMx = _cmd:GetMouseX( ) for rotation. This controls a variable you have for yaw; use a Vector and just modify yaw or create a separate variable, it doesn’t matter. Make sure to math.NormalizeAngle( yaw - dMx ); this lets you simply subtract, or add the change in position resulting in rotation of the camera angle.
You can also _cmd:GetMouseWheel( ) within CreateMove to control zoom. If you plan on using roll, you’ll want to ensure it always Lerps to 0 ( so when a player jumps, it’ll always return to 0; or just leave it as is and don’t play with it, let the game do it by itself )
For CalcView with 6 arguments for player, origin, angles, fov, znear, zfar - I call them _p, _origin, _ang, _fov, _znear, _zfar. If thirdperson is enabled, and they are not in a vehicle ( let the vehicle class manage the view while in a vehicle ). Create a new list; view or _view. set _view.drawviewer to true, this allows us to avoid hooking into ShouldDrawLocalPlayer.
We’ll want to use the yaw we created and are managing with CreateMove to rotate the camera around the player, and only when the player uses a movement key or attack key to update the player yaw to the camera yaw.
To rotate only the camera, you just SetEyeAngles on the player to the old yaw ( one more thing to manage ), when we move the player we update the old angle first and set angle in an if statement else we update the eye angles for the player using the old yaw.
Something like this:
[lua] if ( ply:KeyDown( bit.bor( IN_FORWARD, IN_BACK, IN_MOVELEFT, IN_MOVERIGHT, IN_ATTACK2 ) ) ) then
ply:SetFlag( “view_angle_old”, Angle( angles.p, _angle.y, 0 ), true );
ply:SetEyeAngles( Angle( angles.p, _angle.y, 0 ) );
local _old = ply:GetFlag( “view_angle_old”, Angle( 0, 0, 0 ), true );
ply:SetEyeAngles( Angle( angles.p, _old.y, 0 ) );
That handles rotating the camera, but we’re still not “thirdperson”. Target origin, so _view.origin should be all of the following:
( _angles from CalcView arg + the current view-angle ( where we manage yaw ) + another angle to offset us if you want I use yaw 15 ):Forward( ) * -_dist
where _dist is the distance behind the player we want to be. I use 100 units.
[lua]local _targetOrigin = origin + ( ( angles + _angle + Angle( 0, 15, 0 ) ):Forward( ) * -_dist );[/lua]
Then, just do a trace to ensure the camera can never go into a wall; done.