目の前でゲームを作成する-パート7:Unityの2Dアニメーション(「フラッシュのような」)

この記事では、Unityの2Dアニメーションについて説明します。 ユニット内のネイティブアニメーションでの作業の経験、フラッシュがタイムラインと似ている方法、アニメーション、イベント、ネストの管理、およびアーティストがアニメーションに対処する方法についてお話します。



手始めに、ちょっとした理論。



Unityには2つのエンティティがあります。



1. アニメーション ([アニメーション]ウィンドウに表示されるもの)

2.アニメーションのメカニズムツリー([アニメーション]ウィンドウに表示されるもの)。







以下に、それが何であるか、そしてどのように私たちがしなければならない(または役に立たない)かを少しお話しします。



アニメーション



だから、アニメーション。 実際、これはキーフレームのあるタイムラインです。 ここで、オブジェクトを移動、回転、拡大縮小できます。 当然、曲線を描いてさまざまなイシングを使用できます。 さらに、それらのプロパティ(自己記述を含む)を管理します。 つまり、float public値「brightness」を持つコンポーネントを記述し、通常の手段を使用してx、y、zとともにこの「brightness」をアニメートすることは非常に可能です。 スプライトはフレームごとのアニメーションをサポートします。







ところで、各アニメーションにはFPS(フィールド「サンプル」)があるという事実にもかかわらず、アニメーション自体はFPSにアタッチされていません。 それらは時間に結びついています。 つまり 5 FPSでアニメーションを作成する場合、オブジェクトを最初と最後に2つのキーフレームを設定してポイントAからポイントBに移動すると、ゲームではこのオブジェクトは5 FPSずつ移動しません。 アニメーションはゲームのフレームごとに計算され、アニメーション内のFPSはユーザーの利便性のためにのみ作成されるため、フレームを分割することはありません。



アニメーター



アニメーションを直接制御する大規模で複雑なシステムです。 つまり、アニメーションはキーフレームの設定を持つ単なるファイル(リソース)であり、それ自体は何も知りません。 それがコンポーネント「Animator」です。これが、これらのアニメーションの再生方法を知っているものです。



さらに、これらのアニメーションのツリーを作成し、それらの間でモーフィングを行うことができます。 つまり キャラクターがシフトによってアニメートされている場合(体の各部分が回転/移動する個別のスプライトである場合)、脚のアニメーション、腕のアニメーションを個別に作成することはかなり可能です。 次に、(マウスの助けを借りて)オブジェクトの速度に応じて、メカニカルアニメーターに脚のアニメーションが「歩く」または「走る」という条件を調整します。 また、キャラクターを撮影するために、独立したアニメーションが作成されます。これは、脚を動かす速度とはまったく関係ありません。



最も単純な場合、アニメーターは次のようになります。







つまり、単一のアニメーションが含まれ、接続/遷移は含まれません。



シャーマンを始めます。



これまでのところ、すべてが明確です。 しかし、もう少し複雑なことをする方法について考えてみましょう。



私の特定のケースは、うさぎが座っている雪の吹きだまりです。 雪の吹きだまり自体が動きます:







次に、このアニメーションを作成します。







1.雪の吹きだまり、移動、左に移動

2.雪の吹きだまりからノウサギがのぞきます(リップルアニメーションが停止します)。



3.雪の吹きだまりが右に移動します



原則として、複雑なことは何もありません。 オブジェクト内の雪の吹きだまりの脈動をアニメーション化し、外部アニメーターによってそれを左に移動してから非表示にし、代わりにうさぎのフレームごとのアニメーションを表示し、次に戻します。 そして、これらすべてを1つのタイムラインで(「内部」雪の吹きだまりアニメーションを除く)。



しかし、このオプションはその剛性が好きではありません。 まず、このオプションでは、雪だまりの動きと同じタイムラインにcうウサギのフレームごとのアニメーションが表示されるのは間違っていると思います。 これは、雪の吹きだまりが異なる軌道に沿って移動するこのアニメーションのバリエーションを作成する場合、ウサギのクロールを再びアニメートする必要があることを意味します。 そして、このクロールを修正したい場合、使用されるすべてのアニメーションでこれを行う必要があります。



もっと柔軟性が欲しいです。



別のオプションがあります。 雪の吹きだまりの移動で行ったように、別のオブジェクトでうさぎののぞき見をアニメートし、基本的にこのオブジェクトを適切なタイミングでオン(アクティブ)にすると、アニメーションが開始されます。



これはすでにはるかに優れていますが、それでも完璧ではありません。 実際、この場合、メインのタイムラインで、このクロールのアニメーションの長さを知る必要があります。 適切なタイミングで有効化および無効化する。 しかし、このアニメーションを再び変更し、うさぎがより長く見回した場合はどうなりますか? とにかく、いくつかのより複雑なケースでは、すべてを1つのタイムラインに合わせることがさらに困難になります。



メインタイムラインを一時停止し、添付されたアニメーションの再生を開始し、この添付されたアニメーションの終了時に(またはその中の何らかのイベントによって)一時停止できることが理想的です。



つまり、これを行います:







1.左に移動

2.脈動する雪の吹きだまりを隠し、うさぎがrawうアニメーションを表示して、一時停止します

3.ウサギのクロールアニメーションを非表示にし、移動する雪の吹きだまりを表示し、右に移動します



これには何が必要ですか? Unityでは、アニメーションにカスタムイベントイベント呼び出しを追加できます。 これはまさに私たちが必要とするものです! すべてを正しく書くためだけに残っています。



最初に必要なことは、単純なコンポーネント(この場合はGJAnim



と呼ばれGJAnim



)をGJAnim



し、アニメーターがハングするのと同じオブジェクトにハングさせることです。 タイムラインからイベントを呼び出すことができるのは、このコンポーネントのメソッドです。



一時停止のメソッドを作成します。 ちなみに、団結してそのような直接的な機会はありません。 アニメーションを一時停止するには、通常、速度を0に設定して少しダーティなハックが適用されます。通常は動作しますが、奇妙な点もあります(記事の最後の部分で詳しく説明します)。



 public void Pause() { _animator.speed = 0; } protected void Resume() { _animator.speed = 1; }
      
      





_animator



は、「 Animator



」コンポーネントをキャッシュした変数です。



 _animator = GetComponent<Animator>();
      
      







上記の画面に注意を払った場合、キーフレームの上に小さな縦線があり、これに数字「2」を付けました。 その背後には、「一時停止」イベント(メソッド)呼び出しが非表示になっています。







このようなイベントにパラメーターを渡すこともできることに注意してください。 サポートされている文字列、フロート、およびライブラリのオブジェクト(シーンからではありません)。



はい、一時停止しました。 ここで、タスクは一時停止することです。 明らかに、ネストされたアニメーションはこれを行う必要があります。 つまり、うさぎのうさぎのアニメーションが最後まで再生され、イベントが2階の「さらに進む」ことになりました。



  public void ResumeParent() { Transform pr = transform; while (true) { pr = pr.parent; if (pr == null) { Debug.LogWarning("No GJAnim found in parents!"); return; } GJAnim a = pr.gameObject.GetComponent<GJAnim>(); if (a != null) { a.Resume(); return; } } }
      
      







このメソッドは、親から「 GJAnim



」コンポーネントを検索し、一時停止します。 したがって、このイベントをウサギのアニメーションの最後に配置します。







利益!



実際には、それだけです。 ネストされた/親アニメーションを制御でき、十分な柔軟性を持つ単純なコンポーネントを作成しました。 おそらく、最初の親ではなく特定のアニメーションを一時停止するResumeByName(string)



型の別のメソッドが必要です。



さらに、すべてがUnite UI内で行われ、アニメーターにとって十分に透過的です。 私たちのアーティストは、この楽器の手に1時間落ちた後、すでにアニメーション化しています。



Unityのバグと狂気について。



ただし、すべてがそれほどスムーズではありません。 ある時点で、アニメーションを作成すると、アニメーションが正しく動作しないことがわかりました。



一時停止した1つのオブジェクト(他のすべてのオブジェクト)を表示する親(メイン)アニメーションがありました。この時点で、このオブジェクトで独自の(埋め込み)アニメーションが再生され、最後の一時停止から親が削除されました。 次-次のオブジェクトが表示されたなど。



そのため、フレームが時々スキップすることに気付きました。



彼らは長い間議論し、ログに多くのことを書きました...そして、ここに彼らが見つけたものがあります:



どうやら、ユニット内のアニメーションフレーム/イベントのある種のスタックがあります。 コンピューター(ユニティエディター)の速度が低下すると、このスタックに2つのフレームを一度に配置できるため、次の反復で両方のフレームを実行できます。



これには、ほぼ完全に修正できないファイルが必要です。 アニメーターがフレームですべてのアクションを実行して一時停止(これで問題ありません)し、次のフレームも同じフレームで実行さた状況をキャッチしました。 つまり、2つのアニメーションフレームが1つのフレームに対して同時にカウントされます。 そして、最初のフレームでアニメーション速度を0に設定するイベントがあったからといって、彼は次のフレームを計算することを止めませんでした。



そして、ウサギのアニメーションで誰もこれに気付かない場合(ウサギは間違った場所のピクセルにクロールします)、何かを非表示にして各フレームを表示すると、ファイルが存在する可能性があります。



現時点では、問題は手に負えないようです。 どうやってやったの? このようなアニメーションのFPSは20になります。どうやら、そのようなFPSでは、ユニットが1回の反復で2つのフレームを計算したい場合は発生しません。



しかし、それでも状況はそれほどではありません。 コンピューター上(または非常に遅いもの)でフリーズを使用しても、プレーヤーはアニメーションの失敗をキャッチすることができます。



これをどうするかは明確ではありません。



シリーズのすべての記事:

  1. アイデア、ビジョン、設定の選択、プラットフォーム、配信モデルなど。
  2. CRT / LCDの下で写真をスタイリングするためのシェーダー
  3. スクリプト言語をUnity(UniLua)に固定します
  4. パレットによるフェードイン用のシェーダー(la NES)
  5. 小計(プロトタイプ)
  6. PRインディーズゲームについて話しましょう
  7. Unityの2Dアニメーション(「フラッシュのような」)
  8. Unityでのカットシーンのビジュアルスクリプト(uScript)



All Articles