Unable to apply rotation to movement on a Client side player. Using BOLT and ExecuteCommand method.

Soares
Soares
edited December 2020 in Photon Bolt
Hi!! So, I was able to apply Authoritative Movement to my player instance, but there is a problem. On my player i use my mouse yaw (more preciselly my camera rotation) and multiply that rotation to the movement direction, so my player always walks forward to were my camera is poiting. This works really fine on Server side player, but when I try it on my Client side player, it performs the movement and jumping normally, but just along the XYZ World Axis. Someow BOLT is ignoring my player's rotation, it's not replicating it aswell!
Server Side Player example:
Server-Player.gif
Client Side Player example:
Client-Player-min.gif
My BOLT Asset "PlayerCommand":
Player-Command.jpg

Here's my Player Motor Move() if it can help:

Called in ExecuteCommand, passing the PlayerCommand inputs
public State Move(float horizontal, float vertical, bool jump, float yaw)
{
isGrounded = Physics.CheckSphere(groundChecker.position, GroundDistance, Ground, QueryTriggerInteraction.Ignore);

if(isGrounded && state.velocity.y < 0)
{
state.velocity.y = -2f;
}

direction = new Vector3(horizontal, 0f, vertical).normalized;

if (direction.x != 0f || direction.z != 0f)
{
if(cinemachine != null)
{
angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, yaw, ref turnSmoothVelocity, turnSmoothTime);

It's here were I multiply my mouse yaw by the direction
direction = Quaternion.Euler(0f, yaw, 0f) * direction;
}

cc.Move(direction.normalized * speed * BoltNetwork.FrameDeltaTime);
}

state.velocity = direction.normalized * speed;

if (jump && isGrounded)
{
state.velocity.y = Mathf.Sqrt(jumpForce * -2f * gravity);
}

if (!isGrounded && velocity.y < 0)
{
state.velocity.y += gravity * 1.5f * BoltNetwork.FrameDeltaTime;
}
else
{
state.velocity.y += gravity * BoltNetwork.FrameDeltaTime;
}

cc.Move(state.velocity * BoltNetwork.FrameDeltaTime);

Here I rotate my player, but Bolt wont allow it!
transform.localRotation = Quaternion.Euler(0, angle, 0);

state.position = transform.localPosition;
state.isGrounded = isGrounded;

return state;

}

Waiting for someone to help me! Thank you!

Comments

  • You may want to start with how rotation/turning works in the server auth player example and make changes based off of that
    https://github.com/BoltEngine/Bolt-Sample/blob/1bf755b65eff12c0e0bfa880cc8c7690621f46f6/AdvancedTutorial/scripts/Player/PlayerMotor.cs#L187
  • Soares
    Soares
    edited December 2020
    That's what I've been doing. But I can't see any difference. Do you think I need a Quaternion Result on my PlayerCommand, for it to save the rotation on a state and apply it? The PlayerMotor does not do that but I could give it a try!


    Edit: Ok! I noticed that the problem is that BOLT it's not replicating my rotation over the network, it replicates in the server auth player example, but not in mine. I'm gonna see what's going on!
  • stanchion wrote: »
    You may want to start with how rotation/turning works in the server auth player example and make changes based off of that
    https://github.com/BoltEngine/Bolt-Sample/blob/1bf755b65eff12c0e0bfa880cc8c7690621f46f6/AdvancedTutorial/scripts/Player/PlayerMotor.cs#L187

    I've lost more than 30h in this bug and I didnt found a fix yet :(
    What is happening is that I'm using Authoritative Movement with Client Side Prediction, and the server verification doesn't like that I multiply my Quaternion yaw rotation by the direction Vector3. So, on the resetState the server adjusts just only to the direction Vector3 without the Quaternion rotation multiplied, like if I just pressed to walk and didnt yaw the mouse.
    I've already fixed the rotation has you said in the answer above, so, the rotation is being well replicated, but still, I can only move on those world like axis.
    What do you think this could be?

    I could try to implement a Non-predicted Authoritative Movement, but it seems to replicate badly, because in my client the walk speed goes super fast and gets replicated as normal speed on other clients! I'm really stuck here.
  • SOLUTION!!!
    In Predicted Authoritative Movement, in my expecific case, BOLT didn't let me Move my player with my character controller with directions I calculated inside the ExecuteCommand Move() function (so, inside my PlayerMotor.cs).
    For example, I wasn't able to rotate my player in transform.localRotation = Quaternion.Euler(0, angle, 0); because angle was calculated here inside the Move() angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, yaw, ref turnSmoothVelocity, turnSmoothTime);. This happened also on the direction. As I was calculating the direction multiplied with the mouse rotation here direction = Quaternion.Euler(0f, yaw, 0f) * direction;, BOLT didn't like that I was changing the direction inside this method, because I only had the input for direction forward/backward, and sideways, so in the ResetState he would reset the player again to the direction as if I was only making a direction = new Vector3(horizontal, 0f, vertical).normalized;.

    So... this is the fix. Instead of calculating those inside the Move() method, I calculated them before passing the input, and created a new input for them, so this way, it was a movement input already queued to the server:

    IPlayerCommandInput input = PlayerCommand.Create();

    input.Horizontal = horizontal;
    input.Vertical = vertical;
    input.Jump = jump;
    input.Yaw = yaw;

    Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;
    if ((direction.x != 0f || direction.z != 0f) && myCamera != null)
    {
    direction = Vector3.Normalize(Quaternion.Euler(0, yaw, 0) * direction);
    }

    input.Direction = direction;

    entity.QueueInput(input);


    If you are having problems with server resets remember passing the already calculated input for the character controller to just move. :)