Ich selbst löse dieses Problem gerne, indem ich mir alle Spielerbewegungen als beschleunigungsbasiert vorstelle.
Ich wähle eine Zielgeschwindigkeit unter Verwendung einer beliebigen komplizierten Steuerlogik und fordere den Spieler-Avatar auf, auf dieses Ziel zu beschleunigen, wobei ich die von mir festgelegten maximalen Beschleunigungsraten einhalte.
Abhängig vom Zustand des Avatars (am Boden, auf Eis, in der Luft, in einem Rückstoßzustand) kann ich diese Beschleunigungsraten ändern, damit die Steuereingabe einen schärferen oder weniger ausgeprägten Einfluss hat.
Rigidbody2D body;
void AccelerateTowards(Vector2 targetVelocity, float maxAccel, float maxDecel) {
// Compute desired velocity change.
var velocity = body.velocity;
var deltaV = targetVelocity - velocity;
// Convert our velocity change to a desired acceleration,
// aiming to complete the change in a single time step.
// (For best consistency, call this in FixedUpdate,
// and deltaTime will automatically give fixedDeltaTime)
var accel = deltaV / Time.deltaTime;
// Choose an acceleration limit depending on whether we're
// accelerating further in a similar direction, or braking.
var limit = Dot(deltaV, velocity) > 0f ? maxAccel : maxDecel;
// Enforce our acceleration limit, so we never exceed it.
var force = body.mass * Vector2.ClampMagnitude(accel, limit);
// Apply the computed force to our body.
body.AddForce(force, ForceMode2D.Force);
}
Wenn ich die Beschleunigungs- und Verzögerungsraten wie diese trenne, kann ich eine schärfere Bremskraft erzeugen, die dazu beiträgt, dass sich die Bedienelemente beim Anhalten oder Ändern der Richtung straff und reaktionsschnell anfühlen, während eine gleichmäßige Beschleunigung beibehalten wird, um auf die Geschwindigkeit zu kommen. Außerdem können Sie das Bremsen besonders dann bestrafen, wenn Sie sich auf Eis befinden oder zurückgestoßen werden.
Wir können ein Steuerzustandsparameterobjekt erstellen, um die Höchstgeschwindigkeit, Beschleunigungs- und Verzögerungsraten für unsere Luft-, Boden-, Eis-, Rückstoßzustände usw. zu halten, und dies verwenden, um unser Steuerungshandling sehr flexibel anzupassen:
// Choose our current speed / acceleration parameters based on our state.
var controlState = GetCurrentControlState();
// Compute desired velocity.
var velocity = GetDesiredVelocityFromInput(controlState.maxSpeed);
// Try our best to reach that velocity, with our current parameters.
AccelerateTowards(
velocity,
controlState.maxAccel,
controlState.maxDecel
);