Improbable Icon

Transform Synchronization module and player input to move player

Hi,
I configured Transform Synchronization properly. Everything works fine. The position of transforms are sync… but now I have problems with movement my player. On Development scene everything is fine. When I build Standalone client the player moves 30x faster and the movement is not smooth you can see hudge steps. Someting like get 100 inputs and merge them into one packet and send to the server.

How should I handle the movement?

Video presentation:

Schema file:

package test.player;
import "test/Common.schema";
type Joystick {
    float x_axis = 1;
    float y_axis = 2;
    bool jump = 3;
}

component PlayerInput {
    id = 1004;
    Joystick joystick = 1;
}

Client movement:

using BlankProject;
using Improbable.Gdk.Core;
using Improbable.Gdk.Subscriptions;
using Test.Player;
using UnityEngine;

[WorkerType(UnityClientConnector.WorkerType)]
public class PlayerInputSender : MonoBehaviour
{

    [Require] PlayerInputWriter playerInputWriter;


    bool moved = false;
    void Update()
    {
        var xAxis = Input.GetAxis("Horizontal")*10;
        var yAxis = Input.GetAxis("Vertical")*20;
        var jump = Input.GetButton("Jump");

        Vector3 dir = new Vector3(xAxis, 0f, yAxis);
        dir = Camera.main.transform.TransformDirection(dir);
        dir.y = 0.0f;

        if (IsAnyMovement(xAxis, yAxis, jump))
        {
            playerInputWriter.SendUpdate(new PlayerInput.Update
            {
                Joystick = new Option<Joystick>(new Joystick(dir.x, dir.z, jump))
            });
            moved = true;
        }
        else
        {
            if (moved)
            {
                playerInputWriter.SendUpdate(new PlayerInput.Update
                {
                    Joystick = new Option<Joystick>(new Joystick(0, 0, false))
                });
                moved = false;
            }
        }

    }

    bool IsAnyMovement(float x, float y, bool jump)
    {
        return Mathf.Abs(x) > 0.1f || Mathf.Abs(y) > 0.1f || jump;
    }

}

Server movement:

using System;
using BlankProject;
using Improbable;
using Improbable.Gdk.Subscriptions;
using Test.Player;
using UnityEngine;

[WorkerType(UnityGameLogicConnector.WorkerType)]
public class PlayerMover : MonoBehaviour
{
    [Require] private PlayerInputReader playerInputReader;
    public float speed = 6.0f;
    public float jumpSpeed = 8.0f;
    public float gravity = 20.0f;

    [SerializeField] float m_MovingTurnSpeed = 360;
    [SerializeField] float m_StationaryTurnSpeed = 180;
    float m_ForwardAmount;
    float m_TurnAmount;
    private CharacterController c;

    private void OnEnable()
    {
        c = GetComponent<CharacterController>();
        c.enabled = true;
        playerInputReader.OnJoystickUpdate += PlayerInputReaderOnJoystickUpdate;
    }

    void PlayerInputReaderOnJoystickUpdate(Joystick joystick)
    {
        HandleMovement(joystick);
    }

    void HandleMovement(Joystick joystick) {
        var direction = new Vector3(joystick.XAxis, 0, joystick.YAxis);
        if (direction.sqrMagnitude > 1) {
            direction.Normalize();
        }

        Debug.Log("Joystick " + joystick.XAxis + " " + joystick.YAxis);
        if (c.isGrounded) {
            direction *= speed;

            if (joystick.Jump) {
                direction.y = jumpSpeed;
            }
        }


        ApplyExtraTurnRotation(direction);


        // Apply gravity. Gravity is multiplied by deltaTime twice (once here, and once below
        // when the moveDirection is multiplied by deltaTime). This is because gravity should be applied
        // as an acceleration (ms^-2)
       // direction.y -= gravity * Time.deltaTime;

        // Move the controller
        c.Move(direction * Time.deltaTime);
    }

    void ApplyExtraTurnRotation(Vector3 move)
    {

        if (move.magnitude > 1f) move.Normalize();
        move = transform.InverseTransformDirection(move);
        move = Vector3.ProjectOnPlane(move, Vector3.up);
        m_TurnAmount = Mathf.Atan2(move.x, move.z);
        m_ForwardAmount = move.z;


        // help the character turn faster (this is in addition to root rotation in the animation)
        float turnSpeed = Mathf.Lerp(m_StationaryTurnSpeed, m_MovingTurnSpeed, m_ForwardAmount);
        transform.Rotate(0, m_TurnAmount * turnSpeed * Time.deltaTime, 0);
    }


    void FixedUpdate()
    {
        m_ForwardAmount = 0;
        if (!c.isGrounded) {
            var direction =new Vector3(0, -gravity * Time.deltaTime, 0);
            c.Move(direction * Time.deltaTime);
        }
    }
}
1 Like

Hello @Wader,

If you move the client that’s running in the editor (i.e. the orange client) the behaviour is the same?

Hi,
The client movement in editor was correct.

I figured it out. There was problem with FixedUpdate() and the Time.deltaTime instead of fixedDeltaTime.

1 Like

I am also working on Transform Sync. Can you give me some advice?


:laughing: :laughing: