unity code-动作系统Animator

AnimatorOverrideController是运行时版本

可以运行时更改controller,AnimatorController是编辑器版本,不能运行时修改,所以运行时只能通过用AnimatorOverrideController来替换才行

CreateObject

Animator是动作状态机的入口,他是继承Behaviour的,所以他能拖到gameobject上去

AwakeFromLoad首先执行CreateObject,他会先清理对象ClearObject();

avatarConstant = m_Avatar->GetAsset();这个是获取Avatar对象,是动作的对应的avatar对象,会拿到骨骼信息来做动作。

申请内存大小:

mecanim::animation::CreateAvatarConstant是用来创建avatar的AvatarConstant,然后设置human属性,骨骼属性等,

mecanim::animation::CreateAvatarMemory是创建avatar的内存地址大小,跟数据结构有关。

mecanim::animation::CreateAvatarInput是输入内存大小申请

mecanim::animation::CreateAvatarWorkspace是创建avatar的骨骼等内存对象,

这些申请的过程都是alloc.Construct<>();的方式申请的。

CreateAvatarOutputreateAvatarOutput是输出内存大小申请,

CreateAvatarBindingConstant创建avatar的绑定数据结构申请,

SetAvatarPosition(transform.GetPosition()); SetAvatarRotation(transform.GetRotation()); SetAvatarScale(transform.GetWorldScaleLossy());

这里设置avatar的位置旋转缩放信息。

editor下创建对象:

然后就是对AnimatorController的GetAssets,m_Controller->GetAsset(),因为AnimatorController只针对editor下创建,运行时只获取,所以editor下执行BuildAsset。

这里时获取animtorcontroller里面的属性,是在AnimatorControllerParameter中的m_AnimatorParameters的属性。

然后写入到mecanim::ValueArray中。

状态机:

然后状态机的处理:

这里是通过m_AnimatorLayers拿到所有animator的层级,然后加入到stateMachineIndexVector索引中。

这里是获取每一层的动作剪辑然后放到stateMachineVector。

这里包括是否有ik,是否混合,是否有权重,身体遮挡,骨骼遮挡。

在AnimationSetBindings中。

m_AnimationSetBindings = UnityEngine::Animation::CreateAnimationSetBindings(m_Controller, GetAnimationClips(), m_Allocator);

这里就是拿出输入的绑定,动作剪影以及申请的内存,所有设置到outputBindings中。

设置状态机树状结构以及混合:

在Animator::CreateObject()的m_Controller->GetAnimationSetBindings();后通过SetupControllerMecanimDataSet设置animation的数据到outMecanimDataSet中。

在Animator::SetupControllerMecanimDataSet中UpdateLeafNodeDuration是更新动作状态机的树的数据结构。

然后通过animation::BlendTreeMemory *GetBlendTreeMemory设置混合树到arStateMemory.m_BlendTreeMemoryArray中。

avatar动画系统:

在AvatarBuilder下的BuildAvatar就是创建avatar动作的地方,

GenerateAvatarMap:

然后执行AvatarBuilder::GenerateAvatarMap,首先他会通过GetAllChildren来获取所有子对象,然后如果是kHumanoid类型通过GetHipsNode来找到hip骨骼节点就是他的根骨骼节点,如果是kGeneric类型则通过GetRootMotionNode找到根节点。

如果有用mask功能,则会在GetAllChildren的时候通过mask的才加入到对象列表。

然后他会申请内存ChainedAllocator,大小是30*1024。这个内存大小用于后面的BuildSkeleton,CreateSkeletonPose,nameIDArray,BuildHumanSkeleton,BuildRootMotionSkeleton

BuildSkeleton:

通过CreateSkeleton来创建Skeleton数据结构

并对每个骨骼赋值

avatarPose和avatarGPose 是通过CreateSkeletonPose创建出来的局部的pose数据和global的pose数据。

ReadFromLocalTransformToSkeletonPose

然后ReadFromLocalTransformToSkeletonPose是namedTransform中读取位置缩放旋转的值放到SkeletonPose的m_X中。

然后SkeletonPoseComputeGlobal是赋值到avatarGPose 也就是global的pose。

然后还会创建avatarDefaultPose就是默认的pose。

leftHandValid和rightHandValid是找到左手和右手。

BuildHumanSkeleton

然后如果是humen类型则BuildHumanSkeleton创建骨骼,humanPose和humanGPose对应人体的局部和全局pose。然后通过CreateHuman来创建人体骨骼结构,里面已经对应好骨骼的关系

struct Human

后面赋值到这些结构体中。

然后mecanim::skeleton::SkeletonPoseCopy(avatarSK,avatarGPose,humanSK,humanGPose);这里是赋值骨骼数据到humanGPose中。

然后设置三块

是他的重力以及他的轴和他的碰撞体。

最后让Avatar这个结构体SetAsset设置avatarConstant的数据到Avatar类的m_Avatar中。

完成创建。

在CharacterTestFixture.h的CreateAvatars中有相关的例子。

猜你喜欢

转载自blog.csdn.net/llsansun/article/details/123038361
今日推荐