Locomotion animation syncing across network.

Okay, I’m currently at work, so I can’t get any screenshots or code examples, but I can try and explain this as best I can.

Background

I have already written my networking system - my game was originally a FPS, now I want it be third person instead - the locomotion system is fantastic for this purpose. On my local game, I can move around, stand still and look over my shoulder and all the other bits work fine. (By the way, I used the locomotion demo with the guy shooting an orb thing flying round as a base for this project). The player prefab has been modified to have its own self contained “AimTarget” so that each player SHOULD be a self-contained prefab, including the local player. This all works fine.

Player Movement
I have a script to handle the movement of players. For the local player, it sends an RPC to the other machines. For remote objects, the script takes the postiion from the RPC and Interpolates to smooth the movement of the players transform - This works perfectly.

THE PROBLEM / TL:DR
When I connect two players to the same server, they both “move” correctly - their positions and rotations are correct - they even aim correctly (because of the AimTarget used by the locomotion demo). The problem is the animations are not synced - when I use WASD on one of the players - the remote players object in my game copies my animation - this is a simple case of using networkView.isMine to disable my local player applying animations to ALL the players in the scene - this has been partially fixed, but the problem is now that the remote players “clones” are ‘dragged’ around - its as if the script is moving the player’s root transform, but none of the animations like “walk” and “run” are playing at all.

I sort of know how to fix this, I need to check if the remote players clone is receiving any movement from the owner - if the owners position has changed, apply the desired animation, but I’m not sure if there is an easier or nicer way of doing this and I also cannot find HOW to change the animation states as there are lots of “weights” all being manipulated, but I cannot find where in the scripts.

I’m sorry about the description, It’s a really tricky problem to explain.

I figured this out, and wanted to provide an answer to people looking for a similar problem… By default, locomotion calculated the velocity of the player an sets the animation depending on the velocity e.g. if velocity = 0, play the idle animation etc.

However, the system also by default uses the following code to calculate the velocity:

if (m_CharacterController!=null) {
			Vector3 ccVelocity = m_CharacterController.velocity;
			m_Velocity = ccVelocity;
			
			m_AngularVelocity = CalculateAngularVelocity(m_RotationPrev, m_Rotation);
		}
		else if (m_RigidBody!=null) {
			// Rigidbody velocity is not reliable, so we calculate our own
			m_Velocity = (m_Position-m_PositionPrev)/Time.deltaTime;
			
			// Rigidbody angularVelocity is not reliable, so we calculate out own
			m_AngularVelocity = CalculateAngularVelocity(m_RotationPrev, m_Rotation);
		}
else
{
m_Velocity = (m_Position-m_PositionPrev)/Time.deltaTime;
			
			m_AngularVelocity = CalculateAngularVelocity(m_RotationPrev, m_Rotation);
}

The problem is the first if statement one - we want the system to use the transform.position, not the character controller (remember, these are REMOTE players, we don’t need to control them). If you replace the last else statement with this, it should work:

// only use the transform as the movement detection for the remote players.
// the updatemovementforplayers script will move the remote player, and this bit
// of code will detect the velocity and set the correct animations
		if (networkView.isMine == false){
			m_Velocity = (m_Position-m_PositionPrev)/Time.deltaTime;
			
			m_AngularVelocity = CalculateAngularVelocity(m_RotationPrev, m_Rotation);
		}

This might help someone.