Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

watsonsong
Copy link
Contributor

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

}

if (Gait == AlsGaitTags::Running)
{
return RunSpeed;
return FMath::GetMappedRangeValueClamped(FVector2d(-1, 0),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use floating point literals, such as 0.0f.

float RunForwardSpeed{375.0f};

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ALS", Meta = (ClampMin = 0, ForceUnits = "cm/s"))
float RunBackwardSpeed{275.0f};
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the default backward speed the same as the forward speed.

@@ -991,12 +996,12 @@ FGameplayTag AAlsCharacter::CalculateActualGait(const FGameplayTag& MaxAllowedGa
// different from the desired gait or max allowed gait. For instance, if the max allowed gait becomes
// walking, the new gait will still be running until the character decelerates to the walking speed.

if (LocomotionState.Speed < AlsCharacterMovement->GetGaitSettings().WalkSpeed + 10.0f)
if (LocomotionState.Speed < AlsCharacterMovement->GetWalkSpeed() + 10.0f)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is wrong. You should use WalkForwardSpeed instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is means calculate the gait alway use the forwad speed, even if the actor is walking backward?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, then there should be a condition that will select WalkForwardSpeed or WalkBackwardSpeed depending on the movement direction. The GetWalkSpeed() function still cannot be used, since it does not return the maximum speed.

const auto RelativeVelocityDirection{
LocomotionState.RotationQuaternion.UnrotateVector(LocomotionState.Velocity).GetSafeNormal()
};
AlsCharacterMovement->SetRelativeVelocityDirection(RelativeVelocityDirection);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can access the velocity and capsule rotation directly in the character's movement component.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the 'CalcVelocity' a good place to calculate this vector and update new max walk speed?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may not even need to cache this value, just create a function in the character movement component that will calculate this value on the fly and use it.

@Sixze
Copy link
Owner

Sixze commented May 1, 2024

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

@watsonsong
Copy link
Contributor Author

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
Copy link
Owner

Sixze commented May 6, 2024

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
Copy link

onx2 commented May 9, 2024

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
Copy link
Contributor Author

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
Copy link

onx2 commented May 10, 2024

@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
Copy link
Contributor Author

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
Copy link

onx2 commented May 11, 2024

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
Copy link
Contributor Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants