プレーヤーオブジェクトを処理するとき、ベロシティとaddForceをいつ使用する必要がありますか?


18

Unityフレームワークのこれら2つのメソッドについて混乱しています。どちらもプレーヤーオブジェクトを移動、停止、方向変更などします。一方を他方の上で使用する必要がある場合と、適切な場合はいつですか。



@ Byte56両方の質問が異なることを尋ねている
ロバート

1
異なるが、関連している。そのため、それらはリンクされているだけで、複製ではありません。右側のリンク列に表示されます。
マイケルハウス

回答:


13

あなたは使うだろうvelocity(例えば弾丸)を一定の速度でオブジェクトを移動するとAddForce()(例えば宇宙船スラスタを)運動を追加します。また、移動には2つの「タイプ」があることに注意してください。力と衝動。宇宙船のスラスタには、衝動を使用します。


4
宇宙船スラスタの衝動を好む理由を説明できますか?これは、武器の衝撃などによる瞬間的な運動量の変化ではなく、時間の経過とともに徐々に加速する場合、実際には理想的ではないかもしれません。瞬時にあなたが衝動を使用すると思いながら(あなたは質量が要因であることをしたくない場合や加速度)あなたは、一般的に力をお勧めします時間ウィンドウの上に塗布(それに対応し、または、velocityChange)
DMGregory

@DMGregoryええ、それは追加したい種類の力に依存します。瞬間的なエネルギーの爆発である宇宙船スラスタの私の例では、インパルスが正しい選択です。
トロイの木馬

2
姿勢ジェットの短い発射とメインエンジンの連続燃焼(「スラスタ」は時々SFで少し一般的に使用されます)のどちらを意味したかはすぐにはわかりませんでした。ロケットブースターに衝動を使用します。;)
DMGregory

@DMGregory Indeed; 私の宇宙技術用語は主に映画に基づいています:)
trojanfoe

@trojanfoe Go KSPをプレイします。のように、今。
user253751

21

すでに受け入れられている答えがありますが、カバーする価値のある追加の詳細があると思います。

Velocityを使用する

速度を設定すると、そのオブジェクトの動きに影響を与える可能性のある他のすべてが完全にオーバーライドされます。trojanfoeの例のように、弾丸が発射された瞬間に一度だけ初期速度を設定するなど、状況によってはこれが望ましい場合があります。間違った状況で使用すると問題が発生する可能性があるため、注意してください。

  • 複数のソース/スクリプトが同じRigidbodyの速度を直接設定して変更しようとする場合(つまりbody.velocity = foo)、最後に実行された方が勝ち、他の効果はゼロになります。これは、更新のバグの順序につながる可能性があり、特にエンティティがホバリングまたはゆっくりと落下する原因になります(重力による下向きの加速が蓄積される前に上書きされるため)

  • フレームごとに速度を設定している場合、他のオブジェクトとの衝突は少し奇妙になります。無限トルクのエンジンによってオブジェクトが推進されているようです-衝突でどれだけの速度が失われても、次の物理ステップで最高速度に戻り、その速度は衝突から逸れません。これにより、衝突するオブジェクトを起動したり、小さなオブジェクトが思ったよりもはるかに簡単に巨大なオブジェクトをプッシュしたり、静的なバリアに沿ってゆっくりとスライドしたり、偏向したりすることができます。

これらの両方の効果が必要になる場合があります。たとえば、Kinectゲームを作成していて、プレイヤーの仮想アバターの手足が物理シーンとやり取りできるようにしたい場合、通常、直接速度設定を使用してそれらのボディを移動します。プレイヤーの実際の手は、既知の場所にあり、その仮想物体との衝突からスローダウンしていなかったため、彼らの仮想手が一直線上に滞在する同じことを行う必要があるので、この場合には、私たちが実際にしたい他のすべての物理的効果を無効にしますそこに着く。

AddForceとフレンド

対照的に、AddForceおよび同様のヘルパー関数は、物理学の世界で進行中の他のすべてと協力するように作られています。複数のソース/スクリプトがAddForceをRigidbodyに追加すると、それらの効果がすべて加算され、オブジェクトの動きに正味の変化が生じます(計算方法によっては順序に依存しない場合もあります)。これにより、1つのスクリプトが他の物理効果を完全に踏み潰すことを回避できます。

AddForceは、オプションのForceModeパラメーターを指定することで4つのフレーバーがあり、さまざまなことに役立ちます

ForceMode       |   Use
-----------------------------------------------------------------------
Force (default) |   Accelerate an object over 1 time step, based on its mass.
                |   Units: Newtons = kg * m/s^2
                |
Acceleration    |   Accelerate an object over 1 time step, ignoring its mass. (like gravity)
                |   Units: m/s^2
                |
Impulse         |   Instantaneously propel an object, based on its mass
                |   Units: N * s = kg * m/s
                |
VelocityChange  |   Instantaneously propel an object, ignoring its mass
                |   (like body.velocity = foo, except multiple scripts can stack)
                |   Units:  m/s

車の運転やロケットの燃焼、重力での牽引など、時間の経過に伴う連続的なプッシュ(たとえば、FixedUpdateを適用するもの)をモデル化する場合は、ForceまたはAccelerationが必要です。(重いオブジェクトの加速を遅くするかどうかによって異なります)

弾丸の発射、爆発からの跳ね返り、障壁の跳ね返りなど、突然の急激な動きの変化をモデル化する場合、ImpulseまたはVelocityChangeが必要になる可能性が高くなります。

AddForceを使用すると、物理的なリアリズムをより高めることができますが、行動の物理学を通して考える時間を増やす必要もあります。たとえば、フレームごとに速度を設定するよりも現実的に衝突に反応するように、体に目標速度まで有限の加速度を持たせたい場合、おそらくこのヘルパー関数に似た計算が必要になります:

public static void AccelerateTo(this Rigidbody body, Vector3 targetVelocity, float maxAccel)
{
    Vector3 deltaV = targetVelocity - body.velocity;
    Vector3 accel = deltaV/Time.deltaTime;

    if(accel.sqrMagnitude > maxAccel * maxAccel)
        accel = accel.normalized * maxAccel;

    body.AddForce(accel, ForceMode.Acceleration);
}

私がこれらすべての「ヘルパー関数」と呼ぶ理由は、技術的には次の方法ですべて同じ目的を達成できるからです。

 body.velocity += suitablyCalculatedDeltaV;

私は思う。UnityのPhysX / Box2Dベースの物理ソルバーは、AddForceを介して変更を個別にバッファリングする可能性がありますが、これによる明らかな結果は見ていません)

結局のところ、これらの関数が本当に私たちにもたらすのは、意図の明確さです。段階的な力を適用したい場合、DeltaVにTime.deltaTimeを掛けて質量で除算することを覚えておく必要はありません。ForceMode.Forceが必要であり、正しく一貫した方法で処理されます。そして、私または他の誰かが後でコードを反復するようになったとき、それを理解するために時間と質量の計算をデコードする必要なく、私が意図したことはすぐに明確になります。


6

トロイの木馬の答えに加えて、Angry Birds vs Car Racing。これらの方法の2つの主な異なる例(AddForceおよびvelocityそれぞれ)。たとえば、Angry Birdsでは、自分で投射物の軌跡を設定する必要があるため、速度の使用はもう少し難しくなります。

Angry BirdsでAddForceを使用するときは、

_birdRigidbody.AddForce(new Vector2(5,5));

一方、速度を使用するときは、軌道を使用して

x = v*t*Cos(theta) y = v*t*Sin(theta) - 0.5 * g * t *t

またはこのようなもの。

カーレースゲームでは、Angry Birds、つまりシュートなどとは異なり、常に速度を制御する必要があります。そのため、そのシナリオでは、handle velocityはより便利ですAddForce

ご理解ください。少なくとも少し。


1
AngryBirdsの例では、スリングショットがリリースされたときに、タイムウィンドウ全体で効果をシミュレートするデフォルトのForceMode.Forceではなく、瞬間的な運動量の変化(ImpulseやVelocityChangeなど)を使用する必要があります。どちらのアプローチでも同等の動作を得るために数値を調整できますが、固定時間ステップを変更すると、力の解は異なる出力を持ちます(より長いまたはより短い時間間隔で力を積分するため)これはリリースの瞬間を表しているためです。
DMGregory

0

Rigidbody VelocityとRigidbody Addforceは、Unity 3Dの2つの紛らわしい機能であり、多くの場合、初心者はその違いを理解できません。この記事では、RigidBody.velocityとRigidBody.addforceの違いについて説明します。

どちらの場合も、それがAddforceか速度関数かに関係なく、それらを説明するためにforceという用語を使用します。

Rigidbody.velocityを使用している場合、その場合、オブジェクトに力を加えていますが、この力は力を加えない限り、力を加え続けるまでオブジェクトを動かすだけです。

例えば

body.velocity = new Vector3(0,0,5);

z位置に5fを追加し、Wキーを押すとその力が追加されるとしましょう。Wキーを押すと、オブジェクトはすぐに5の速度で起動します。この機能を使用して車に力を加えている場合、その車は5の速度で起動します。

body.velocity = new Vector3(0,0,200);

そして、値を200に変更し、保存後にWを押すと、車は開始から200の速度で実行を開始しますが、これは現実の世界では不可能です。

Rigidbody.addforceについて話す場合

Carの例を続けます。車に200の力を加えると

body.addforce(0,0,200);

Wを押すと、車は200の速度で移動し始めませんが、低速から開始し、ドラッグの値に従って速度を上げて停止します。

Rigidbody.addforceはゆっくりと起動し、次に高速になります。重いテーブルをドラッグしているように、最初にそのテーブルを押し始めます。テーブルはその位置から少し移動しますが、そのテーブルを押し続けると移動し始めます。そのテーブルを離れると、サーフェスに応じてある程度の距離をカバーします。これは、同じrigidbody.addforceと同じです。

Rigidbody.velocityを使用すると、オブジェクトを移動してプレイヤージャンプのように即座に反応することができ、その力の結果はジャンプの直後に消えます。Rigidbody.addforceを使用すると、スロースタートと連続移動が必要になります。ロケット。ジャンプでRigidbody.addforceを使用すると、Player / Objectはしばらくの間スペースに残り、その後地面に戻ります。

(ソース)


少なくとも、投稿をStack Exchangeの回答形式に適合させてみてください:)
Vaillancourt
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.