Actor animation desync
#1

When you apply an animation to an actor while they are streamed out for a player (or if they become streamed out), they won't have the animation applied when they stream in again.

This is ok for short one-time animations, but makes permanent animations like sitting down completely impossible, unless you re-apply the animation, but then the actor quickly jumps up and sits down again..

Is it possible to re-apply animations client-side when actors stream in please? Or perhaps ApplyActorAnimationForPlayer?

Sort of related: it'd be nice to have a callback for when an actor streams in/out.

Thanks.
Reply
#2

A callback such as OnActorStreamIn will fix it
Reply
#3

For players, NPCs and now actors it's a well known bug "Animations desync".

We have a body death system (lying animation, using NPCs), we solved this by sending the RPC ApplyAnimation to each stream-in player, for example this is using the RAK plugin (also works in 0.3.7):
Code:
#define RPC_ApplyAnimation 86

enum AnimsSyncEnum {
	s_is_anim,
	s_animlib[50],
	s_animname[50],
	Float:s_fDelta,
	s_loop,
	s_lockx,
	s_locky,
	s_freeze,
	s_time,
	s_forcesync
};

new AnimsSync[MAX_PLAYERS][AnimsSyncEnum];

forward ApplyAnimationEx(playerid, animlib[], animname[], Float:fDelta, loop, lockx, locky, freeze, time, forcesync);
public ApplyAnimationEx(playerid, animlib[], animname[], Float:fDelta, loop, lockx, locky, freeze, time, forcesync) {
	
	AnimsSync[playerid][s_is_anim] = true;

	format(AnimsSync[playerid][s_animlib], 50, "%s", animlib);
	format(AnimsSync[playerid][s_animname], 50, "%s", animname);

	AnimsSync[playerid][s_fDelta]		= fDelta;
	AnimsSync[playerid][s_loop]			= loop;
	AnimsSync[playerid][s_lockx]		= lockx;
	AnimsSync[playerid][s_locky]		= locky;
	AnimsSync[playerid][s_freeze]		= freeze;
	AnimsSync[playerid][s_time]			= time;
	AnimsSync[playerid][s_forcesync]	= forcesync;

	//ApplyAnimation(playerid, animlib, "null", fDelta, loop, lockx, locky, freeze, time, forcesync); // Pre-load?
	ApplyAnimation(playerid, animlib, animname, fDelta, loop, lockx, locky, freeze, time, forcesync);
}


forward ClearAnimationsEx(playerid, forcesync);
public ClearAnimationsEx(playerid, forcesync) {
	AnimsSync[playerid][s_is_anim] = false;

	ClearAnimations( playerid, forcesync );
}

forward ApplyAnimationSync(playerid, toplayerid);
public ApplyAnimationSync(playerid, toplayerid) {

	if ( AnimsSync[playerid][s_is_anim] && ! IsPlayerInAnyVehicle(playerid) ) {
		new BitStream:bsAnim = InitBitStream();
		WriteToBitStream(bsAnim, BS_SHORT, 	playerid);
		WriteToBitStream(bsAnim, BS_CHAR, 	strlen(AnimsSync[playerid][s_animlib])); // anim lib len
		WriteToBitStream(bsAnim, BS_STRING, AnimsSync[playerid][s_animlib] ); // anim lib
		WriteToBitStream(bsAnim, BS_CHAR, 	strlen( AnimsSync[playerid][s_animname] )); // anim name len
		WriteToBitStream(bsAnim, BS_STRING, AnimsSync[playerid][s_animname] ); // anim name
		WriteToBitStream(bsAnim, BS_FLOAT, 	AnimsSync[playerid][s_fDelta] ); // fDelta
		WriteToBitStream(bsAnim, BS_BOOL, 	AnimsSync[playerid][s_loop] ); // loop
		WriteToBitStream(bsAnim, BS_BOOL, 	AnimsSync[playerid][s_lockx] ); // lockx
		WriteToBitStream(bsAnim, BS_BOOL, 	AnimsSync[playerid][s_locky] ); // locky
		WriteToBitStream(bsAnim, BS_BOOL, 	AnimsSync[playerid][s_freeze] ); // freeze
		WriteToBitStream(bsAnim, BS_UINT, 	AnimsSync[playerid][s_time] ); // time
		//WriteToBitStream(bsAnim, BS_CHAR, AnimsSync[playerid][s_forcesync] ); // forcesync // doesn't exists

		SendRPC(toplayerid, RPC_ApplyAnimation, bsAnim); // Pre-load?
		SendRPC(toplayerid, RPC_ApplyAnimation, bsAnim);
	}

}

// Sync
public OnPlayerStreamIn(playerid, forplayerid) {

	ApplyAnimationSync( playerid, forplayerid );
	ApplyAnimationSync( forplayerid, playerid );

	return 1;
}
NOTE: Remember to use ApplyAnimationEx() and ClearAnimationsEx() instead of ClearAnimations()

That you need is the new RPC for ApplyActorAnimation to make it work with Actors – or SA-MP team adds OnActorStreamIn, ApplyActorAnimationForPlayer and ApplyAnimationForPlayer to avoid plugins and network manipulation (and others workarounds).

Regards.
Reply
#4

I really hope this gets fixed. It would give actors much more possibilities.
Reply
#5

It's only RC, it will most likely be fixed when more features are added for actors. There are many actor controls that are not added yet but do exist in GTA, I bet some will be added soon.
Reply
#6

Quote:
Originally Posted by Crayder
View Post
It's only RC, it will most likely be fixed when more features are added for actors. There are many actor controls that are not added yet but do exist in GTA, I bet some will be added soon.
This problem exists for NPCs too though, and they've been in SA-MP for years.
Reply
#7

Quote:
Originally Posted by PeppeAC
View Post
A callback such as OnActorStreamIn will fix it
or timer and IsActorStreamedIn
Reply
#8

Untested: Try setting all streamed (close) players virtual worlds to something random then back to the correct one. This may restream the player.
Reply
#9

Quote:
Originally Posted by MP2
View Post
This problem exists for NPCs too though, and they've been in SA-MP for years.
This is true but I really hope they do something about it as we would have to make snippets just to make an OnActorStreamIn then reapply animations (but then what about players who are already streamed in and watching the animation? it will be reset)... It's some simple functions that could be added to make sa-mp easier to go with.. but nobodu knows why they aren't added.

In NPCS it can be solved very easily (but the same issue that I stated above is still there).

pawn Code:
public OnPlayerStreamIn(playerid)
{
    SendCommand("/kcnrnpcanimation");
    return 1;
}

public OnNPCSpawn()
{
    SendCommand("/kcnrnpcanimation");
    return 1;
}
Thats what I use to combat the issue, whenever a play streams in for the NPC... play the animation but this is only for idle NPCs.
Reply
#10

Quote:
Originally Posted by PeppeAC
View Post
A callback such as OnActorStreamIn will fix it
Quote:
Originally Posted by Kalcor
View Post
SA-MP 0.3.7 RC

The 0.3.7 RC is a testing version for an update to SA-MP's 0.3 branch. The official release will come once the testing phase is complete.

Updates:

SA-MP 0.3.7 RC6-2 Optional server update

- Fixes the DestroyActor() function.
- Adds OnActorStreamIn/OnActorStreamOut.
Looks like that's fixed.
Reply


Forum Jump:


Users browsing this thread: