【Unity】Rigidbody.GetAccumulatedForce()の解説と使用例(キャラのジャンプ処理)


解説

GetAccumulatedForce()は、前回の物理シミュレート以降にAddForce()で加えた力の合計を返します。この力はまだrigidbody.velocityに反映されておらず、次の物理シミュレートで反映されます。
m (質量) × a (加速度) = F (加えた力) なので、次のrigidbody.velocityは以下のようになるでしょう。

次のrigidbody.velocity = 今のrigidbody.velocity + rigidbody.GetAccumulatedForce() / rigidbody.mass * Time.fixedDeltaTime;

GetAccumulatedForce()の結果に重力が入ってないので多少ずれるかもしれません。

使用例:固定速度でジャンプする

ゲームのキャラクターの物理を実装するとき、ジャンプ処理って割と異色なんですよね。
歩行・ノックバック・風圧などの移動処理はとにかくAddForce()しておけばイイ感じの物理になりますが、ジャンプ処理は物理法則を無視したいことが多いです。空中の多段ジャンプなど、慣性を無視して毎回同じ速度で上昇したいのです。
単にAddForce(JumpSpeed)と実装すると、落下速度などの外部要因によってジャンプの高さが毎回変わってしまうので、以下のように実装しました。

// やりたいこと:
// rb.AddForce( velocity.yの打ち消し + 加速度.yの打ち消し + ジャンプ速度 );

public void Jump()
{
    var accVelocity = rb.GetAccumulatedForce() / rb.mass * Time.fixedDeltaTime;
    rb.AddForce(Vector3.up * (-rb.velocity.y - accVelocity.y + JumpSpeed), ForceMode.VelocityChange);
}
  • Q:公式でも言及されている通り、ジャンプ処理だけはrigidbody.velocity.yを上書きして良いのでは?

  • A:シンプルな実装ならそれでも良いです。
    私はこの処理の前にバネによるAddForce()処理を実装しており、着地と同時にジャンプすると 上書きしたvelocity + バネの反発力 となり予定より高くジャンプしてしまいました。バネの反発力を消したかったので今回のように実装しました。


いいなと思ったら応援しよう!