Unity—Mecanim动画系统

这两天学习了动画系统,接下来学习物理引擎和粒子特效!

每日一句:你只管自信,其他的交给别人来说

目录

Mecanim动画系统

新特性

常用名词:

步骤:

模型动画的导入

Animator动画状态机

Mecanim BlendTree(混合树)

Mecanim BlendTree2D

Mecanim层设置(Layer)

动画事件

判断动画是否在播放


Mecanim动画系统

新特性

·针对人性角色提供了一种特殊的工作流,包含Avatar的创建和对肌肉的调节

·动画重定向(Retargetina)的能力,可以非常方便地把动画从一个角色模型应用到其他角色上

·提供了可视化Animator视窗,可以直观地通过动画参数和Transition(动画过度线)等管理各个动画间的过度

常用名词:

Animator Mecanim动画系统动画组件

AnimatorCotorller  动画状态机(控制机)

Avatarˈævətɑː(r)/ Meccanim可识别的骨骼

Retargeting  角色之间动画的互用

步骤:

1.选择到模型源文件查看,修改Animation Type(动画样式)

【Model

 Scale Factor 0.01模型比例因数

 Rig

Animation Type(动画样式)Legacy默认—Animation、Generic非人型、Humanoid人型

 Avatar Definition  Avatar定义,用来创建骨骼映射】

2.Apply应用后自动生成Animator组件、Avatar

【Animator组件APPly Root Motion属性 是否对位置、旋转产生影响】

3.Configure 若为√显示,则骨骼匹配成功,若为×,则需要重新匹配

【单击Configure按钮,进入Avatar配置界面

Mapping骨骼映射  Muscles Settings肌肉设置(一般默认)】

4.创建状态机Creat—>Animator Controller,拖入到

5.找到Window—>Animator面板(或双击状态机),把动画拖到面板

模型动画的导入

【Animation

Loop Time循环播放片段

Bake Into Pose 只进行动画,不会对旋转、位置产生影响

Loop match 首尾属性没有发生变化】

Animator动画状态机

动画参数parameters  当满足什么条件进行动画衔接

脚本:找组件+为切换条件赋值

private Animator anim;

void Start()

{anim=this.GetComponent<Animator>();}

private void Update()

{if(anim)

 { anim.SetFloat=Input.GetAxis(WSFloat,Vertical);}正向返回1,负向返回-1,不按返回0

只要不按键“WSFloat”值为0,按W键,慢慢增长为1,过程中会出现大于0.1的情况,切换动画,松开键值回到0

 【或】

 【并且】

 

【仅供参考,此图有待完善】 

public class BehaviourScript1 : MonoBehaviour

{

    private Animator anim;

    private void Start()

    {

        anim = this.GetComponent<Animator>();

    }

    private void Update()

    {

        if(anim!=null)

        {

            anim.SetFloat("ADFloat", Input.GetAxis("Horizontal"));

            anim.SetFloat("WSFloat", Input.GetAxis("Vertical"));

            anim.SetBool("ShiftBool", Input.GetKeyDown(KeyCode.RightShift));

            anim.SetBool("SpaceBool", Input.GetKeyDown(KeyCode.Space));

        }

    }

}

Mecanim BlendTree(混合树)

对两个或更多个相似的运动进行混合,可实现一个动画状态有多个动画效果

1.Animator Controller视图右键

Create State—>From New Blend

2.双击进入混合树视图(双击空白部分可回去)

[混合树动画参数]

3.在Inspector面板中Add Motion Field

                                                            [可自定义]

[前后左右跑]

 private void Update()

    {

        if(anim!=null)

        {

            anim.SetFloat("ADFloat", Input.GetAxis("Horizontal"));

            anim.SetFloat("WSFloat", Input.GetAxis("Vertical"));

        }

    }

Mecanim BlendTree2D

通过2个动画参数控制动画切换

Blend Type:2D Freeform Directional

[Mecanim BlendTree2D]

[2个动画参数]

Mecanim层设置(Layer)

用于动画混合效果(如边跑步边攻击)

【不同的骨骼位置有不同的动画表现效果(攻击只动上半身,把上半身骨骼遮罩住)】

Animator Layers +:

添加层,通过Weight设置动画权重

【weight权重,指某个动画层在整个动画中的影响

  0为此层动画与整个动画完全不融合

  1为此层动画与整个动画融合】

Mask控制动画混合位置,并将此层需要的动画拖到面板中

Create—>Avatar Mask

[Avatar Mask 攻击只动上半身,就把上半身遮罩住了]

SetLayerWeight(int LayerIndex,float weight)

加一个空的动画,以免造成这个层权重到1了,播到一半接着播

动画事件

找到源文件—>找到需要的动画,用事件调用方法

(当播放攻击动画,对方有减血效果……)

Events 添加事件

 

[Function 方法  Float,Int,String,Object传入的参数]

到某一时刻,给角色换装

void Changecloth(Texture cloth)

{this.GetComponentInChildren<Renderer>().material.mainTesture=cloth;}

Any State  可以从任意状态切换过去,但不能切换回来

public class DieBehaviourScript1 : MonoBehaviour

{

    private Animator anim;

    public int score = 5;

    private bool dieBool = true;

    // Start is called before the first frame update

    void Start()

    {

        anim = this.GetComponent<Animator>();

    }



    // Update is called once per frame

    void Update()

    {

        if(Input.GetKeyDown(KeyCode.Space))

        {

            if (score > 0)

                score -= 1;

        }

    }

    //动画切换

    private void AnimFunc()

    {

        if(anim!=null&&dieBool)//因为在Update里调用的,给个bool,不让一直调

        {

            anim.SetBool("DieBool", score <= 0);

        }

    }

    public void DieEvent()

    {

        anim.SetBool("DieBool", false);

        dieBool = false;

    }

}

Animator Override Controller 继承状态机

判断动画是否在播放

Animator anim;

int idel=Animator.StringToHash(“Base layer.Idle”);

AnimatorStateInfo  currentBaseStage;//当前播放的动画

void Start()

{anim=GetComponent<Animator>();}

void Update()

{ currentBaseStage=anim.GetCurrentAnimatorStateInfo(0);//当前播放的动画

if(currentBaseStage.nameHash==idle&&!anim.IsInTransition(0))//正在播放待机动画,并且没有动画衔接

{anim.SetBool(“hit”,false);

}

猜你喜欢

转载自blog.csdn.net/m0_63330263/article/details/126364445