「翻译」Unity 动画状态机的转换中断机制

博客原文:Wait, I’ve changed my mind! State Machine Transition interruptions

I recently investigated a tricky bug reported by a user involving the combination of empty states, override layers, and transition interruptions. As I was digging in, I found that our documentation about transition interruptions in the animation system was a bit… minimalist. A long conversation with my team later, we concluded that a blog post was in order.

我最近调查了一个用户诡异的BUG报告,其中涉及了空状态、覆盖层级、转换中断。在深入探究后,我发现我们关于动画系统中转换中断的文档有一些……极简主义。经过与团队的长时间讨论之后,我们总结出了这篇博客。

So let’s dive into some intricate details of State Machine Transitions and interruptions!
By default in the animation system, transitions cannot be interrupted: once you start going from one state to the other, there’s no way out. Like a passenger on a transatlantic flight, you’re cozily nestled in your seat until you reach your destination and you can’t change your mind. For most users, this is fine.

让我们来看看一些复杂的状态机转换和中断的细节!
默认的情况下,动画系统的转换是不可中断的:当你开始从一个状况转换到另一个状态,是没有其他出路的。就像跨大西洋航班的乘客一样,在到达了你的目的地之前,你只能待在位置上。对于大多数使用者,这是OK的。

But if you need more control over transitions, Mecanim can be configured in a variety of ways to meet your needs. If you’re unhappy with your current destination, you can hop in the pilot’s seat and can change plans midway through your flight. This means more responsive animations, but also many opportunities to get lost in the complexity.

但是如果你对转换有更多控制需求,可以通过各种方式配置Mecanim,以满足这些需求。如果你对当前航班的目的地不满意,你可以在中途改变它。也就是说,这将是一个更灵活的动画,但使用者会很有可能搞不清这些复杂的机制。

So let’s walk through a few examples to sort that out. We can begin with a fairly simple state machine with four states, labeled A to D, and triggers hooked to every transition on the state machine.

那么让我们通过一些简单的例子来搞懂它吧。我们先建立一个简单的状态机,其中有A B C D四个状态,同时将触发器挂载到每个转换上。

建立状态机

By default, when we trigger the A->B transition, our state machine transitions towards B and nothing can keep it from reaching its destination. But if we go on the A->B transition inspector and change the interruption source from “None” to “Current State”, our journey from A to B can be interrupted by some triggers on state A.

在默认情况下,当我们触发了A->B的转换时,我们的状态机开始向转向B,而且没有什么可以阻止它到达目的地。但是如果我们去A->B的转换面板上修改Interruption Source(中断源) "None" -> "Current State",从A到B的转换可以被A上的一些触发器中断。

A->B的转换面板

Why only “some”? Because the “Ordered Interruption” checkbox is also checked by default. This means only transitions on state A that have a higher priority than the current one are allowed. Looking at the inspector of state A, we can see that this only applies to the A->C transition.

为什么是「一些」?因为"Ordered Interruption"(有序中断)是被默认勾选的。也就是说,只有A上有更高优先级的转换是生效的。在A状态的面板上,我们可以看到只有A->C的转换是生效的。

A状态的面板

So if we activate the A->B trigger, then shortly after the A->D trigger, our transition remains uninterrupted. However, if we press the A->C trigger instead, then the transition is immediately interrupted and the state machine starts transitioning towards C.

所以,如果我们激活了A->B的触发器,然后触发A->D的触发器,我们的转换依然不会被中断。然而,如果我们触发A->C的触发器,当前的转换会立即被中断,同时状态机开始向C转换。

Internally, the animation system records the pose at the time of the interruption, and will now blend between that static pose (X) and the new destination animation.

这个机制内部,动画系统记录了中断时的pose数据,并使用这个静态的pose数据与新的目标动画进行混合。

动画混合示意图

Why a static pose, instead of a possibly smoother blend between the current and new transitions? Simply put: performance. When a game faces a cascade of interruptions, keeping track of several dynamic transitions taking place simultaneously would quickly made the animation system unscalable.

为什么是静态pose数据,而不是在当前和新的转换之间可能更平滑的融合? 简单地说:性能。 当游戏面临一连串的中断时,跟踪同时发生的几个动态转换将迅速使动画系统不可扩展。

Now, if we uncheck that “Ordered Interruption” checkbox, then both A->C and A->D can interrupt the transition. However, if they are both triggered on the same frame, A->C will still take precedence because it has a higher priority.

如果我们取消"Ordered Interruption"(有序中断)的勾选, A->C 和 A->D都可以中断 A->B 的转换。尽管如此,如果它们都在同一帧被触发,依然是A->C优先,因为它有更高的优先级。

If we change the interruption source to “Next State”, A->C and A->D can no longer interrupt the transition, regardless of their order. However, if we press the B->D trigger, we will immediately start transitioning from A to D, without completing the transition towards B.

如果我们将Interruption Source(中断源) 改为"Next State",A->C 和 A->D 将不再中断转换,无论她们的优先级。尽管如此,如果我们触发了B->D 的触发器,在完成向B的转换之前,状态机将会立即开始A->D的转换。

Transition order matters on state B too. The “Ordered Interruption” checkbox is not available anymore (any triggered transition on B can interrupt the transition because they do not have a priority ranking relative to A->B), but the order of the transitions on B will determine which transition wins if both are triggered within the same frame. In this case, if B->D and B->C are triggered in the same frame, B->D will be selected.

转换的优先情况也在B上。"Ordered Interruption"(有序中断)不再生效(触发任何B上的任何转换条件都可以撞断转换,因为它们相对A->B没有优先级),但是如果多个转换条件在同一帧被触发,依然由在B上的优先级决定哪个生效。例如:如果 B->D 和 B->C 在同一帧被触发,B->D 将会生效。

B上的转换条件

Finally, for complete control, we can set the Interruption Source to “Current State Then Next State”, or “Next State Then Current State”. In that case, the transitions will be analyzed independently on one state, then the other. So, let’s assume we have the following configuration.

最后,为了完全控制,我们可以设置Interruption Source(中断源) 为"Current State Then Next State"或"Next State Then Current State"。在这种情况下,转换将在一个状态下独立分析,然后另一个状态。我们假设有以下配置:

配置

During the A->B transition, a very excited player triggers four transitions within the same frame: A->C, A->D, B->C and B->D. What happens?First, “Ordered Interruption” is checked, so we can ignore A->D right away: it has lower priority than A->B. The current state gets resolved first, so we do not even have to look at state B to know that transition A->C wins.

在A->B的转换期间,在同一帧触发了A->C A->D B->C B->D,会发生什么呢?
首先,"Ordered Interruption"(有序触发)是生效的,我们可以忽略A->D,因为它的优先级比A->B低。
其次,"Current State Then Next State",我们可以忽略B上的转换(B->C B->D),因为当前的状态高于下一个状态。
最终,我们发现A->C竞争成功。

A上的转换条件
B上的转换条件

However, with the same configuration, if only B->C and B->D get triggered, transition B->D will take place (it has greater precedence than B->C).

在相同的配置下,如果在同一帧只触发了B->C B->D,那么B->D将会生效,因为它有着更高的优先级。

Now, this is only for one transition… All other transitions can also be interruptible too, with their own specific rules. So if we make transition A->C interruptible from the next state, we can have transition A->B interrupted by A->C which in turn could be interrupted by C->D.

以上为只有一个转换的情况。其他的转换条件同样可以根据具体的规则中断它。
所有如果我们使A->C可以在"Next State"中被中断,那么我们让A->C中断A->B,在其转换过程中同样有可能被C->D中断。

One important thing to keep in mind: regardless of interruptions taking place, the source state remains the same until the transition is complete, and Animator.GetCurrentAnimatorStateInfo() will always return that source state.

一个非常重要的事情需要被记得:无论中断是否发生,在转换完成之前,源状态是不会改变的。所以 Animator.GetCurrentAnimatorStateInfo()将一直返回源状态。

In short, transition interruptions settings are powerful and offer a lot of flexibility, but they can quickly become very confusing. So use transition interruptions wisely, and when in doubt, test it out in the Editor.

简而言之,转换中断机制是一个强大且灵活的,但也能很快变得非常复杂。所以明智地使用转换中断,当有疑问时,在编辑器中测试它。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容

  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 9,344评论 0 23
  • 小时候, 二月的柳枝发了新绿, 就会剪下一段柳条, 插在家中好看的瓶子里, 欣赏它的曼妙。 三月的桃花杏花吐了蕾,...
    杨柳依依簡阅读 258评论 0 5
  • 1,团结能人做大事,团结庸人能做事,团结小人不坏事。 2,多起感恩之心,勿起背主之念。 3,精力管理的本质在于提升...
    我是哼哼哈嘿阅读 1,447评论 0 0
  • 终于醒悟来,原来周末的活动,不宅都是想给SS看的。而如今,与何人说。无所事事,毫无兴致,提不起一点精神,乏味的第二...
    iamght阅读 181评论 0 0