数据驱动的动画状态


14

编辑:澄清我的问题是什么:这是处理内容创建/管理中游戏引擎中动画/动画状态的好方法吗?这样做的缺点是什么?将有替代方法吗?-尽管我的回答在评论中得到了部分回答,但这似乎是必经之路。

我正在尝试在2D游戏引擎爱好项目中处理动画,而无需对其进行硬编码。在我看来,硬编码动画状态似乎是一种常见但非常奇怪的现象。

一些背景知识:我正在使用一个实体系统,在该系统中组件是数据包,而子系统则对它们起作用。我选择使用轮询系统来更新动画状态。

对于动画状态,我的意思是:“ walking_left”,“ running_left”,“ walking_right”,“ shooting”,...

我处理动画的想法是将其设计为数据驱动模型。数据可以存储在xml文件,rdbms等文件中,也可以在游戏/关卡/开始时加载。通过这种方式,您可以轻松地编辑动画和转场,而不必在您的各处更改代码游戏。

作为示例,我制作了一个我想到的数据定义的xml草案。

一个非常重要的数据就是动画描述。动画将具有唯一的ID(描述性名称)。它将保存图像的参考ID(它使用的Sprite表,因为不同的动画可能使用不同的Sprite表)。每秒运行动画的帧数。此处的“重播”定义了动画应运行一次还是无限次运行。然后,我将矩形列表定义为框架。

<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>

动画数据将被加载并保存在动画资源池中,并由使用它的游戏实体引用。它将被视为资源,例如图像,声音,纹理,...

要定义的第二个数据将是用于处理动画状态和过渡的状态机。这定义了游戏实体可以处于的每个状态,可以过渡到的状态以及触发状态改变的原因。

每个实体的状态机都不同。因为鸟类可能具有“行走”和“飞行”状态,而人类只有“行走”状态。但是它可以由不同的实体共享,因为多个人可能具有相同的状态(尤其是当您定义一些常见的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”状态。

我苦苦挣扎的最后一部分是如何将动画数据和动画状态绑定到实体。在我看来,最合乎逻辑的方法是为实体使用的状态机数据添加一个指针,并为该机中的每个状态定义其使用的动画。

这是一个xml示例,我将通过解决动画状态和动画数据ID来定义游戏中某些常见实体的动画行为和图形表示。请注意,“向导”和“兽人”都具有相同的动画状态,但是动画不同。同样,不同的动画可能意味着不同的精灵表,甚至意味着不同的动画序列(动画可能更长或更短)。

<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 2012年

@ John-谢谢队友,我今天晚上晚些时候看一下。@ MrCranky-好吧,基本上就是您所说的。如果有什么好处,并且可能提供了更多建立方法的提示/链接。我真的在黑暗中经验丰富。
user8363'4

1
我想对所提供的信息的深度给予支持,但是要回应MrCranky,我并没有真正关注问题所在。对于我自己的个人建议(几周前建立了这种系统就产生了这种想法),我想您会发现的。
Mike Cluck 2012年

@MikeC这只是我需要的答案。对于无法澄清我的问题,我深表歉意。也许,如果我没有发现的话,它看起来更像是一个问题:)。事实是,我找不到很多涉及动画状态的资源,也没有找到对它们进行硬编码的资源,因此创建/更改内容将是一场噩梦。所以我的问题是:这种方法正确吗?如果你们说的是,那很好:)。
user8363'4

Answers:


4

就像在第一个XML代码段中所做的那样,最好在纯旧数据中描述动画剪辑。您可以手工制作,也可以从艺术品包装中导出。无论哪种方式,您都可能想创建一个管道,该管道将从诸如XML之类的人类可读中间格式中获取并放入易于加载的好东西中。

下一步是能够渲染事物。如果您使用某种场景图,则可能意味着要为其制作一个Anim Node。您应该能够告诉动画节点当前正在播放哪个动画以及当前在时间轴上的位置。确保在此级别上可以访问边界框信息,以便可以轻松地将其输入到剔除系统中。

现在,您要将动画与游戏实体相关联。我倾向于使用基于组件的模型,因此对我来说,这意味着使用AnimState组件。这是介于游戏和渲染之间的中间层。它跟踪实体正在播放哪个动画,播放模式(循环播放,一次,乒乓球等),时间安排等。它可以将“动画”之类的事件发送回该实体,并在适当时更新动画节点的状态。 。如果活动实体的AnimState在播放动画,则每个sim标记会更新一次。

动画状态组件可能足以用于简单的游戏项目(基本的背景道具等),但是对于更复杂的实体,您将需要使用状态机进行管理。最好用Lua或Python之类的脚本语言来表达。状态可以具有多个功能块(onEnter,onExit,onUpdate,onEvent),以及指定特定动作和在特定时间发生的触发器的时间轴。您可能会有某种管理器类,负责适当地更新这些状态机,并在它们发生时触发时间线回调。您应该尝试使这些内容尽可能地基于事件,因为您编写的每个OnUpdate都是具有实体数量的线性成本。您还将希望能够指定标签(“攻击”,“空闲”,与整个状态和状态的某些时间区域相关联的“ ignoreinput”等)。您可能还需要一些适用于整个状态图而不只是特定状态的高级事件处理程序。

“有意识的”角色也可能会具有某种AI。我倾向于制作一个特殊的“运动”组件来处理走动。它使用信号和事件系统与状态图进行交互,并查询状态标签,并且可以被告知“走路指向”或“以一定速度沿特定方向行驶”。然后,更高级别的AI组件(例如行为树或其他任何东西)可以使用此接口,而不必担心细节。


1

到目前为止,我见过的最好的数据驱动动画系统是Blend Tree。真的,这真是太好了,它可以满足您在这里所要求的一切。根据AIGameDev.com的说法,它已成为业界事实上的标准,我相信它们是正确的。

不幸的是,我发现有一个快速的谷歌搜索没有很好的资源,但你可以试试这个那个得到一个概述。AIGameDev.com 上还有一篇付费文章,不知道是否值得拥有一个高级帐户。


这是非常好的资源,谢谢。我正在寻找这样的信息。
user8363'4

1
离散的Sprite-sheets不可能混合动画,只有连续的骨骼动画才可以混合
AlexFoxGill 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.