Interpolation
{{subst:#if:|||
Important step for replacing wikilinks after you've created this page
After you click 'Edit' do what the image shows. If you can't see editing toolbar you need to enable it in 'Preferences' -> Editing -> checkbox 'Enable the editing toolbar'
![]() |
参见: {{LAuto}}
|
--- DON'T JUST BLINDLY DELETE THIS PART. DO REPLACE THE LINKS AND CATEGORIES. THE PICTURE SHOWS HOW TO USE IT ! ---
SEARCH FOR: \[\[(?!#|File(?:[ _]talk)?:|Image(?:[ _]talk)?:|Media:|Template(?:[ _]talk)?:|MediaWiki(?:[ _]talk)?:|Talk:|Category[ _]talk:|Project[ _]talk:|Valve[ _]Developer[ _]Community[ _]talk:|Help[ _]talk:|User(?:[ _]talk)?:|c:|commons:|Dictionary:|Google:|GoogleGroups:|IMDB:|M:|Meta:|Metawikipedia:|MW:|SdkBug:|SourceForge:|Steampowered:|W:|Wiki:|WikiBooks:|Wikipedia:|Wikiquote:|Wiktionary:|WP:)(:?(?:Category|Category|Help|Project|Valve[ _]Developer[ _]Community|Special|)(?:[^\|\]]+))(\|?.*?)\]\]
REPLACE WITH: {{subst:LAuto|$1$2}}
}}
As a courtesy, please do not edit this while this message is displayed.
If this page has not been edited for at least several hours to a few days, please remove this template. This message is intended to help reduce edit conflicts; please remove it between editing sessions to allow others to edit the page.
The person who added this notice will be listed in its edit history should you wish to contact them.

This page either contains information that is only partially or incorrectly translated, or there isn't a translation yet.
If this page cannot be translated for some reason, or is left untranslated for an extended period of time after this notice is posted, the page should be requested to be deleted.
Also, please make sure the article complies with the alternate languages guide.(en)

It is not recommended to use machine translation without any corrections.
If the article is not corrected in the long term, it will be removed.
Also, please make sure the article complies with the alternate languages guide.(en)
This notice is put here by LanguageBar template and if you want to remove it after updating the translation you can do so on this page.
A multiplayer client will typically need to render three or more frames with each server update it receives (assuming 60fps+ and cl_updaterate 20).
Source's interpolation system prevents the jittery motion this would ordinarily lead to by buffering server updates then playing them back with the gaps smoothly interpolated between. It can also protect against glitches caused by packet loss.
The server knows how much interpolation each client has, and adjusts lag compensation accordingly.
Impact and management
Interpolation adds artificial latency to a player's view of the game world and as such should be kept to the barest minimum. Unfortunately, Valve's games still default to a minimum interpolation delay ("lerp") of 100ms, a value tuned for the era of dial-up modems!
- Players should set
cl_interp 0
, as this will ensure that the lerp is the precise length needed to accommodate the current server update rate. Raising the update rate will reduce lerp further. - Modders should consider removing or renaming
cl_interp
to prevent confusion. - Server operators can regulate lerp with
sv_client_min_interp_ratio
andsv_client_max_interp_ratio
.
Players who suffer from packet loss may want to raise cl_interp_ratio
to 3 (protects against one dropped packet) or even 4 (protects against two consecutive dropped packets).
Implementation
This simple entity prints an interpolated float every frame.
Server:
#include "cbase.h"
class CInterpDemo : public CBaseEntity
{
public:
DECLARE_CLASS(CInterpDemo, CBaseEntity);
DECLARE_SERVERCLASS();
CInterpDemo() { m_MyFloat = 0; }
void Spawn() { SetNextThink(gpGlobals->curtime + 0.0001); BaseClass::Spawn(); }
int UpdateTransmitState() { return SetTransmitState( FL_EDICT_ALWAYS ); }
void Think();
CNetworkVar(float,m_MyFloat);
};
IMPLEMENT_SERVERCLASS_ST(CInterpDemo, DTInterpDemo)
SendPropFloat( SENDINFO(m_MyFloat) ),
END_SEND_TABLE()
LINK_ENTITY_TO_CLASS( interp_demo, CInterpDemo );
void CInterpDemo::Think()
{
m_MyFloat += 0.1;
// without this, LATCH_SIMULATION_VAR will never be triggered
SetSimulationTime( gpGlobals->curtime );
SetNextThink(gpGlobals->curtime + 0.0001);
BaseClass::Think();
}
Client:
#include "cbase.h"
class C_InterpDemo : public C_BaseEntity
{
public:
DECLARE_CLASS(C_InterpDemo, C_BaseEntity);
DECLARE_CLIENTCLASS();
C_InterpDemo();
bool ShouldInterpolate() { return true; } // ordinarily only entities in PVS are interpolated
void PostDataUpdate(DataUpdateType_t updateType);
void ClientThink();
float m_MyFloat;
char* UpdateMsg;
CInterpolatedVar<float> m_iv_MyFloat;
};
IMPLEMENT_CLIENTCLASS_DT(C_InterpDemo,DTInterpDemo,CInterpDemo)
RecvPropFloat( RECVINFO(m_MyFloat) ),
END_RECV_TABLE()
LINK_ENTITY_TO_CLASS( interp_demo, C_InterpDemo );
C_InterpDemo::C_InterpDemo() :
m_iv_MyFloat("C_InterpDemo::m_iv_MyFloat") // just a debug name, can be anything unique
{
// This is a simulation latch, so the variable will only be interpolated
// if the entity is moving or has a new SimulationTime.
AddVar( &m_MyFloat, &m_iv_MyFloat, LATCH_SIMULATION_VAR );
UpdateMsg = "";
}
void C_InterpDemo::PostDataUpdate(DataUpdateType_t updateType)
{
UpdateMsg = " (from server)";
SetNextClientThink(CLIENT_THINK_ALWAYS);
BaseClass::PostDataUpdate(updateType);
}
void C_InterpDemo::ClientThink()
{
Msg("Interpolated float: %f%s\n",m_MyFloat,UpdateMsg);
UpdateMsg = "";
SetNextClientThink(CLIENT_THINK_ALWAYS);
}
The important steps are:
- Initialise our
CInterpolatedVar
in the class constructor, giving it a debug name in the process.待完善: How to debug? - Call
AddVar()
to latch theCInterpolatedVar
onto the actual variable. - Ensure that
ShouldInterpolate()
returns true when we want it to. (This entity isn't visible so wouldn't normally be interpolated.) - On the server, call
SetSimulationTime()
. The simulation latch we chose inAddVar()
is triggered by changes to this value or to the origin/angles. You could also choose an animation latch which is triggered by changes to the entity's current animation frame ("cycle").
Troubleshooting
If your variable is not being interpolated:
- Check
C_BaseEntity::PostDataUpdate()
, which is where the interp system kicks in. - If the interpolated value needs to be passed to other code (e.g. VPhysics positioning), make sure you are doing so in
ClientThink()
every frame. - Make sure your entity is in PVS on the client.