NeoAxis 学习笔记 3

动画操作

 

在class Dynamic创建函数OnPostCreate()中初始化:

protected override void OnPostCreate( bool loaded )

{

    ...

    CreateAnimationController();

    ...

}

 

其中class MeshObjectAnimationController和class AnimationItem都不是引擎部分的,都是游戏部分的。

在class Dynamic的刷新函数中更新动画:

 

void OnRenderFrame()

{

    ...

    animationController.DoRenderFrame(); // 更新动画帧

    ...

 

   if( forceAnimationRemainingTime == 0 ) // 设置默认动画
      OnUpdateBaseAnimation();

}

 

当forceAnimationRemainingTime为0时,就为物体设置默认动画,这个函数在class Dynamic中没有实现,放到了具体的子类中实现,比如class GameCharacter中:

protected override void OnUpdateBaseAnimation()
  {
   base.OnUpdateBaseAnimation();

   //walk animation
   if( IsOnGround() && GroundRelativeVelocity.ToVec2().LengthSqr() > .3f )
   {
    float velocity = ( Rotation.GetInverse() * GroundRelativeVelocity ).X *
     Type.WalkAnimationVelocityMultiplier;
    UpdateBaseAnimation( Type.WalkAnimationName, true, true, velocity );
    return;
   }

   //idle animation
   {
    UpdateBaseAnimation( Type.IdleAnimationName, true, true, 1 );
    return;
   }
  }

根据速度,设置默认动画是idle或者walk。

 

当角色做了一个动作,比如跳时,需要设置一个临时的跳的动画来代替默认动画,

在class Dynamic function SetForceAnimation中:

public void SetForceAnimation( string animationBaseName, bool allowRandomAnimationNumber )

{

    ...

    //activate new animation
   currentAnimationItem = animationController.Add( animationBaseName,
    allowRandomAnimationNumber, false );
   if( currentAnimationItem != null )
    forceAnimationRemainingTime = currentAnimationItem.Length;

}

 

forceAnimationRemainingTime 作为临时动画的时间长度,在上面的function OnRenderFrame中,如果forceAnimationRemainingTime 为0,表示临时动画结束,就需要还原成默认动画了。

 

在function OnTick()中来更新临时动画的时间:

protected override void OnTick()

{

    ...

   if( animationController != null )
    TickForceAnimationRemainingTime();

}

 

void TickForceAnimationRemainingTime()
  {
   if( forceAnimationRemainingTime != 0 )
   {
    forceAnimationRemainingTime -= TickDelta;
    if( forceAnimationRemainingTime < 0 )
     forceAnimationRemainingTime = 0;
   }
  }

 

由于自己开发的需要,添加一个功能:添加多个动画,组成一个动画串,单个动画之间可以设置延时。

在class Dynamic里面添加一个结构定义和一个列表:

 

        // for delay animation
        struct DelayAnimationItem
        {
            public float delayTime;
            public string animationName;
        }
        List<DelayAnimationItem> delayAnimationList = new List<DelayAnimationItem>();

 

增加一个添加动画函数:

 

        public void AppendForceAnimation(string animationBaseName, float delayTime)
        {
            //!!!!!should to disable animation for disabled renderer
            if (animationController == null)
                return;

            if (delayTime <= 0.0f)
            {
                return;
            }

            DelayAnimationItem item = new DelayAnimationItem();
            item.delayTime = delayTime;
            item.animationName = animationBaseName;

            delayAnimationList.Add(item);
        }

 

暂时将动画保存到列表中,不支持从多个动画中随机选择,不支持循环播放的动画。

然后在function OnTick()函数中判断是否有等待播放的动画:

OnTick() --> TickForceAnimationRemainingTime()

修改TickForceAnimationRemainingTime()为如下:

 

        void TickForceAnimationRemainingTime()
        {
            if (delayAnimationList.Count > 0)
            {
                DelayAnimationItem item = delayAnimationList[0];
                item.delayTime -= TickDelta;
                if (item.delayTime <= 0.0f)
                {
                    SetForceAnimation(item.animationName, false);
                    delayAnimationList.RemoveAt(0);
                }
                else
                {
                    delayAnimationList[0] = item;
                }
            }
            else if( forceAnimationRemainingTime != 0 )
            {
                forceAnimationRemainingTime -= TickDelta;
                if( forceAnimationRemainingTime < 0 )
                    forceAnimationRemainingTime = 0;
            }
        }

 

因为对延时精度要求不高,所以在OnTick中调用。

在一个动画播放完毕之后,需要判断是否有其他动画等待播放,如果有,则减小延时,播放动画,如果没有,则回到默认动画。

修改function OnRenderFrame()为如下:

 

protected override void OnRenderFrame()

{

    ...

            //animation management
            if( animationController != null )
            {
                if( EntitySystemWorld.Instance.Simulation &&
                    !EntitySystemWorld.Instance.SystemPauseOfSimulation )
                {
                    if (0 == delayAnimationList.Count || 0 < forceAnimationRemainingTime)
                        animationController.DoRenderFrame();

                    if( currentAnimationItem != null && currentAnimationItem.Removed )
                        currentAnimationItem = null;
                    if( forceAnimationRemainingTime != 0 && currentAnimationItem == null )
                        forceAnimationRemainingTime = 0;

                    if (forceAnimationRemainingTime == 0 && 0 == delayAnimationList.Count)
                        OnUpdateBaseAnimation();
                }
            }

}

当临时动画播放完,并且有下一个临时动画等待播放时,不更新动画;当临时动画播放完,并且没有其他临时动画等待执行时,才返回到默认动画。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值