Unity AnimationState 动画状态

本文介绍Unity中的AnimationState接口,详细解释如何使用此接口控制动画混合、速度、权重等参数,实现高级动画效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AnimationState  动画状态

Inherits from TrackedReference继承自“跟随引用”

 

The AnimationState gives full control over animation blending.

AnimationState将全面控制动画混合

In most cases the Animation interface is sufficient and easier to use. Use the AnimationState if you need full control over the animation blending any playback process.

在大多数情况下Animation界面是完全可以满足基本使用。如果你需要全面控制动画混合任何播放过程,可以使用AnimationState

 

The AnimationState interface allows you to modify speed, weight, time and layers while any animation is playing. You can also setup animation mixing and wrapMode.

AnimationState界面允许你修改速度,重力,时间和层,即便是动画正处于播放中。你也可以设置动画合成和wrapMode(循环模式;Animation.wrapMode 循环模式 

 

 

The Animation

动画

 

Variables  变量

enabled

激活/允许

Enables / disables the animation.

允许/禁止动画(是否启用动画)

weight

权重

The weight of animation

动画的权重

wrapMode

循环模式

Wrapping mode of the animation.

动画的循环模式

time

时间

The current time of the animation

动画的当前时间

normalizedTime

格式化/规范化/标准化时间

The normalized time of the animation.

动画格式化时间

speed

速度

The playback speed of the animation. 1 is normal playback speed.

动画的播放数度。“1”是正常播放速度

normalizedSpeed

标准速度

The normalized playback speed.

标准的播放速度

length

长度

The length of the animation clip in seconds.

一秒内动画片段的长度

layer

The layer of the animation. When calculating the final blend weights, animations in higher layers will get their weights

动画的层。当计算最后的混合权重时,动画中“高层(优先级高的层)”将会先取得权重

clip

剪辑

The clip that is being played by this animation state.

动画状态播放剪辑

name

The name of the animation

动画的名

blendMode

混合模式

Which blend mode should be used?

应该使用那种混合模式

 

Functions  函数

AddMixingTransform

添加混合Transform(转换)

Adds a transform which should be animated. This allows you to reduce the number of animations you have to create.

应选一个动画加入Transform(转换)。这允许你减少一定数量必要的创建(动画的创建)。

RemoveMixingTransform

移除混合Transform(转换)

Removes a transform which should be animated.

应移除一个动画的Transform(转换)

 

 

 

AnimationState.blendMode  混合模式

 

var blendMode : AnimationBlendMode

Description  描述

Which blend mode should be used?

应该使用哪种混合模式?

JS:

 

// Set the leanLeft animation to blend additively

设置leanLeft 动画为混合相加
animation["leanLeft"].blendMode = AnimationBlendMode.Additive;

 

C#:

 

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    void Example() {
        animation["leanLeft"].blendMode = AnimationBlendMode.Additive;
    }
}

 

 

AnimationState.clip  剪辑

 

var clip : AnimationClip

Description  描述

The clip that is being played by this animation state.

剪辑是通过动画状态播放的

 

JS:

// Prints the frame rate of the animation clip to the console

//输出动画剪辑的帧速率到控制台

print(animation["walk"].clip.frameRate);

 

C#:

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    void Example() {
        print(animation["walk"].clip.frameRate);
    }
}

 

 

AnimationState.enabled  启用

 

var enabled : boolean

Description  描述

Enables / disables the animation.

启用/禁用动画

For the animation to take any effect the weight also needs to be set to a value higher than zero. 

If the animation is disabled, time will be paused until the animation is enabled again.

对于动画

JS:

// Enable the walk cycle

//允许“走”循环

animation["Walk"].enabled = true;
animation["Walk"].weight = 1.0;

 

C#:

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    void Example() {
        animation["Walk"].enabled = true;
        animation["Walk"].weight = 1.0F;
    }
}

 

 

AnimationState.layer  图层

 

var layer : int

Description 描述

The layer of the animation. When calculating the final blend weights, animations in higher layers will get their weights distributed first. 

动画的层。当计算最后的混合权重时,处于高层中的动画将会获得权限的优先分布

Lower layer animations only receive blend weights if the higher layers didn't use up all blend weights.

如果高图层没有用尽全部的混合权重,底图层动画只接受混合权重。

 

JS:

// Puts the walk and run animation in layer 1

//将“走”和“跑”动画放入层1

animation["Walk"].layer = 1;
animation["Run"].layer = 1;

 

C#:

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    void Example() {
        animation["Walk"].layer = 1;
        animation["Run"].layer = 1;
    }
}

 

 

AnimationState.length  长度

 

var length : float

Description  描述

The length of the animation clip in seconds.

用秒来计算动画的长度。

JS:

// Print the length of the walk animation in seconds

//输出“走”动画的长度(秒单位)

print (animation["Walk"].length);

C:

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    void Example() {
        print(animation["Walk"].length);
    }
}

 

 

 

 

AnimationState.normalizedSpeed  标准(标准化)速度

 

var normalizedSpeed : float

Description  描述

The normalized playback speed.

标准播放速度

This is most commonly used to synchronize playback speed when blending between two animations. In most cases it is easier and better to use animation.SyncLayer instead.

这个最常被用于同步播放速度,当两个动画之间混合时。在大多数情况下可以更容易更好的使用animation.SyncLayer instead

 

JS:

// Sync run and walk speed

//同步“跑”和“走”速度

animation["Run"].normalizedSpeed = animation["Walk"].speed;

 

C#:

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    void Example() {
        animation["Run"].normalizedSpeed = animation["Walk"].speed;
    }
}

 

 

AnimationState.normalizedTime  标准(标准化)时间

var normalizedTime : float

Description  描述

The normalized time of the animation.

动画的标准化时间

A value of 1 is the end of the animation. A value of 0.5 is the middle of the animation.

动画结尾的值为1。动画中间的值为0.5

JS:

// Fast forward to the middle of the animation

//快进到动画的中部

animation["Walk"].normalizedTime = 0.5;

 

C#:

using UnityEngine;
using System.Collections;
public class example : MonoBehaviour {
    void Example() {
        animation["Walk"].normalizedTime = 0.5F;
    }
}

 

 

AnimationState.speed  速度

 

var speed : float

Description  描述

The playback speed of the animation. 1 is normal playback speed.

动画的播放速度。“1”是正常的播放速度

A negative playback speed will play the animation backwards.

负(即,负数)的播放速度将播放动画的倒放

JS:

// Walk backwards

//倒着走

animation["Walk"].speed = -1.0;

// Walk at double speed

//两倍步速

animation["Walk"].speed = 2;

 

C#:

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    void Example() {
        animation["Walk"].speed = -1.0F;
        animation["Walk"].speed = 2;
    }
}

 

 

AnimationState.time   时间

var time : float

Description  描述

The current time of the animation

动画的当前时间

If the time is larger than length it will be wrapped according to wrapMode. The value can be larger than the animations length. In this case playback mode will remap the time before sampling. This value usually goes from 0 to infinity

如果时间大于实际长度,它将会按照wrapMode(循环模式)循环。这个值可以大于动画长度。在这种情况下播放模式将映射之前的时间采样。这个值通常从0到无穷(大)

 

JS:

// Rewind the walk animation

//倒回步行动画

animation["Walk"].time = 0.0;

C#:

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    void Example() {
        animation["Walk"].time = 0.0F;
    }
}

 

 

AnimationState.weight  权重

var weight : float

Description  描述

The weight of animation

动画的权重

This calculates the blend weights for one curve.

这是为了一个曲线计算混合权重

Weights are distributed so that the top layer gets everything. If it doesn't use the full weight then the next layer gets to distribute the remaining weights and so on. Once all weights are used by the top layers, no weights will be available for lower layers anymore Unity uses fair weighting, which means if a lower layer wants 80% and 50% have already been used up, the layer will NOT use up all weights. instead it will take up 80% of the 50%.

权重被分配以至于顶层获取任何一切。如果它没有使用全部权重以至于下一层获取其余权重的分配等等。一旦全部的权重通过顶层被使用,底层的Unity将没有权重可以用,这意味着,如果一个底层在已经消耗50%时还想(使用权重)消耗80%,这层将不会用尽全部的权重。反而将会消耗50%中的80%

Example: a upper body which is affected by wave, walk and idle a lower body which is affected by only walk and idle weight name layer lower upper
 20% wave 2 0% 20%
 50% walk 1 50% 40%
 100% idle 0 50% 40%

例如:上体受到wave, walk  idle 的影响,下体只受到 walk  idle权重名的影响

 20% wave 2 0% 20%
 50% walk 1 50% 40%
 100% idle 0 50% 40%

 

- Blend weights can change per animated value because of mixing. Even without mixing, sometimes a curve is just not defined. Still you want the blend weights to add up to 1. Most of the time weights are similar between curves.

混合权重会改变每一个动画的值由于混合。即使没有混合,有时曲线仅仅是没有定义。直到你想将混合权重增加到1。大多数时权重曲线之间是相似的。

 

JS:

// Set the blend weight of the walk animation to 0.5

//设置步行动画的混合权重为“0.5

animation["Walk"].weight = 0.5;

 

C#:

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    void Example() {
        animation["Walk"].weight = 0.5F;
    }
}

 

 

AnimationState.wrapMode  循环模式

 

var wrapMode : WrapMode

Description  描述

Wrapping mode of the animation.

动画的循环模式

By default wrapMode is initialized to the value set in the Animation component's wrap mode.

通过设置wrapMode(循环模式)的缺省值,设置 Animation component's动画组件)为循环模式。

 

JS:

// Set the wrap mode of the walk animation to loop

//设置步行动画的循环模式为loop(循环)

animation["Walk"].wrapMode = WrapMode.Loop;

 

C#:

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    void Example() {
        animation["Walk"].wrapMode = WrapMode.Loop;
    }
}

 

 

AnimationState.AddMixingTransform  添加混合Transform 转换)

 

function AddMixingTransform (mix : Transform, recursive : boolean = true) : void

Description  描述

Adds a transform which should be animated. This allows you to reduce the number of animations you have to create.

添加一个动画转换(这个转换应该为动画)。这是让你减少一定数量必要创建的动画。

For example you might have a handwaving animation. You might want to play the hand waving animation on a idle character or on a walking character. Either you have to create 2 hand waving animations one for idle, one for walking. By using mixing the hand waving animation will have full control of the shoulder. But the lower body will not be affected by it, and continue playing the idle or walk animation. Thus you only need one hand waving animation.

例如,可能你有的挥手动画。可能你想去操纵挥手动画在一个闲置的角色或在一个正在步行的角色上。或者你不得不创建2个挥手动画,一个给闲置(角色),一个给正在步行的(角色)。通过使用混合挥手动画,将会完全控制臂膀。但是下肢(下体)将不会受到控制,并且继续在空闲或步行动画运动。因此你只需要一个挥手动画。

If recursive is true all children of the mix transform will also be animated. If you don't call AddMixingTransform, all animation curves will be used.

如果循环为真(true),全部的混合转化也将变为子动画。如果你没有调用AddMixingTransform,全部动画曲线将被使用。

JS:

/// Adds a mixing transform using a path instead

///添加混合转换,使用另一种路径

var shoulder : Transform;
animation["wave_hand"].AddMixingTransform(shoulder);

 

C#:

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    public Transform shoulder;
    void Example() {
        animation["wave_hand"].AddMixingTransform(shoulder);
    }
}

 

Another example using a path. 

另一个例子所使用的路径

JS:

function Start () {
    // Adds a mixing transform using a path instead

    var mixTransform : Transform = transform.Find("root/upper_body/left_shoulder");
    animation["wave_hand"].AddMixingTransform(mixTransform);
}

 

C#:

using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    void Start() {
        Transform mixTransform = transform.Find("root/upper_body/left_shoulder");
        animation["wave_hand"].AddMixingTransform(mixTransform);
    }
}

<think>好的,我现在需要解决在Unity中检查Animation动画是否播放完毕的问题。根据用户提供的引用资料,我需要先了解现有的方法以及可能遇到的问题。 首先,引用[1]提到最初使用AnimationEvent来实现动画完成时的回调,但遇到倒播动画时事件在开始时触发的问题。这说明直接绑定事件可能不可靠,特别是当动画有反向播放的情况时。因此,可能需要寻找其他方法。 引用[2]讨论了Unity动画系统,指出控制播放流程和判断动画是否完成是常见需求。这里可能需要使用到动画状态的信息,比如normalizedTime属性来判断播放进度。但要注意动画循环的情况,normalizedTime超过1可能表示循环了一次。 引用[3]提到动态添加事件的方法,但指出动态添加的事件不会保存到动画控制器上。这可能涉及到在运行时通过代码添加回调,比如使用协程或者事件监听。 接下来,我需要整理可能的解决方案: 1. 使用AnimationEvent,但需要注意倒播的问题,可能需要根据动画的播放方向调整事件触发逻辑。不过这种方法可能有局限性,特别是当动画复杂时。 2. 通过检查动画的normalizedTime属性。当动画没有循环且normalizedTime >=1时,表示播放完毕。但需要处理循环的情况,或者在动画剪辑设置中禁用循环。 3. 使用协程等待动画播放时间。通过获取动画剪辑的长度,用WaitForSeconds等待相应时间后触发回调。这种方法简单,但如果有动画被加速或减速,时间可能不准确。 4. 使用事件监听,比如在代码中注册一个回调方法,在动画结束时调用。可能需要结合AnimationState的事件或者使用UnityEvent。 现在需要验证这些方法的可行性。例如,检查normalizedTime时,要确保动画是单次播放,或者在Update中持续监测。对于协程方法,要处理动画可能被中断的情况。 另外,引用[3]提到动态添加事件,可能涉及到在代码中为特定动画添加结束时的回调,而无需手动添加事件。这可以通过脚本在运行时绑定。 最后,用户可能需要具体的代码示例,所以需要提供不同方法的实现,并指出优缺点,帮助用户根据情况选择合适的方法。</think>在Unity中检查Animation动画是否播放完成,可通过以下方法实现: ### 方法一:通过normalizedTime属性判断 ```csharp Animation anim = GetComponent<Animation>(); AnimationClip clip = anim.clip; void Update() { if (anim.isPlaying && anim[clip.name].normalizedTime >= 1.0f) { // 动画播放完成的回调 OnAnimationComplete(); } } ``` 注意:需确保动画剪辑设置为单次播放(Wrap Mode=Once)[^2] ### 方法二:协程等待动画时长 ```csharp IEnumerator PlayAnimationAndWait(Animation animation, string clipName) { animation.Play(clipName); yield return new WaitForSeconds(animation[clipName].length); // 动画播放完成的回调 OnAnimationComplete(); } ``` 注意:动画加速/减速时需使用`animation[clipName].speed`调整等待时间 ### 方法三:动态添加AnimationEvent ```csharp void AddAnimationEvent(AnimationClip clip, float time) { AnimationEvent evt = new AnimationEvent(); evt.time = time; evt.functionName = "OnAnimationComplete"; clip.AddEvent(evt); } ``` 注意:倒播动画时需重新计算事件触发时间[^1] ### 方法四:Animator状态机检测 ```csharp Animator animator = GetComponent<Animator>(); IEnumerator CheckAnimationCompletion() { while (animator.GetCurrentAnimatorStateInfo(0).normalizedTime < 1.0f) { yield return null; } OnAnimationComplete(); } ``` 需配合Animator Controller使用[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值