データ駆動型のアニメーション状態


14

編集:私の質問が正確に何であるかを明確にするために:これは、コンテンツの作成/管理に注目してゲームエンジンでアニメーション/アニメーション状態を処理する良い方法ですか?この方法で行うことの欠点は何ですか?また、それを行う別の方法は何ですか?-私の答えはコメントの中で部分的に答えられましたが、それが進むべき道のようです。

アニメーションをハードコーディングせずに、2Dゲームエンジンの趣味プロジェクトでアニメーションを処理しようとしています。アニメーションの状態をハードコーディングすることは、よくあることですが、非常に奇妙な現象のように思えます。

少しの背景:コンポーネントがデータの袋であり、サブシステムがそれらに作用するエンティティシステムを使用しています。ポーリングシステムを使用してアニメーションの状態を更新することにしました。

アニメーションを述べて私は意味: "walking_left"、 "running_left"、 "walking_right"、 "撮影"、...

アニメーションを処理する私のアイデアは、データ駆動型モデルとして設計することでした。データはxmlファイル、rdbmsなどに保存できます。また、ゲーム/レベル/の開始時にロードすることもできます。この方法で、コードをどこにでも変更することなく、アニメーションとトランジションを簡単に編集できます。ゲーム。

例として、念頭に置いたデータ定義の xmlドラフトを作成しました。

非常に重要なデータの1つは、単にアニメーションの説明です。アニメーションには一意のID(わかりやすい名前)が付けられます。画像への参照IDを保持します(異なるアニメーションは異なるスプライトシートを使用する可能性があるため、使用するスプライトシート)。アニメーションを実行する1秒あたりのフレーム。ここでの「リプレイ」は、アニメーションを1回または無限に実行する必要があるかどうかを定義します。次に、四角形のリストをフレームとして定義しました。

<animation id='WIZARD_WALK_LEFT'>
    <image id='WIZARD_WALKING' />
    <fps>50</fps>
    <replay>true</replay>
    <frames>
        <rectangle>
            <x>0</x>
            <y>0</y>
            <width>45</width>
            <height>45</height>
        </rectangle>
        <rectangle>
            <x>45</x>
            <y>0</y>
            <width>45</width>
            <height>45</height>
        </rectangle>
    </frames>
</animation>

アニメーションデータは、アニメーションリソースプールに読み込まれて保持され、それを使用しているゲームエンティティによって参照されます。画像、音、テクスチャなどのリソースとして扱われます...

定義する2番目のデータアニメーションの状態と遷移を処理する状態マシンです。これは、ゲームエンティティが存在できる各状態、移行できる状態、およびその状態の変化をトリガーするものを定義します。

この状態マシンは、エンティティごとに異なります。鳥には「歩く」と「飛ぶ」という状態があるかもしれませんが、人間には「歩く」という状態しかありません。ただし、複数の人間がおそらく同じ状態になる可能性があるため(特に、モンスターなどの一般的なNPCを定義する場合)、異なるエンティティで共有できます。また、オークは人間と同じ状態になる場合があります。この状態定義は、ゲームエンティティの選択グループによってのみ共有される可能性があることを示すためだけです。

<state id='IDLE'>
  <event trigger='LEFT_DOWN' goto='MOVING_LEFT' />
  <event trigger='RIGHT_DOWN' goto='MOVING_RIGHT' />
</state>
<state id='MOVING_LEFT'>
  <event trigger='LEFT_UP' goto='IDLE' />
  <event trigger='RIGHT_DOWN' goto='MOVING_RIGHT' />
</state>
<state id='MOVING_RIGHT'>
  <event trigger='RIGHT_UP' goto='IDLE' />
  <event trigger='LEFT_DOWN' goto='MOVING_LEFT' />
</state>

ポーリングシステムでこれらの状態を扱うことができます。各ゲームティックは、ゲームエンティティの現在の状態を取得し、すべてのトリガーをチェックします。条件が満たされると、エンティティの状態が「goto」状態に変更されます。

最後に苦労したのは、アニメーションデータとアニメーション状態をエンティティバインドする方法でした。最も論理的なアプローチは、エンティティが使用するステートマシンデータへのポインタを追加し、そのマシンの各ステートに使用するアニメーションを定義するように思えました。

アニメーションの状態とアニメーションデータIDを指定することにより、ゲーム内の一般的なエンティティのアニメーション動作とグラフィック表現を定義する方法のxmlの例を次に示します。「ウィザード」と「オーク」の両方のアニメーションの状態は同じですが、アニメーションが異なることに注意してください。また、異なるアニメーションは、異なるスプライトシート、またはアニメーションの異なるシーケンスでさえも意味する可能性があります(アニメーションはより長くも短くもなります)。

<entity name="wizard">
    <state id="IDLE" animation="WIZARD_IDLE" />
    <state id="MOVING_LEFT" animation="WIZARD_WALK_LEFT" />
</entity>

<entity name="orc">
    <state id="IDLE" animation="ORC_IDLE" />
    <state id="MOVING_LEFT" animation="ORC_WALK_LEFT" />
</entity>

エンティティが作成されると、ステートマシンデータとアニメーションデータ参照を含むステートのリストが追加されます。

将来、エンティティシステムを使用して、同様のxml形式でコンポーネントを定義することでエンティティ全体を構築します。

-

これは私がいくつかの研究の後に思いついたことです。しかし、頭を悩ませているので、フィードバックを期待していました。意味をなさないものがここにありますか、またはこれらを処理するより良い方法がありますか?私はフレームを反復処理するというアイデアを理解しましたが、それをさらに一歩進めるのに苦労しており、これが私の試みです。


1
トリガーについては考慮していませんが、アニメーションデータを保存するための同様のアイデアを思いつきました。これについて私が書い短い記事と、XMLを消費し、アニメーションの側面を処理するXNAプロジェクトへのリンクを示します。セットとシーケンスの概念のように、いくつか異なる点がありますが、それ以外は順調に進んでいると思います。
ジョンマクドナルド

2
あなたのデザインが悪いわけではありません(そうではありません、私が過去に構築した同様のシステムのラインに非常に沿っています)が、ここであなたの質問は正確に何ですか?私はそれが本当に明確に立つことができると思う。
MrCranky

@ジョン-ありがとう、私は今晩後半にそれを見ていきます。@ MrCranky-まあ、ほとんどあなたが言ったことだけ。それが良いものであり、おそらく確立された方法へのヒント/リンクである場合。経験的には、ここは本当に暗いです。
user8363

1
提供された情報の深さについてこれに賛成票を投じたいと思いますが、MrCrankyを反映するために、私は質問が何であるかを実際に追っていません。私自身の個人的なアドバイス(この種のシステムを数週間前に構築したことから生じる)については、私はあなたがスポットにいると言うでしょう。
マイククロック

@MikeCそれは私が必要とした答えです。私は自分の質問を明確にすることができなかったという事実をおaびします。たぶん私がそれに気づかなかったら、質問のように見えるでしょう:)。事実、アニメーションの状態を扱う多くのリソースと、それをハードコーディングしたリソースを見つけることができなかったので、コンテンツの作成/変更は悪夢になります。だから私の質問は次のとおりです。このアプローチは正しいかどうか?そして、皆さんがそうだと言うなら、それは大丈夫です:)。
user8363

回答:


4

アニメーションクリップは、最初のXMLスニペットで行ったように、plain-old-dataで最もよく記述されます。これは手動で作成することも、アートパッケージからエクスポートすることもできます。いずれにせよ、XMLのような人間が読める中間形式からそれを取得し、読みやすくて読みやすいものに入れるパイプラインを作成することになるでしょう。

次のステップは、Thingをレンダリングできるようにすることです。何らかのシーングラフを使用している場合、それはおそらくアニメーションノードを作成することを意味します。アニメーションノードに、現在どのアニメーションを再生しているか、現在タイムラインのどこにいるかを伝えることができるはずです。このレベルでバウンディングボックス情報にアクセスできるようにして、カリングシステムに簡単にフィードできるようにしてください。

ここで、アニメーションをゲームエンティティに関連付ける必要があります。私はコンポーネントベースのモデルを使用する傾向があるため、私にとってはこの手段とAnimStateコンポーネントです。これは、ゲームプレイとレンダリングの間の中間層です。エンティティが再生しているアニメーション、プレイモード(ループ、1回、ピンポンなど)、タイミングなどを追跡します。「アニバーバー」などのイベントをエンティティに送り返し、必要に応じてアニメーションノードの状態を更新します。 。アクティブなエンティティのAnimStateは、アニメーションを再生している場合、sim tickごとに1回更新されます。

単純なゲームアイテム(基本的な背景の小道具など)には、おそらくアニメーションコンポーネントで十分ですが、より複雑なエンティティの場合は、ステートマシンを使用して管理する必要があります。これは、LuaやPythonなどのスクリプト言語で最もよく表現されます。状態には、いくつかの機能ブロック(onEnter、onExit、onUpdate、onEvent)、および特定の時間に発生する特定のアクションとトリガーを指定するタイムラインを含めることができます。おそらく、これらのステートマシンを必要に応じて更新し、発生したタイムラインコールバックをトリガーする何らかのマネージャクラスを持っているでしょう。書くすべてのOnUpdateはエンティティカウントを伴う線形コストになるため、これらのイベントは可能な限りイベントベースに保つようにしてください。また、タグを指定できるようにする必要があります(「攻撃」、「アイドル」、「ignoreinput」など)は、州全体と州の特定の時間領域の両方に関連付けられています。特定の状態だけでなく、状態グラフ全体に適用される高レベルのイベントハンドラも必要になるでしょう。

「感覚的」なキャラクターは、おそらく何らかのAIも持つでしょう。私は、歩き回るのを処理する特定の「運動」コンポーネントを作成する傾向があります。信号とイベントのシステムを使用して状態タグを照会し、ステートグラフとインターフェイスし、「ポイントまで歩く」または「特定の速度で特定の速度で実行する」ように指示できます。高レベルのAIコンポーネント(ビヘイビアツリーなど)は、詳細を気にせずにこのインターフェイスを使用できます。


1

私が今まで見た中で最高のデータ駆動型アニメーションシステムはBlend Treeです。本当に、それは非常に良いです、そして、それはあなたがここで求めているすべてをすることができます。AIGameDev.comによれば、今では業界の事実上の標準であり、私はそれらが正しいと信じています。

残念ながら、私は速いのグーグルとは良いリソースを発見した、しかし、あなたが試すことができ、このまたはそのの概要を取得します。AIGameDev.comにも有料の記事があります。プレミアムアカウントを取得する価値があるかどうかはわかりません。


これは非常に良いリソースです、ありがとう。このような情報を探しています。
-user8363

1
連続した骨格アニメーションでのみ、個別のスプライトシートではアニメーションをブレンドできません。
AlexFoxGill
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.