Duplicate Animation Events Fix: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
(page refresh)
 
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{lang|Duplicate Animation Events Fix}}
{{cleanup}}
{{note|This change is already present in the code generated using the "Start a Multiplayer mod from a template" option in the Create a Mod Wizard.}}
== Introduction ==
== Introduction ==
This is neither a prediction issue NOR a duplicated animation issue. It has to do with the introduction of the new PlayerAnimState code in the 15 June 2009 Orange Box SDK release.
This is neither a prediction issue NOR a duplicated animation issue. It has to do with the introduction of the new PlayerAnimState code in the 15 June 2009 {{orangebox|4}} SDK release.
 
The addition of the PlayerAnimState brings great changes to controlling the animations on the player, but the problem is it was thrown into an already very messy animation code that involves literally hundreds of calls to functions in various levels of virtualization...


The introduction of the PlayerAnimState brings great changes to controlling the animations on the player. The problem is it was thrown into an already messy animation code that involves literally hundreds of calls to functions in various levels of virtualization...
== Explanation ==


Regardless, at the end of the CHL2MPPlayerAnimState::DoAnimationEvent(...) function there is a little present from Valve. That is to do the View Model animation that corresponds to the third person anim! However, the problem lies in the way Valve detects network variable changes, those pesky "Parity" variables you might see around, specifically m_nResetEventsParity.
At the end of the <code>CHL2MPPlayerAnimState::DoAnimationEvent()</code> function there is a little present from Valve, running a update to the View Model animation that corresponds to the third person animations. But, the problem lies in the way the SDK detects network variable changes, such as those pesky "{{wiki|Parity}}" variables you might see around, specifically <code>m_nResetEventsParity</code>.


Let's backtrack a little, all weapons call their own viewmodel animations with a function called SendWeaponAnim(...) which does exactly that and also increments the m_nResetEventsParity.
Let's backtrack a little, all weapons call their own viewmodel animations with a function called <code>SendWeaponAnim()</code> which does exactly what its name suggests ''and'' also increments <code>m_nResetEventsParity</code>.


Now the animation doesn't play twice because most weapon calls are in the same frame and it doesn't send the m_nNewSequenceParity since the sequence doesn't change. However, m_nResetEventsParity does get changed and it royally messes everything up. Since the PlayerAnimState stuff is only invoked client side it changes the event parity (sometimes) before the server update changes it, which is why this is an intermittent problem.
Now the animation doesn't play twice because most weapon calls are in the same frame and it doesn't send the m_nNewSequenceParity since the sequence doesn't change. However, <code>m_nResetEventsParity</code> does get changed and it royally messes everything up.  
Since the PlayerAnimState stuff is only invoked client side it changes the event parity (sometimes) before the server update changes it, this is an intermittent problem.


This code is actually used to call the animation events on the predicted viewmodels of OTHER players (so muzzle flashes and the like play properly in third person view). The problem is valve didn't filter it out for the local player which causes the doubling of animation events.
The code is actually used to call the animation events on the predicted viewmodels of OTHER players (so muzzle flashes and the like play properly in third person view). The problem is valve didn't filter it out for the local player which causes the "doubling" of animation events.


== Requirements ==
== Requirements ==
Line 18: Line 26:
Simply add a filter for the local player in the following code hl2mp_playeranimstate.cpp:
Simply add a filter for the local player in the following code hl2mp_playeranimstate.cpp:


In function CHL2MPPlayerAnimState::DoAnimationEvent(...)
In the function <code>CHL2MPPlayerAnimState::DoAnimationEvent()</code>
<source lang=cpp>
<source lang=cpp>
#ifdef CLIENT_DLL
#ifdef CLIENT_DLL
Line 39: Line 47:
== Notes and Future Work ==
== Notes and Future Work ==
Future version of the SDK might fix this problem the other way, and that is to rely on this player animation code to setup the viewmodel animations instead of the weapon handling it's own animations in the specific parts of the code (PrimaryAttack, Draw, Holster, etc.)
Future version of the SDK might fix this problem the other way, and that is to rely on this player animation code to setup the viewmodel animations instead of the weapon handling it's own animations in the specific parts of the code (PrimaryAttack, Draw, Holster, etc.)
This change is already present in the code generated using the "Start a Multiplayer mod from a template" option in the Create a Mod Wizard.


[[Category:Programming]]
[[Category:Programming]]

Latest revision as of 12:36, 29 November 2023

English (en)Русский (ru)Translate (Translate)
Broom icon.png
This article or section needs to be cleaned up to conform to a higher standard of quality.
For help, see the VDC Editing Help and Wikipedia cleanup process. Also, remember to check for any notes left by the tagger at this article's talk page.
Note.pngNote:This change is already present in the code generated using the "Start a Multiplayer mod from a template" option in the Create a Mod Wizard.

Introduction

This is neither a prediction issue NOR a duplicated animation issue. It has to do with the introduction of the new PlayerAnimState code in the 15 June 2009 Orange Box branch Orange Box branch SDK release.

The addition of the PlayerAnimState brings great changes to controlling the animations on the player, but the problem is it was thrown into an already very messy animation code that involves literally hundreds of calls to functions in various levels of virtualization...

Explanation

At the end of the CHL2MPPlayerAnimState::DoAnimationEvent() function there is a little present from Valve, running a update to the View Model animation that corresponds to the third person animations. But, the problem lies in the way the SDK detects network variable changes, such as those pesky "Wikipedia icon Parity" variables you might see around, specifically m_nResetEventsParity.

Let's backtrack a little, all weapons call their own viewmodel animations with a function called SendWeaponAnim() which does exactly what its name suggests and also increments m_nResetEventsParity.

Now the animation doesn't play twice because most weapon calls are in the same frame and it doesn't send the m_nNewSequenceParity since the sequence doesn't change. However, m_nResetEventsParity does get changed and it royally messes everything up. Since the PlayerAnimState stuff is only invoked client side it changes the event parity (sometimes) before the server update changes it, this is an intermittent problem.

The code is actually used to call the animation events on the predicted viewmodels of OTHER players (so muzzle flashes and the like play properly in third person view). The problem is valve didn't filter it out for the local player which causes the "doubling" of animation events.

Requirements

  • Using the latest OB SDK code

Solution

Simply add a filter for the local player in the following code hl2mp_playeranimstate.cpp:

In the function CHL2MPPlayerAnimState::DoAnimationEvent()

#ifdef CLIENT_DLL
	// Make the weapon play the animation as well
	if ( iGestureActivity != ACT_INVALID && GetBasePlayer() != C_BasePlayer::GetLocalPlayer() )  // <-- CHANGE HERE
	{
		CBaseCombatWeapon *pWeapon = GetHL2MPPlayer()->GetActiveWeapon();
		if ( pWeapon )
		{
			pWeapon->EnsureCorrectRenderingModel();
			pWeapon->SendWeaponAnim( iGestureActivity );
			// Force animation events!
			pWeapon->ResetEventsParity();		// reset event parity so the animation events will occur on the weapon. 
			pWeapon->DoAnimationEvents( pWeapon->GetModelPtr() );
		}
	}
#endif

Notes and Future Work

Future version of the SDK might fix this problem the other way, and that is to rely on this player animation code to setup the viewmodel animations instead of the weapon handling it's own animations in the specific parts of the code (PrimaryAttack, Draw, Holster, etc.)