Bản thân tôi, tôi thích giải quyết điều này bằng cách nghĩ tất cả các chuyển động của người chơi là dựa trên gia tốc.
Tôi chọn tốc độ mục tiêu bằng bất kỳ logic điều khiển phức tạp nào tôi thích, sau đó yêu cầu avatar của người chơi tăng tốc về phía mục tiêu đó, đồng thời tôn trọng tốc độ tăng tốc tối đa tôi đặt.
Sau đó, tùy thuộc vào trạng thái của hình đại diện (trên mặt đất, trên băng, trên không, ở trạng thái phản hồi), tôi có thể thay đổi các tốc độ tăng tốc đó để làm cho đầu vào điều khiển có tác động sắc nét hơn hoặc ít rõ rệt hơn.
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);
}
Việc tách tốc độ tăng tốc và giảm tốc như thế này cho phép tôi cho lực phanh sắc nét hơn, điều này có xu hướng giúp các điều khiển cảm thấy chặt chẽ và phản ứng nhanh khi dừng hoặc thay đổi hướng, trong khi vẫn giữ tốc độ mượt mà để tăng tốc. Nó cũng cho phép bạn xử phạt phanh cụ thể khi ở trên băng hoặc bị đẩy lùi.
Chúng ta có thể tạo một đối tượng tham số trạng thái điều khiển để giữ tốc độ tối đa, gia tốc và tốc độ giảm tốc cho các trạng thái không khí, mặt đất, băng, phản hồi, v.v. và sử dụng điều này để điều chỉnh xử lý điều khiển rất linh hoạt:
// 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
);