local thirdperson = CreateConVar("3rdperson", "0", FCVAR_USERINFO)
local m_yaw = GetConVar("m_yaw"):GetFloat()
local m_pitch = GetConVar("m_pitch"):GetFloat()
local view_angle, view_origin = EyeAngles(), EyePos()
hook.Add("CalcView", "Cool 3rd Person", function(ply, origin, angles)
if not thirdperson:GetBool() then return end
-- Use a hull trace to prevent the camera clipping through the world
view_origin = util.TraceHull({
start = origin,
endpos = origin - view_angle:Forward() * 100 + view_angle:Right() * 15,
filter = ply,
mask = MASK_SHOT,
mins = Vector(-5, -5, -5),
maxs = Vector(5, 5, 5),
}).HitPos
return {
angles = view_angle, -- Set the camera view to the calculated angle
origin = view_origin, -- Set the origin to be thirdperson
drawviewer = true,
}
end)
hook.Add("StartCommand", "Cool 3rd Person", function(ply, cmd)
if not thirdperson:GetBool() then return end
-- We need to calculate mouse movement ourselves since we need to set the view angles
view_angle = view_angle + Angle(cmd:GetMouseY() * m_pitch, cmd:GetMouseX() * -m_yaw, 0)
view_angle[1] = math.Clamp(view_angle[1], -89, 89)
view_angle[2] = math.NormalizeAngle(view_angle[2])
-- Movement will get wonky in any other MOVETYPE
if ply:GetMoveType() == MOVETYPE_WALK then
-- Run a trace from the 3rd person camera
local view_trace = util.TraceLine({
start = view_origin,
endpos = view_origin + view_angle:Forward() * 1e4,
filter = ply,
mask = MASK_SHOT,
}).HitPos
-- Update view angles so we're facing where the camera trace hit
cmd:SetViewAngles((view_trace - ply:GetShootPos()):Angle())
-- Because we've meddled with the view angle we need to update the movement so it works as expected
local move_fix = Vector(cmd:GetForwardMove(), cmd:GetSideMove(), 0)
move_fix = (move_fix:Angle() + (cmd:GetViewAngles() - view_angle)):Forward() * move_fix:Length()
cmd:SetForwardMove(move_fix[1])
cmd:SetSideMove(move_fix[2])
else
cmd:SetViewAngles(view_angle)
end
end)
Comments