关于动画结束的处理

一时兴起,写了这一篇文章。在实际开发中为了更好的表现,需要在一段动画播放后,再做别的行为

这篇文章3月6日开始定题,3月22日写完初稿,5月4日再补充一点,今天发布。

一.不同的动画组件

  1. 动画美术直接编辑动画,定位到要变化挂点的帧(比如24帧),在Events里添加一个动画事件, 名字规范成 TakeWeapon


这个方案

优:让美术准确控制帧数, 可以个性化
劣:所有模型该动作都要加一下。

二.用程序添加

网上有animation添加事件的

    AnimationEvent evt = new AnimationEvent();
    evt.time = 0;
    evt.functionName = "Test";
    animation.GetClip("ani").AddEvent(evt);

但我们现在用的新动画系统Animator, 如何找到对应名字的动画呢?
找了一下 Animator的接口和成员变量,还是有一个可用的:

 for(int i=0;i< animator.runtimeAnimatorController.animationClips.Length;++i)
 {
     if(animator.runtimeAnimatorController.animationClips[i].name == name)
     {
         return animator.runtimeAnimatorController.animationClips[i];
     }
 }

能找到对应的名字的 animationClip,然后就可以

     AnimationEvent evt = new AnimationEvent();
     evt.time = 24f/30;
     evt.functionName = "TakeWeapon";
     animClip.AddEvent(evt);

优:所有角色动画动作可以统一处理,不需要美术再加工

劣:时间不太好做个性化。

事件绑定好了,但是执行时报错误:
AnimationEvent ‘TakeWeapon’ has no receiver!
原来 TakeWeapon方法所在脚本必须挂在Animation(或Animator)所在GameObject上!

三.当使用Animator组件的时候

void Update()
{
    var stateInfo = an.GetCurrentAnimatorStateInfo(0);
    if(stateInfo.IsName(_openName)&& stateInfo.normalizedTime >= 1f)
    {
        //播放结束
    }
}

四.使用IEnumerator 等待动画的长度

Animation Anim;
float time = Anim.Getclip("anim1").Length;
private IEnumerator WaitAnimationEnd()
{
    yield return new WaitForSeconds(time);
    EndAnimation();
}

private void EndAnimation()
{
    // 动作播放结束
}

五.使用Animation踩的坑

1. 有一个头像大小缩放的动画,从Animation是没有任何问题的,但实际代码调用的时候,一直不执行。

功能开发中,优先级并不是特别高。就一直没查。
后来查找原因,当界面没有打开的状态下,执行动画的播放.当界面打开的时候再播放,动画部生效了,所以在animation调用的时候,要一句

 if(this.gameObject.activeInHierarchy == false)return;
2.基于四的思路,做了一个文字动画反复播放显示的内容。当同时添加两段文字的时候,只播放了一次。设计上是将文字做了队列缓存 。当一个动画播完在播放另一个。
private Animation Anim;
public Queue<string> TipsStringQueue = new Queue<string>();
 //Add String
public void AddString(string tips)
{
    TipsStringQueue.Enqueue(tips);
    if(!Anim.isPlaying)
    {
        ParseString();
    }
}

private void ParseString()
{
    if(TipsStringQueue.count == 0)
        return;
    string tips = TipsStringQueue.Dequeue();
    if(!string.IsNullOrEmpty(tips))
    {
        //Json解析
        //UI元素赋值
        Anim["Anim01"].time = 0;
        Anim.Play();
        StopCoroutine(WaitAnimationEnd());
        StartCoroutine(WaitAnimationEnd());
    }
}
private IEnumerator WaitAnimationEnd()
{
    yield return new WaitForSeconds(Anim.GetClip("Anim01").length);
    EndAnimation();
}

private void EndAnimation()
{
    if(TipsStringQueue.count>0)
    {
        ParseString();
    }
}

Anim[“Anim01”].time = 0;在Play()之前写这句很重要的,不然就会出现当同时加入两个文字的时候,播放一次。

补充 把Loop的Animation停止指定帧

当时实习生遇到,把一个Loop的动画停在初始帧。
把循环动画停在指定的帧上,先给time赋值,在simple(),在stop()。

private void StoLoopAnimationOnBegin()
 {
        Animation an;
        an["an1"].time = 0;
        an.Sample();
        an.Stop();
 }
原因是

在调用了动画播放之后,动画并不会立即应用(骨骼Transform并不会立即改变),最快也要等到本帧lateUpdate才能生效。

如果有特殊需求,希望在调用了动画播放之后立即生效,则可以紧接着调一句Animation.sample()

JavaScript 的 `animate` 函数通常是指使用 CSS 动画或者 jQuery 的 `.animate()` 方法来创建动画效果。在处理动画时,我们有时会关心动画是否已经成。为了监听动画结束事件,我们可以使用以下几种方法: ### 1. 使用 CSS Keyframes 和 Animation Events 如果你在直接操作 CSS 动画,那么可以利用动画事件属性来监听动画结束后的行为。 #### 示例代码: 假设我们有一个元素 `#myElement`,我们希望当动画结束时触发一些操作,可以这样编写: ```css #myElement { animation-name: fadeIn; animation-duration: 2s; /* 定义动画持续时间 */ animation-fill-mode: forwards; /* 确保最后状态被保留 */ /* 当动画成时执行的操作 */ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } } #myElement:hover { animation-play-state: paused; /* 当鼠标悬停时暂停动画 */ } /* 当动画成时触发的动作 */ .myElement-animation-end { // 这里可以放置你想在动画成后执行的代码 } ``` ### 2. 使用 JavaScript/jQuery .animate() 方法 如果你正在使用 `.animate()` 方法(通常是通过 jQuery 实现),可以通过在回调函数中检查动画是否已成。 #### 示例代码: ```javascript $( "#myElement" ).animate({ height: "toggle", /* 调整高度为折叠效果 */ opacity: "toggle", /* 改变透明度为折叠效果 */ }, function() { $(this).addClass('myElement-animation-end'); /* 加上表示动画成的类 */ }); ``` 在这个例子中,当动画开始时,`.myElement` 元素的高度和透明度都会变化。动画结束后,所有元素都会添加 `myElement-animation-end` 类。这个类可以进一步地被用于在 CSS 中定义动画结束后想要实现的效果。 ### 相关问题 - 动画事件和监听技巧: 1. **如何区分动画的不同阶段(开始、成、正在进行)**?在 CSS 和 JavaScript/jQuery 的解决方案中,都可以通过观察 `animationStart`、`animationEnd` 和 `transitionEnd` 等事件来区分动画的不同阶段。 2. **如何优化动画性能**?理解动画性能涉及的关键因素,如避免不必要的计算、限制动画次数、合理使用缓存以及考虑浏览器差异等。 3. **动态生成动画**?了解如何在运行时创建新的动画,这在需要根据用户输入或其他动态数据生成动画时特别有用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值