Unity Networking Synced Player Movement

Hi all,

I’m using the standard Unity networking, but I’m having issues with syncing the player movement. I understand I have to use Vector3.Lerp() and some other odd things that I do not understand, but after following a guide I cannot get it to work. My PlayerPrefab is using a CharacterController, so accessing a RigidBody wouldn’t obviously work.

I took code from a tutorial that uses a rigidbody, and then transformed it to use the PlayerPrefab’s transform and the CharacterController’s velocity.

    private float lastSynchronizationTime = 0f;
    private float syncDelay = 0f;
    private float syncTime = 0f;

    private Vector3 syncPosition = Vector3.zero;
    private Vector3 syncVelocity = Vector3.zero;
    private Quaternion syncRotation = Quaternion.identity;
   
    private Vector3 syncStartPosition = Vector3.zero;
    private Vector3 syncEndPosition = Vector3.zero;   
// Update is called once per frame
    void Update () {
        if (networkView.isMine)
        {
            UpdateMovement();
        }
        else
        {
            SyncedMovement();
        }
    }

    void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
    {
        if (stream.isWriting)
        {
            syncPosition = transform.position;
            stream.Serialize(ref syncPosition);
           
            syncVelocity = GetComponent<CharacterController>().velocity;
            stream.Serialize(ref syncVelocity);

            syncRotation = transform.rotation;
            stream.Serialize(ref syncRotation);
        }
        else
        {
            stream.Serialize(ref syncPosition);
            stream.Serialize(ref syncVelocity);
            stream.Serialize(ref syncRotation);

            transform.position = syncPosition;
            transform.rotation = syncRotation;

            syncTime = 0f;
            syncDelay = Time.time - lastSynchronizationTime;
            lastSynchronizationTime = Time.time;
           
            syncEndPosition = (syncPosition + syncVelocity) * syncDelay;
            syncStartPosition = transform.position;
        }
    }
   
    void SyncedMovement()
    {
        syncTime += Time.deltaTime;
        transform.position = Vector3.Lerp(syncStartPosition, syncEndPosition, syncTime / syncDelay);
    }

Yes, some of the code is missing. I have only provided the Network Syncing section of the player controller.

Bump

There is an example in the Unity Wiki : http://wiki.unity3d.com/index.php?title=NetworkView_Position_Sync

or more simply using lerp : [PUN] Syncing Rigidbodies across network. - Questions & Answers - Unity Discussions

Neither of these worked for my code. I’m not using Photon, and I’m not using a RigidBody. Both of these samples of code make my character “flicker” on the other screen, but in the editor it always says other connected players are at Vector3(0, 0, 0);

I was able to get everything working just fine. Following How to create an online multiplayer game with Unity - Paladin Studios
I took the syncing part of their code and modified it to use transform instead of RigidBodies, and then after doing that, and seeing that the code still did not work, I realized I had to have my NetworkView observe the Sync Script, not Transform. Derp.

Thanks for the help though.

Really wasn’t any help given. Glad you got it figured out. I’m checking out your link now!

edit : already bookmarked! And its not Photon. Nice one.

If you do end up using that link, and you end up not using a RigidBody (Meaning you use a CharacterController, or a custom CC) you’ll need to replace, as I said, all the RigidBody’s with transform, and use GetComponent().velocity to get the Velocity for prediction.