目の前でゲームを作成する-パート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)

Source: https://habr.com/ru/post/J235011/


All Articles