UpdateメソッドとFixedUpdatedメソッドをいつ使用するかについてのさらに別の記事。かなり簡単に、タイムステップの混合と一致の問題を再現したので、私はすべてのゲーム状態をfixedupdateメソッドに入れるべきだと確信しました。
この記事の内容に入る前に、私は最初の場所で団結に興味を持っている理由を明確にしたかったです:
- 私はビデオゲームをプレイしたり作成したりすることにあまり興味がありません
- 私は便利なツールを構築することに興味があります(長年web開発者Unityの学習に関しては、公式のUnityチュートリアルは特に有用ではありませんでした。 絶対初心者のためのUdemyコースLearn Unity3Dが優れていることがわかりました。
私は材料を巡航していて、UpdateとFixedUpdateのレッスンの違いに電話を切っていました。 もう少し研究すると、問題の核心は、私が次の理論的根拠を理解していないということでした。
Update();…次のような定期的な更新に使用されます:非物理オブジェクトの移動
FixedUpdate();…次のような定期的な更新に使用されます。
FixedUpdate();…次のような定期的な更新に使用されます: 物理(Rigidbody)オブジェクトの調整
Unity—UpdateとFixedUpdate—Unity公式チュートリアル
もう少し研究が上がった:
結論として、すべてのゲームロジックをUpdateまたはFixedUpdateに入れます。 あなたが弾丸を噛んで、いくつかの吃音を受け入れて喜んでいない限り、タイムステップを混ぜて一致させないでくださ さらに、ユーザー入力、視覚効果、およびゲーム状態間の補間専用のUpdateを使用して、すべてのゲーム状態をFixedUpdateに入れることを検討する価値があります。 これはあなたのゲームをどのように構造化するかを変更する必要がありますが、,それは多くの利点を持つ実績のある設計構造です.
—KinematicSoup—TimestepsとUnityで滑らかな動きを達成
記事のビデオクリップは、タイムステップの混合と一致の問題を示しています。div>
このアドバイスに従う前に、私は再作成したかったです私自身でtimestepsを混合し、一致させる問題。この記事の執筆に使用したプロジェクトの最終版はダウンロードできます。
Update Vs FixedUpdate
UpdateメソッドとFixedUpdateメソッドの違いについての基本的な理解から始める必要があります。 説明するために、Setupという名前の空のGameObjectを作成し、次のスクリプトコンポーネントを追加します。
Assets/Setup。cs(incomplete)
3秒後のコンソール出力は次のようになりました:
- updateは各レンダリングの前に呼び出され、その頻度(フレームレート)はレンダリングとホストデバイスの複雑さに基づいて変化します。 強力なコンピュータは150fpsを超えるフレームレートを達成することができます。 30fpsの下では、貧しい経験であると考えられています。
- FixedUpdateは、内部物理の更新(重力などの物理によるものの移動)の前に呼び出されます。 Unityのfixed timestepのデフォルトは0.02で、FixedUpdateは毎秒50回呼び出されます。
遅いフレームレートをシミュレート
遅いフレームレート(10fps)をシミュレートするために、セットアップを更新します。次のようにcsスクリプト:
Assets/Setup。cs(incomplete)
3秒後のコンソール出力は次のようになりました:Div>
観測:
- vsynccountを0に設定すると、unityはレンダリングと画面のリフレッシュレートの同期を無効にします。
- 実際のフレームレートは、ホストデバイスの制限とレンダリングの複雑さのために、
TARGET_FRAME_RATE
よりも低くなる可能性があります。
手動アニメーション
様々なアニメーションの効果を観察するために、我々は参照のために固定キューブを配置することから始めます。
We add our first animated GameObject (Sphere) in front of it with the following script component.
Assets/Sphere.cs (incomplete)
Running it with the normal frame rate:
Running it with 10fps frame rate:
Observations:
- 明らかに、私たちは問題を抱えています。 アニメーションの速度がフレームレートに依存しないようにします。
- 問題は、速度を0.1単位/フレームに設定しているため、速度を単位/秒で測定する必要があるためです。修正は、単位/秒の単位で速度を提供することです。0.1単位/フレーム*50フレーム/秒=5単位/秒。 その後、我々は時間を使用しています。deltaTimeは、Updateの最後の呼び出しからの時間を知るためのものです。 次に、移動距離はSPEED*deltaTimeです。
資産/球。cs(incomplete)
この修正を適用すると、フレームレートに関係なく同じアニメーションが得られます(ただし、10fpsでは、期待どおりにぎくしゃくしています)。p>
必要性を説明するために縮小されたフレームレートを使用しました単位/秒で速度を提供するために、セットアップの行をコメントアウトすることができます。遅いフレームレートをシミュレートしたcs。
物理学のアニメーション
GameObjectを手動でアニメーション化する代わりに、物理学を適用することでアニメーション化できます。 シリンダーをアニメーション化することができます(右に5単位/秒移動)。
- 平面の作成(Planeと呼ばれる)
- 円柱の作成(Cylinderと呼ばれる)
- RigidbodyコンポーネントをCylinderに追加します(全方向の回転を凍結します)
- 摩擦のない滑りやすい物理マテリアルを作成し、Cylinderと平面の両方に適用します
- スクリプトコンポーネントを使用して初期速度でシリンダーを開始します
アセット/シリンダーcs
これを行うと、球と円柱が同じ速度で右に移動することがわかります。Div>
観測:
- 球の位置は、レンダリングの直前に更新されます(updateメソッドで手動で)
- シリンダーの位置は、内部物理アップデートで更新されます。
アニメーション付きアニメーション
GameObjectをアニメーション化する第三の方法は、アニメーションを使用することです(明らかに)。 カプセルをアニメーション化するには、
- カプセルの作成(Capsuleと呼ばれます)
- アニメーションコントローラ(Capsuleとも呼ばれます)を作成し、capsule GameObjectにコンポーネ
- アニメーションを作成します(また、カプセル)。
- アニメーションコントローラで、その動きをカプセルアニメーションにする状態(開始)を作成します。
- 最後に、カプセルの水平位置が5単位で1秒になるように位置をアニメーション化します。これを配置すると、球、円柱、カプセル(ほぼ)が同じ速度で右に移動することがわかります。Div>
観測:
- 理由はわかりませんが、カプセルは予想よりもわずかに速く移動しました。
- カプセルの位置は、レンダリング前(デフォルト)または物理アップデート中に更新するように設定できます。
高速フレームレートの含意
強力なコンピュータでは、150fpsまでのフレームレートを達成することができます。 既定の物理更新が1秒に50回(更新間隔0.02秒)のコンピューターでは、各レンダリングの前に更新される要素は、物理更新で更新される要素よりも頻繁に更新されます。 この不一致は、タイムステップの混合と一致の問題の原因です。開発マシンのフレームレートを上げることはできませんが(約50fpsに制限されています)、物理の更新を1秒あたり10回の更新(0)に人為的に遅くすることがプロジェクトの設定を使用して、更新の間に1秒)。div>
あなたが見ることができるように、混合し、混合することによって、そして、
タイムステップの一致問題を再作成しました(gameelements間の一貫性のない動き)。修正するには、カプセルのアニメーションを物理の更新時に更新するように変更し、同様にSphereのスクリプトコンポーネントを次のように更新します。
Assets/Sphere。cs
これにより、すべてのアニメーションは、各物理学の更新の前に一貫して更新されます。P>
最後に、物理アップデートを次のように返します50fps(または0.02秒毎に);一貫した、時機を得た更新の達成。
かなり簡単に、タイムステップの混合と一致の問題を再現し、私はすべてのゲームの状態をfixedupdateメソッドに入れるべきだと自分自身を確信しました。