Sixze / ALS-Refactored

Completely reworked and improved C++ version of Advanced Locomotion System V4.
MIT License
943 stars 261 forks source link

Support character move forward and backward with different speed. #489

Closed watsonsong closed 2 months ago

watsonsong commented 4 months ago

Support character move forward and backward with different speed. It let the backword movement can be slower.

Sixze commented 4 months ago

Have you tested this in multiplayer? I have doubts that it will work correctly there.

watsonsong commented 4 months ago

Have you tested this in multiplayer? I have doubts that it will work correctly there.

I test in PIE mode with 'Play as Listen Server' and 'Play as Client'(pure dedicated server). It seems animation and speed is correct when backward.

Sixze commented 4 months ago

I test in PIE mode with 'Play as Listen Server' and 'Play as Client'(pure dedicated server). It seems animation and speed is correct when backward.

But what about network simulation?

onx2 commented 4 months ago

I'm handling this in the Input_OnMove function, as well as strafe speed. In my use case, I don't mind the sprint being a jog while moving backward, rather than the character turning into that direction at full speed.

void AAlsCharacterExample::Input_OnMove(const FInputActionValue& ActionValue)
{
    const auto Value{UAlsMath::ClampMagnitude012D(ActionValue.Get<FVector2D>())};

    const auto ForwardDirection{UAlsMath::AngleToDirectionXY(UE_REAL_TO_FLOAT(GetViewState().Rotation.Yaw))};
    const auto RightDirection{UAlsMath::PerpendicularCounterClockwiseXY(ForwardDirection)};

    float XSpeed = Value.X;
    float YSpeed = Value.Y;
    const bool bBackward = YSpeed < UE_SMALL_NUMBER;

    const bool bStrafe = FMath::IsNearlyZero(YSpeed) && !FMath::IsNearlyZero(XSpeed);

    if (bBackward)
    {
        XSpeed *= 0.5f;
        YSpeed *= 0.5f;
    }
    else if (bStrafe)
    {
        XSpeed *= 0.75f;
    }

    AddMovementInput(ForwardDirection * YSpeed + RightDirection * XSpeed);
}
watsonsong commented 4 months ago

I'm handling this in the Input_OnMove function, as well as strafe speed. In my use case, I don't mind the sprint being a jog while moving backward, rather than the character turning into that direction at full speed.

void AAlsCharacterExample::Input_OnMove(const FInputActionValue& ActionValue)
{
  const auto Value{UAlsMath::ClampMagnitude012D(ActionValue.Get<FVector2D>())};

  const auto ForwardDirection{UAlsMath::AngleToDirectionXY(UE_REAL_TO_FLOAT(GetViewState().Rotation.Yaw))};
  const auto RightDirection{UAlsMath::PerpendicularCounterClockwiseXY(ForwardDirection)};

  float XSpeed = Value.X;
  float YSpeed = Value.Y;
  const bool bBackward = YSpeed < UE_SMALL_NUMBER;

  const bool bStrafe = FMath::IsNearlyZero(YSpeed) && !FMath::IsNearlyZero(XSpeed);

  if (bBackward)
  {
      XSpeed *= 0.5f;
      YSpeed *= 0.5f;
  }
  else if (bStrafe)
  {
      XSpeed *= 0.75f;
  }

  AddMovementInput(ForwardDirection * YSpeed + RightDirection * XSpeed);
}

This is a good method. Simple enough and not Intrusion. But is it safe for dedicated server. Can the client may modify the backward and strafe speed, and the server can not detect it?

onx2 commented 4 months ago

@watsonsong I'm fairly new to game development, especially networked game development, so I don't think I can speak to that with 100% certainty. However, my intuition tells me that it wouldn't be a problem because if they were able to modify this code than no matter what logic we put here there could be issues. For example, if they somehow got access to modify this code freely, even without my additions, what is stopping them from changing it to:

AddMovementInput(ForwardDirection * 99999999 + RightDirection * 9999999);

My change is just scaling down the input provided by the player so I think it should be fine in any situation. But please do your own research if you are feeling uneasy about it.

watsonsong commented 4 months ago

I means the only safe place is our dedicated server. And the client may be modified by any way. In the bad case, the cheater can make move backward as the speed as the forward movement.

onx2 commented 4 months ago

I'm not sure I follow, as this is client-side code, so there is the same potential for cheating with or without a multiplier. You should always run validation on the server.

watsonsong commented 4 months ago

Yes that what I mean. The server does not known anything about the speed multiplier. So it possible to cheating with it. So I think It may better the limit the speed on the movement logic.