私が最初に提案したのは、オブジェクトの速度を手動で追跡することを避けることでした。Unityの物理システムでは、これを正確にRigidbody.velocity.magnitude
に簡単にアクセスできます。これを使用してmaxSpeed
と比較して、追加の力を加えるべきかどうかを判断することができます。
速度がf(x)=sqrt(x)
のカーブに一致するようにしたい場合は、このためにいくつかの基本的な計算を行う必要があります。人為的に速度を制限したくないので(物理的なやりとりを起こさせたいので)、その代わりにアクセラレーションを関数に制約する必要があります。
プレーヤーの加速度を定義する関数を決定するには、速度を(理想的には)一致させる関数を導出する必要があります。これは、指定されたポイントでの速度の変化率を与えます。これは定義上、加速です。
ここでは、理想速度のモデルとして関数f(x)=sqrt(x)
を使用します。 sqrt(x)
の派生は1/(2 * sqrt(x))
です - これは私たちの加速を定義する関数です。ここでは、与えられた速度の加速度を決定する必要があります。これは、コード内で使用する関係であるためです。これは少し簡単な代数を取る - 私たちは、与えられたy
x
のために解決する必要があります
y = 1/(2 * sqrt(x))
sqrt(x) * y = 1/2
sqrt(x) = 1/(2 * y)
x = (1/(2 * y))^2
今、私たちは、任意のスピードに必要な加速を提供してくれます方程式を持っています。私たちは今、コードにこれを置くことができます - maxSpeed
までの平方根関数に従って加速:
float maxAcceleration = 10;
// Basically x = (1/(2 * y))^2, but in code
float CalculateAccGivenSpeed(float speed)
{
// Early exit so we don't bother with undefined results from dividing by 0
if (speed == 0)
{
return Mathf.Infinity;
}
float rootAcc = 1/(2 * speed);
return rootAcc * rootAcc;
}
void FixedUpdate()
{
// Only accelerate if speed is lower than maximum allowed
if (rb.velocity.magnitude < maxSpeed)
{
float allowableAcc = CalculateAccGivenSpeed(rb.velocity.magnitude);
// Constrain acceleration here so rigidbody doesn't explode from stationary
allowableAcc = Mathf.Min(maxAcceleration, allowableAcc);
// Using ForceMode.Acceleration so we don't have to worry about mass
rb.AddForce(transform.forward * allowableAcc, ForceMode.Acceleration);
}
}
加速度があまりにも速く/ゆっくり行くあなた見つけた場合、あなたはスカラー値でCalculateAccGivenSpeed()
の結果を掛けることができます。数学的には、平方根関係を維持しながら、与えられたy値(速度)に達する速度を変えながら、平方根関数をy軸に沿ってスケーリングします。
希望すると便利です。ご質問がある場合はお知らせください。
私はあなたがここでやっていることと少し混乱しています。なぜあなたは加速*質量のようなものではなく、 'AddForce()'で速度を使用していますか?なぜあなたは 'AddForce()'を独自のアクセラレーション実装と混ぜていますか?あなたのスクリプトはどのようにあなたが望むものではありませんか? – Serlite
@Serlite私はそれが少し複雑であることを知っていますが、私はこのスクリプトを何度も変更してしまい、変数名が間違っています。 'speed'は開始時に設定され、' maxSpeed'に達するまで増加し、プレーヤーの実際の速度を制御しません。私は 'Addforce()'を使用しています。なぜなら、プレイヤーは何かをヒットするときにスローダウンしたいからです。 –
ここで物理システムを間違って使用しているような気がします。剛体の速度のより正確な表現は 'velocity.magnitude'です。これを 'maxSpeed'と比較することで、さらに力を加えるべきかどうかを判断できます。手動で' speed'変数を追跡する必要はありません。 – Serlite