PUN Classic (v1), PUN 2 and Bolt are in maintenance mode. PUN 2 will support Unity 2019 to 2022, but no new features will be added. Of course all your PUN & Bolt projects will continue to work and run with the known performance in the future. For any upcoming or new projects: please switch to Photon Fusion or Quantum.

RPG Movement Demo

In this demo we are going to synchronize basic movement of a character using Photon. The new PhotonTransformView component gives us many options to dial in the movement and make it look as smooth for a remote character as it is for the local one.

This demo also shows how animation can be synchronized without sending any animation specific data. The animator is set up to react to changes in movement and since the movement is synchronized, the appropriate animations can still be played.

Screenshot of RPG Movement Demo
Animated Demo Characters

The character for the demo is the prefab "Robot Kyle Mecanim". On it you see PUN's components and the script IdleRunJump, which applies user-input to the character.

The mecanim demo makes use of the PhotonAnimatorView which explicitly sends animation data.

Mecanim Animator Setup

This demo shows how you can synchronize animation without actually sending any animation specific data. The RPGMovement class implements the movement and animation behaviour for this demo and its Update() function is setup like this:

    void Update()
        if( m_PhotonView.isMine == true )


The movement is only handled if this object actually belongs to the player and the networked movement is handled by PhotonTransformView

However, we still update the animations for remote objects. The Animator has several parameters setup, the ones that are relevant for the movment animation are Speed and Direction.

We calculate these values based on the difference between the position the character was in during the last update and the most current position.

    void UpdateAnimation()
        Vector3 movementVector = transform.position - m_LastPosition;

        float speed = Vector3.Dot( movementVector.normalized, transform.forward );
        float direction = Vector3.Dot( movementVector.normalized, transform.right );

        m_Animator.SetFloat( "Speed", speed );
        m_Animator.SetFloat( "Direction", direction );

        m_LastPosition = transform.position;

Using the character's forward vector, we can then determine differences in speed and direction and pass them on to the Animator. By calculating these values based on the position, any position update received from PhotonTransformView is also used in this calculation and therefore the animation works for synchronized objects.

To Document Top