Skip to content

[TF2] Fix taunt cam zoom in effect not working on finished taunts#1788

Open
rawra89 wants to merge 5 commits intoValveSoftware:masterfrom
rawra89:taunt-cam-fix
Open

[TF2] Fix taunt cam zoom in effect not working on finished taunts#1788
rawra89 wants to merge 5 commits intoValveSoftware:masterfrom
rawra89:taunt-cam-fix

Conversation

@rawra89
Copy link

@rawra89 rawra89 commented Feb 2, 2026

This PR fixes the taunt cam zoom in effect being broken when players finish taunting. This used to be a feature added around 2009-early 2010s, but broke sometime in 2015.

Before:

tauntcam-before.mp4

After:

tauntcam-after.mp4

Camera would immediately snap to first person, instead of approaching into the player's head, then switching to first person
@rawra89 rawra89 marked this pull request as draft February 2, 2026 10:49
@rawra89
Copy link
Author

rawra89 commented Feb 2, 2026

There's currently a bug where if you changelevel during the zoom in effect, the player will start in thirdperson. Will fix later today. Fixed.

@rawra89 rawra89 marked this pull request as ready for review February 3, 2026 03:27
@rawra89
Copy link
Author

rawra89 commented Feb 10, 2026

Found another bug where if you switch classes while thirdperson is on, it will force you back to first person. Going to convert this into a draft for now until it's fixed. This appears to be an issue only when sv_cheats is on.

@rawra89 rawra89 marked this pull request as draft February 10, 2026 06:56
rawra89 added 2 commits March 4, 2026 20:43
Turns out the camera getting stuck is specific to sv_cheats 1 being on. It doesn't seem to get stuck when cheats are off.
@rawra89 rawra89 marked this pull request as ready for review March 5, 2026 02:35
Copy link
Contributor

@inco-cc inco-cc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently there's an issue with this change regarding taunts that use a camera height offset.

When the taunt ends, the camera will immediately snap back to a height offset of zero, since g_ThirdPersonManager.SetOverridingThirdPerson is being called after the taunt ends, rather than when the taunt camera interpolation ends, which doesn't take into account the camera height offset. You can see this in your after video comparison with the High Five and Schadenfreude taunts.

There's also another related issue that was already present before this change, which could also be addressed with this PR. The camera height offset is calculated separately from camera distance, making it approach its target height before its target distance, which looks quite jarring at the start of a taunt.

This is the result of my suggested changes with the Director's Vision taunt, which offsets the camera down by 15 units:

taunt-cam-height.webm

m_TauntCameraData.m_flDist = m_flTauntCamTargetDist;
}

g_ThirdPersonManager.SetOverridingThirdPerson( false );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

This is causing the third person camera to ignore m_flTauntCamCurrentDistUp, making the camera jump back to zero height offset immediately after the taunt ends and starts interpolating back to first person view.

}

::input->CAM_SetCameraThirdData( NULL, angles );

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
g_ThirdPersonManager.SetOverridingThirdPerson( false );

This seems like an appropriate place to call g_ThirdPersonManager.SetOverridingThirdPerson. This way the camera override will stop when the taunt camera has fully stopped and we're back in first person view, allowing m_flTauntCamTargetDistUp to affect the camera height during C_TFPlayer::TauntCamInterpolation.

m_flTauntCamCurrentDist += Sign( m_flTauntCamTargetDist - m_flTauntCamCurrentDist ) * gpGlobals->frametime * tf_tauntcam_speed.GetFloat();
m_flTauntCamCurrentDist = clamp( m_flTauntCamCurrentDist, m_flTauntCamCurrentDist, m_flTauntCamTargetDist );
m_flTauntCamCurrentDist = Approach( m_flTauntCamTargetDist, m_flTauntCamCurrentDist, gpGlobals->frametime * tf_tauntcam_speed.GetFloat() );
}
Copy link
Contributor

@inco-cc inco-cc Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
m_flTauntCamCurrentDistUp = ( m_flTauntCamCurrentDist / tf_tauntcam_dist.GetFloat() ) * m_flTauntCamTargetDistUp;
}

m_flTauntCamCurrentDistUp can instead be calculated based on m_flTauntCamCurrentDist, making interpolation much smoother for taunts with a camera height offset.

Note that this uses tf_tauntcam_dist instead of m_flTauntCamTargetDist since the latter changes back to zero when zooming back in, which of course would cause the game to crash in this calculation.

Comment on lines 5712 to 5715
if ( m_flTauntCamCurrentDistUp != m_flTauntCamTargetDistUp )
{
m_flTauntCamCurrentDistUp += Sign( m_flTauntCamTargetDistUp - m_flTauntCamCurrentDistUp ) * gpGlobals->frametime * tf_tauntcam_speed.GetFloat();
m_flTauntCamCurrentDistUp = clamp( m_flTauntCamCurrentDistUp, m_flTauntCamCurrentDistUp, m_flTauntCamTargetDistUp );
m_flTauntCamCurrentDistUp = Approach(m_flTauntCamTargetDistUp, m_flTauntCamCurrentDistUp, gpGlobals->frametime * tf_tauntcam_speed.GetFloat() );
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if statement is no longer needed when m_flTauntCamCurrentDistUp is calculated at the same time as m_flTauntCamCurrentDist.


g_ThirdPersonManager.SetDesiredCameraOffset( Vector( m_flTauntCamCurrentDist, 0, m_flTauntCamCurrentDistUp ) );

if ( m_flTauntCamCurrentDist == m_flTauntCamTargetDist && m_flTauntCamCurrentDistUp == m_flTauntCamTargetDistUp )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ( m_flTauntCamCurrentDist == m_flTauntCamTargetDist )

After moving the new m_flTauntCamCurrentDistUp calculation to the same block as m_flTauntCamCurrentDist at the start of this method, this statement should be changed to only check m_flTauntCamCurrentDist, otherwise the taunt camera will never finish since m_flTauntCamTargetDistUp doesn't reset back to zero.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants