{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/unity-animation-system/",
  "atlas": "https://www.pystone.net/?node=unity-animation-system#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/unity-animation-system.md",
  "context": "https://www.pystone.net/notes/unity-animation-system.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:unity-animation-system",
  "slug": "unity-animation-system",
  "title": "【动画】Unity动画系统",
  "type": "note",
  "visibility": "public",
  "idStability": "rename-stable",
  "author": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "publisher": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "aliases": [],
  "summary": "【动画】Unity动画系统",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "950b7459a8e087ac2611596511902cafe72cae0ef3f427a72bd3b2509fed9d15",
  "assets": [
    {
      "reference": "assets/1615977607114.png",
      "url": "/media/b7934311c461acb00b77.png",
      "mediaType": "image/png",
      "contentHash": "b7934311c461acb00b77e79be8f4c3f3beb421a3b4128e25ce5731997790af97",
      "byteLength": 23859,
      "width": 400,
      "height": 219
    },
    {
      "reference": "assets/1615977339562.png",
      "url": "/media/e35715921abf078f3ca5.png",
      "mediaType": "image/png",
      "contentHash": "e35715921abf078f3ca5e3f617eb12a01b9e2c6ba0a22eddcfa62711d2cfa5b5",
      "byteLength": 10959,
      "width": 378,
      "height": 119
    },
    {
      "reference": "assets/1615977392724.png",
      "url": "/media/d9ac80bd8b1b73d4c88e.png",
      "mediaType": "image/png",
      "contentHash": "d9ac80bd8b1b73d4c88ea8102aaa089853a9b71085440141df00622a66881814",
      "byteLength": 12291,
      "width": 363,
      "height": 128
    },
    {
      "reference": "assets/1615984365722.png",
      "url": "/media/901bb27d26310f5d5793.png",
      "mediaType": "image/png",
      "contentHash": "901bb27d26310f5d57939c0940acad4888d4dfee51d45934f3e88260cd21ed54",
      "byteLength": 44695,
      "width": 734,
      "height": 503
    },
    {
      "reference": "assets/1615984621432.png",
      "url": "/media/3a63345df04a146668fd.png",
      "mediaType": "image/png",
      "contentHash": "3a63345df04a146668fd59674364ee0399c3457833ff3e1df92631ddfdc8da3a",
      "byteLength": 42215,
      "width": 739,
      "height": 401
    },
    {
      "reference": "assets/1615987896583.png",
      "url": "/media/33a59c65d2c2af5be1d1.png",
      "mediaType": "image/png",
      "contentHash": "33a59c65d2c2af5be1d18d0d9e624dd8a8f22ec37582ca3a125cdb03e8a5542d",
      "byteLength": 25869,
      "width": 559,
      "height": 220
    },
    {
      "reference": "assets/1615988240440.png",
      "url": "/media/39ce420caae4eb3c4977.png",
      "mediaType": "image/png",
      "contentHash": "39ce420caae4eb3c4977da71b2598dd9f3023a9fffaa99ddc34724f149c072e4",
      "byteLength": 20225,
      "width": 526,
      "height": 308
    },
    {
      "reference": "assets/1615987356620.png",
      "url": "/media/290118a3d6df11e4d869.png",
      "mediaType": "image/png",
      "contentHash": "290118a3d6df11e4d8695e31f9257ca24ad364aaeab082ccf836580ed87396ef",
      "byteLength": 35667,
      "width": 744,
      "height": 423
    },
    {
      "reference": "assets/1615987405918.png",
      "url": "/media/63ea3eb70c1c92706a79.png",
      "mediaType": "image/png",
      "contentHash": "63ea3eb70c1c92706a7939fbfff04ca1e4cf03bd995dc8075fe615b8ab3e43ea",
      "byteLength": 98546,
      "width": 810,
      "height": 617
    },
    {
      "reference": "assets/1615987432960.png",
      "url": "/media/26d28fc1b0937a5e37ae.png",
      "mediaType": "image/png",
      "contentHash": "26d28fc1b0937a5e37ae4839716b2a6b4851331e2d6ba92edcfcf4eadf571e68",
      "byteLength": 6528,
      "width": 235,
      "height": 132
    },
    {
      "reference": "assets/1615987484236.png",
      "url": "/media/169759bd585b3257ff51.png",
      "mediaType": "image/png",
      "contentHash": "169759bd585b3257ff51b27c37995183160e2bdb9ea7ff8678f7ff0b79ef9206",
      "byteLength": 9132,
      "width": 484,
      "height": 180
    },
    {
      "reference": "assets/1615989784924.png",
      "url": "/media/1b9935734fc54c37394f.png",
      "mediaType": "image/png",
      "contentHash": "1b9935734fc54c37394f4d21473f5955e31e9b1ab7f539289b310379102159dc",
      "byteLength": 36525,
      "width": 540,
      "height": 334
    },
    {
      "reference": "assets/1615989156276.png",
      "url": "/media/3dbc1f8ebaa1ddd2122e.png",
      "mediaType": "image/png",
      "contentHash": "3dbc1f8ebaa1ddd2122e785a8ce9fdcd9e28fce31ac4be5fe864e2bc47a35c0b",
      "byteLength": 13521,
      "width": 560,
      "height": 105
    }
  ],
  "headings": [
    {
      "depth": 1,
      "text": "【动画】Unity动画系统",
      "anchor": "动画unity动画系统",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#%E5%8A%A8%E7%94%BBunity%E5%8A%A8%E7%94%BB%E7%B3%BB%E7%BB%9F"
    },
    {
      "depth": 2,
      "text": "Animation System Overview",
      "anchor": "animation-system-overview",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#animation-system-overview"
    },
    {
      "depth": 3,
      "text": "Animation Type",
      "anchor": "animation-type",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#animation-type"
    },
    {
      "depth": 4,
      "text": "Generic",
      "anchor": "generic",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#generic"
    },
    {
      "depth": 4,
      "text": "Humanoid",
      "anchor": "humanoid",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#humanoid"
    },
    {
      "depth": 4,
      "text": "Legacy Animation System",
      "anchor": "legacy-animation-system",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#legacy-animation-system"
    },
    {
      "depth": 4,
      "text": "pros and cons",
      "anchor": "pros-and-cons",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#pros-and-cons"
    },
    {
      "depth": 4,
      "text": "性能差异",
      "anchor": "性能差异",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#%E6%80%A7%E8%83%BD%E5%B7%AE%E5%BC%82"
    },
    {
      "depth": 3,
      "text": "关于 “Mecanim 动画系统”",
      "anchor": "关于-mecanim-动画系统",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#%E5%85%B3%E4%BA%8E-mecanim-%E5%8A%A8%E7%94%BB%E7%B3%BB%E7%BB%9F"
    },
    {
      "depth": 2,
      "text": "角色模型动画Workflow",
      "anchor": "角色模型动画workflow",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#%E8%A7%92%E8%89%B2%E6%A8%A1%E5%9E%8B%E5%8A%A8%E7%94%BBworkflow"
    },
    {
      "depth": 2,
      "text": "ImportSettings操作",
      "anchor": "importsettings操作",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#importsettings%E6%93%8D%E4%BD%9C"
    },
    {
      "depth": 3,
      "text": "ApplyRootMotion",
      "anchor": "applyrootmotion",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#applyrootmotion"
    },
    {
      "depth": 4,
      "text": "自定义RootMotionNode",
      "anchor": "自定义rootmotionnode",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#%E8%87%AA%E5%AE%9A%E4%B9%89rootmotionnode"
    },
    {
      "depth": 4,
      "text": "性能问题",
      "anchor": "性能问题",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#%E6%80%A7%E8%83%BD%E9%97%AE%E9%A2%98"
    },
    {
      "depth": 3,
      "text": "动画剪辑",
      "anchor": "动画剪辑",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#%E5%8A%A8%E7%94%BB%E5%89%AA%E8%BE%91"
    },
    {
      "depth": 3,
      "text": "其它参数",
      "anchor": "其它参数",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#%E5%85%B6%E5%AE%83%E5%8F%82%E6%95%B0"
    },
    {
      "depth": 2,
      "text": "Animator组件的属性",
      "anchor": "animator组件的属性",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#animator%E7%BB%84%E4%BB%B6%E7%9A%84%E5%B1%9E%E6%80%A7"
    },
    {
      "depth": 2,
      "text": "AnimationController",
      "anchor": "animationcontroller",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#animationcontroller"
    },
    {
      "depth": 3,
      "text": "Sub-State Machine",
      "anchor": "sub-state-machine",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#sub-state-machine"
    },
    {
      "depth": 3,
      "text": "Blend Tree",
      "anchor": "blend-tree",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#blend-tree"
    },
    {
      "depth": 3,
      "text": "动画过渡",
      "anchor": "动画过渡",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#%E5%8A%A8%E7%94%BB%E8%BF%87%E6%B8%A1"
    },
    {
      "depth": 3,
      "text": "State配置",
      "anchor": "state配置",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#state%E9%85%8D%E7%BD%AE"
    },
    {
      "depth": 2,
      "text": "Animator Override Controller",
      "anchor": "animator-override-controller",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#animator-override-controller"
    },
    {
      "depth": 2,
      "text": "事件机制",
      "anchor": "事件机制",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#%E4%BA%8B%E4%BB%B6%E6%9C%BA%E5%88%B6"
    },
    {
      "depth": 3,
      "text": "Mono—>SMB的通信",
      "anchor": "monosmb的通信",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#monosmb%E7%9A%84%E9%80%9A%E4%BF%A1"
    },
    {
      "depth": 3,
      "text": "SMB—>Mono的通信",
      "anchor": "smbmono的通信",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#smbmono%E7%9A%84%E9%80%9A%E4%BF%A1"
    },
    {
      "depth": 2,
      "text": "Avatar相关",
      "anchor": "avatar相关",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#avatar%E7%9B%B8%E5%85%B3"
    },
    {
      "depth": 2,
      "text": "一些API",
      "anchor": "一些api",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#%E4%B8%80%E4%BA%9Bapi"
    },
    {
      "depth": 2,
      "text": "动画系统性能",
      "anchor": "动画系统性能",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#%E5%8A%A8%E7%94%BB%E7%B3%BB%E7%BB%9F%E6%80%A7%E8%83%BD"
    },
    {
      "depth": 3,
      "text": "多角色场景解决方案",
      "anchor": "多角色场景解决方案",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#%E5%A4%9A%E8%A7%92%E8%89%B2%E5%9C%BA%E6%99%AF%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88"
    },
    {
      "depth": 4,
      "text": "Bake Mesh",
      "anchor": "bake-mesh",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#bake-mesh"
    },
    {
      "depth": 4,
      "text": "GPU Skinning",
      "anchor": "gpu-skinning",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#gpu-skinning"
    },
    {
      "depth": 2,
      "text": "Ref",
      "anchor": "ref",
      "citation": "https://www.pystone.net/notes/unity-animation-system/#ref"
    }
  ],
  "claims": [],
  "outgoing": [],
  "incoming": [
    {
      "id": "note:game-graphics-and-runtime",
      "title": "游戏图形与运行时",
      "url": "https://www.pystone.net/notes/game-graphics-and-runtime/",
      "atlas": "https://www.pystone.net/?node=game-graphics-and-runtime#knowledge-atlas",
      "label": "游戏图形与运行时",
      "origin": "explicit",
      "humanReviewed": true,
      "context": "Unity中的“【动画】Unity动画系统”导航项",
      "citation": "https://www.pystone.net/notes/game-graphics-and-runtime/#unity"
    }
  ],
  "contentMarkdown": "# 【动画】Unity动画系统\n\n> 创建时间：2021/3/17 17:49\n\n  * 【动画】Unity动画系统\n    * Animation System Overview\n      * Animation Type\n        * Generic\n        * Humanoid\n        * Legacy Animation System\n        * pros and cons\n        * 性能差异\n      * 关于 “Mecanim 动画系统”\n    * 角色模型动画Workflow\n    * ImportSettings操作\n      * ApplyRootMotion\n        * 自定义RootMotionNode\n        * 性能问题\n      * 动画剪辑\n      * 其它参数\n    * Animator组件的属性\n    * AnimationController\n      * Sub-State Machine\n      * Blend Tree\n      * 动画过渡\n      * State配置\n    * Animator Override Controller\n    * 事件机制\n      * Mono—>SMB的通信\n      * SMB—>Mono的通信\n    * Avatar相关\n    * 一些API\n    * 动画系统性能\n      * 多角色场景解决方案\n        * Bake Mesh\n        * GPU Skinning\n    * Ref\n\n## Animation System Overview\n\n### Animation Type\n\n#### Generic\n\nThe Root node allows Unity to establish consistency between Animation clips for a generic model.\n\n#### Humanoid\n\nWith rare exceptions, humanoid models have the same basic structure. This structure represents the major articulated parts of the body: the head and limbs. The first step to using Unity’s Humanoid animation features is to set up and configure an Avatar. Unity uses the Avatar to map the simplified humanoid bone structure to the actual bones present in the Model’s skeleton.\n\n#### Legacy Animation System\n\nOur legacy animation system is only included for backward compatibility with old projects, and it has a very limited feature set compared with our current animation system. The only reason you should use it is for legacy projects built using the old system.\n\n#### pros and cons\n\n  * Humanoid allows for retargeting animations on all humanoid type characters. Mecanim allows a better integration of humanoid avatars.\n\n  * Generic allows for characters that aren’t humanoid and doesn’t match the humanoid mecanim structure.\n\nHumanoid requires you to have only 2 spine bones. Generic doesn’t have that restriction.\n\n* * *\n\nThe Humanoid system is used for animating human body types. This can mean humans, robots, upright animals, or whatever else you can think of that looks like a human. In any case, for this type of animation, it is best to create the animations in a separate modelling program, and then import them to Unity. If the model is correctly rigged, everything should import very smoothly.\n\nThe Generic system is very simple. It is used for any type of animation that is not humanoid. You can use it to open a door, fire a gun, etc.. For this type of animation, it is probably easier to use the animation editor that Unity provides to make your animations.\n\n* * *\n\nHumanoid与Generic是不太可能完全相同的。Humanoid模式其本质是让通过Unity引擎自己的Avatar模板来驱动的，这个模板仅有30~35根骨骼（具体数字忘记了），而一般3D Max做出来的模型，其骨骼是很难与之一一对应，比如你上图中的手骨，其在3D Max中很可能是有动画的，而在Humanoid中主要还是映射过去计算的。这样就存在了部分骨骼之间的骨骼位置不一致，从而导致了Skinning后的结果也会不一致。\n\nHumanoid模式使用的精髓还在于Retargeting，而这一点就基本上决定了不可能与原始动画完全一致，如果想要完全一致，Unity提供了另一种模式：Generic。\n<https://answer.uwa4d.com/question/5a38b5775f86da7f0e37863d>\n\n* * *\n\n> Legacy is outdated and probably going to be phased out. So there are no pros with it.\n\n#### 性能差异\n\n```csharp\nclass Program\n{\n    static void Main(string[] args)\n    {\n        dynamic dyn = 1;\n        object obj = 1;\n        dyn = dyn + 3;\n        //obj = obj + 3; 报错\n\n        // Rest the mouse pointer over dyn and obj to see their\n        // types at compile time.\n        System.Console.WriteLine(dyn.GetType());\n        System.Console.WriteLine(obj.GetType());\n    }\n}\n\n```\n\n作者： _ArayA_\n链接：<https://www.jianshu.com/p/6fc0332357e8>\n来源：简书\n著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。\n\n### 关于 “Mecanim 动画系统”\n\nMecanim integrated humanoid animation retargeting, muscle control, and the state machine system.\nMecanim 并没有清楚的定义与边界。\n“Mecanim” has now simply come to mean our main animation system.\nUnity的Mecanim动画系统，是一套基于状态机的动画控制系统，是一个面向动画应用的动画系统。\n\n> Mecanim operated only with humanoid characters, our legacy animation system was still required for animating non-humanoid characters and other keyframe-based animation of gameobjects within Unity.\n\n## 角色模型动画Workflow\n\n1.通过建模软件创建角色模型网格（涉及建模软件的使用）\n2.针对角色姿态，以及动画布置，创建角色骨骼\n3.进行骨骼的蒙皮，将网格和角色网格绑定起来（顶点权重调整）\n4.利用绑定好骨骼的角色制作动画，导出资源\n5.Unity提取资源文件中的人物模型，提取动画切片（Clip）\n6.通过Mecanim动画系统进行编辑，创建动画状态，动画的融合、过渡调整，设定过渡条件，结合脚本控制，将动画应用到游戏开发中\n\n> 需要我们在网格建立的时候考虑应用动画是对于网格的拉伸，扭曲，需要有好的拓扑结构\n>  在创建骨骼时，要符合15块骨骼为基准的骨骼结构\n>  对于蒙皮，可能要结合需要被应用的动画资源，或是对于目前已制作出的动画效果，对权重进行反复的调整\n>  Unity无法解析physique蒙皮，因此我们必须使用Skin进行网格的蒙皮\n\n## ImportSettings操作\n\nImportSettings影响的是对AnimationClip的导入，导入之后，曲线就只能手动编辑关键帧了，所以，影响到整体曲线形成方式的操作都在ImportSettings当中设置。\n\nLoop Pose：Enable to make animation loop seamlessly. （使动画首尾姿态尽量无缝衔接，避免出现突变。实质上就是动画末尾到开头的过渡效果。）\n\nBake Into Pose：将角色对应属性的变换植入到身体（Pose）的运动中，让根节点对应属性的运动不发生改变。勾选Bake Into Pose，将消除根节点对应的运动属性，在切片播放时，角色对应的旋转/位移，将不会被植入到Unity中。\n\n### ApplyRootMotion\n\n动画的运动包括根节点的运行（RootMotion）和各个骨骼节点相对于根节点的运动。其根节点（Root）默认为Animator所在的物体。\n\n动画导入后，如果不Bake，运动分为Root的运动和子节点骨骼的运动两部分。\n\n  * 在播放动画时，不ApplyRootMotion，则不会进行根节点的运动，也就是只看到人物各个骨骼在相对于根节点做动作，而人物整体不运动。例如对于奔跑的动作，如果人物的位移与旋转是由根节点的位移与旋转实现的，播放时，人的手和脚在摆动，而位置不变。\n\n  * 播放动画时，勾选了ApplyRootMotion，则会将动画资源中Root的运动数据应用到根节点上，根节点会进行相应的位移和旋转。而RootMotion执行的是相对于初始位置的运动，因此奔跑的动作循环播放会导致人物一直前进。\n\n如果Bake，则会将RootMotion运动的信息烘焙到各个骨骼点上 ，导入的动画就没有Root节点运动的信息，无论是否ApplyRootMotion，角色的根节点的transform都不会改变，而骨骼节点执行的是相对于根节点的运动，并且是原先根节点运动(前进转身等)运动与骨骼节点运动（摆手臂等）的叠加。\n\n总之RootMotion记录的是根节点相对于动画初始transform的运动。如果Bake，就将整体运动信息烘焙到骨骼上，根节点不动，动画循环播放，每次会从原位置开始运动。如果不Bake，不ApplyRootMotion，动画只有骨骼节点的运动， 没有整体的运动。如果ApplyRootMotion，就会将根节点的整体运动执行，每次开始播放动画，都相对于当前动画的位置运动。\n\n#### 自定义RootMotionNode\n\n在ImportSettings中可以设置RootMotionNode：\n\n![Alt text](assets/1615977607114.png)\n\n如果设置了RootMotionNode，则会进行Bake，以所选节点为Root，将运动信息烘焙到子节点上，运行时，依然看到根节点transform是不变的，但是角色会前进一段后回到原位置。\n\n#### 性能问题\n\n如果不进行Bake，并且ApplyRootMotion的话，每一帧都需要更新根节点的位置，并在此基础上确定各个骨骼的位置，会有一定的开销。\n如果ApplyRootMotion勾选，Unity每帧都会在ApplyOnAnimatorMove函数中调用ApplyBuiltinRootMotion。\n\n![Alt text](assets/1615977339562.png)\n\n如果不勾选，则不会调用：\n\n![Alt text](assets/1615977392724.png)\n\n### 动画剪辑\n\n通过Clips下方的加号来新建AnimationClip，在下方可以更改AnimationClip的名字，在Length条上可以对动画进行裁剪。\n\n![Alt text](assets/1615984365722.png)\n\n剪辑时，下方将会显示出曲线图。通过红色/黄色/绿色，来标记剪切出的剪辑中，角色的某种姿态属性是否能够构成循环。（绿色可以，红色不可以，黄色取中间值）。\n裁剪的结果是否能循环体现在Bake选项后的红色提示灯上，用于在Bake时参考：\n\n![Alt text](assets/1615984621432.png)\n\n由于Bake后Root是不动的，动画会循环播放，因此，绿色状态下才建议开发者进行Bake。如果是红色状态 ，Bake后动画的播放就会不连续。\n\n### 其它参数\n\nCycle Offset：应是一个0到1之间的数值，否则无效，可以设定循环时起始播放位置的偏移\n\nBase Upon：对应属性的改变要以什么为参照（通常保持默认即可）\n—original 引用FBX文件中原先的位置，方位坐标，并以此为参照，通常对Y轴启用，对Rotation启用可能导致人物初始朝向不是Z轴正方向，对XZ平面启用可能导致人物不在原点位置\n—Body Orientation 按身体的朝向变化为参照，通常对Rotation启用\n—Center Of Mass 按身体重心位置为参照，选定时，身体重心位置会被至于原点，通常不对Y轴启用，而对XY平面启用\n—feet 按脚底的Y轴高度为参照（Y轴高度的另一个参照）\n\nMirror：左右镜像翻转动画，可以节省动画师的工作量\n\n## Animator组件的属性\n\nController：状态机的配置资源文件，整合Clip资源，创建状态机状态（State），设置动画 **过渡** 与 **融合** 。\n\nAvatar：动画节点导引替身，与动画复用（尤其是人形动画复用）有关，通过配置和应用Avatar，可以实现不同FBX模型之间的动画复用\n\nUpdate Mode：状态机播放动画的时间模式。\n\n![Alt text](assets/1615987896583.png)\n\nNormal：使用游戏Upadte的更新模式\nAnimate Physics：使用物理周期的更新模式（使用Unity中的物理系统实现位移，角色需要与场景中的物体进行物理交互）\nUnscaled Time：不受TimeScale影响的更新模式（通常应用于GUI界面的动画）\n\nCulling Mode：剔除模式\n\nAlways Animate：无论物体是否被摄像机可见，总是计算所有节点的运动，完整的进行动画播放\nCull Update Transforms：当物体不被摄像机可见时，仅计算根节点的位移植入，保证物体位置上的正确\nCull Completely：当物体不被摄像机可见时，完全终止动画的运行\n\n## AnimationController\n\n### Sub-State Machine\n\n创建一个子动画组。创建的指向动画组的过渡，当过渡触发时，就会来到该动画组的Entry，并进入该动画组的初始状态。\n\n指向Exit的过渡 - 当触发时，就会返回上一层的Entry并进入上一层的初始状态。\n\n![Alt text](assets/1615988240440.png)\n\n### Blend Tree\n\n动画融合树\n\n### 动画过渡\n\n**Has Exit Time** ：勾选时上一个状态对于的动画片段必须被播放到末尾，才允许这个过渡被触发，不勾选可以在任意时刻进行过渡\n\n**Eixt Time** ：CurrentState所对应的动画片段，开始进行过渡融合的位置对起始位置的偏移（百分比）\n**Transition Duration(s)** ：过渡融合的区间长度（百分比或秒）\n**Transition Offset** ：过渡：NextState动画，进行过渡融合对应起始位置的偏移（百分比）\n\n**Fixed Duration** ：过渡区间的计算方式（决定Transition Duration的单位），不勾选按照对CurrentState动画的相对百分比长度计算，勾选按照恒定的秒时长计算\n\n**Interruption Source** ：打断来源，允许该过渡被来自CurrentState或NextState的其它过渡打断\n被CurrentState打断则发生了“跳转”，NextState的指向被改变（例如受击打断了攻击）\n被NextState打断则发生了“跃进”，动画迅速的完成了两个状态的过渡（例如从站立状态快速过渡到冲刺斩，奔跑状态被越过）\n\n**合理的运用打断，实现快节奏的状态切换，是制作动作游戏的基础**\n\nOrdered Interruption：针对CurrentState出发的过渡，是否只允许比当前过渡优先级高的过渡打断该过渡\n\n### State配置\n\nMotion：这个State所引用的动画片段\n\nSpeed：动画片段的播放速度（置为-1可倒放动画）\n\nMultiplier：Speed的一个倍率因子，需要勾选Parameter，可选定一个浮点动画参数来动态控制这个因子\n\nNormalized Time：片段播放位置，0到1之间浮点，需要一个被控制的浮点动画参数来作为输出映射，从而我们可以在脚本中获取这个片段的播放进度（Normallize Time * 片段帧长度，可以得到当前片段播放到第几帧）\n\nMirror：是否进行左右翻转，可以勾选要Parameter，可选定一个布尔动画参数来动态控制\n\nCycle Offset：偏移量（和之前Clip中的偏移相同），0到1之间的浮点值，可勾选Parameter选定一个浮点动画参数来动态控制\n\nFoot IK：脚部的IK反向力学修正，针对人物上坡，上楼梯时的踏空而行进行修正\n\nWrite Default：初始化属性，如果一个Clip对于角色某个节点的某个属性完全不涉及，那么播放该Clip时，对于不涉及的属性值，是要置为初始状态，还是置为其它Clip末尾时对该值的修改结果。勾选则置为0帧初状态，不勾选则应用之前播放的Clip对其修改的结果\n\nWrite Default主要是针对人物骨骼之外的一些节点，例如武器，跟随物，这些节点只在部分互动动作之中被用到，那些没有使用该节点的动作执行时，是要让节点处于初始状态，还是上一次互动动作末尾时的状态\n\n## Animator Override Controller\n\nAnimator Override Controller 也是一种Controller状态机配置资源文件，它可以继承一种指定的Animator Controller，并在此基础上进行修改，从而在复用Controller的同时，做出针对性的修改。\nOverride Controller与AnimationController作用相同，只是可以替换AnimationClip的取值。\n\n## 事件机制\n\nAnimationState面板上可以添加StateMachineBehaviour类Script，通过Override相关函数响应相关事件。\n\n![Alt text](assets/1615987356620.png)\n\n![Alt text](assets/1615987405918.png)\n\nAnimationClip编辑时，可在关键帧添加AnimationEvent。\n\n![Alt text](assets/1615987432960.png)\n\n关键帧触发事件时，调用AnimationClip所在物体上的脚本中的同名函数。\n\n![Alt text](assets/1615987484236.png)\n\n### Mono—>SMB的通信\n\n  1. 拖动赋值 —— 序列化的方法\n\n![Alt text](assets/1615989784924.png)\n\n  2. API\n\n```csharp\nclass Program\n{\n    static void Main(string[] args)\n    {\n        dynamic dyn = 1;\n        object obj = 1;\n        dyn = dyn + 3;\n        //obj = obj + 3; 报错\n\n        // Rest the mouse pointer over dyn and obj to see their\n        // types at compile time.\n        System.Console.WriteLine(dyn.GetType());\n        System.Console.WriteLine(obj.GetType());\n    }\n}\n\n```\n\n### SMB—>Mono的通信\n\n  1. 依然是序列化方法，同样需要用到两个Inspector窗口\n\n  2. 在Mono中获取到该SMB，之后在Mono的Awake/Start对SMB中的Mono挂点进行赋值（逆向设置）\n\n## Avatar相关\n\nAvatar能够复用的条件是，生成源Avatar的FBX模型中的骨骼层级结构及名称与当前FBX相同\n\n![Alt text](assets/1615989156276.png)\n\n复用方式：Avatar的存在主要是为了解决人物动画的复用问题，不同来源的FBX中，对于骨骼节点的层级结构，以及命名可能不尽相同，因此Unity以Avatar作为一个中介，不同的FBX都对Avatar中的标准人物骨骼结构去创建映射关系。在Animator状态机进行动画控制时，依照人物模型创建的Avatar，将人物动画片段对标准人物骨骼中的节点控制，映射到当前的人物模型当中，从而就实现了对不同来源FBX中，人物动画的复用。\n\n## 一些API\n\n```csharp\nclass Program\n{\n    static void Main(string[] args)\n    {\n        dynamic dyn = 1;\n        object obj = 1;\n        dyn = dyn + 3;\n        //obj = obj + 3; 报错\n\n        // Rest the mouse pointer over dyn and obj to see their\n        // types at compile time.\n        System.Console.WriteLine(dyn.GetType());\n        System.Console.WriteLine(obj.GetType());\n    }\n}\n\n```\n\n## 动画系统性能\n\n**Mesh** 面片数对Camera.Render的影响最大，而对其他Animator.Update、MeshSkinning.Update几乎没有影响。\n**骨骼数量** 增多时则主要影响Animator.Update，MeshSkinning.Update\n\n当我们打开多线程渲染 **Multithread Rendering** 后，会开启Render Thread。然后主线程Camera.Render的耗时则会大幅下降，并且之前开销越大，则下降幅度越明显。\n\n而打开 **Optimize Game Objects** 选项后，Animator.Update，MeshSkinning.Update的耗时则会大幅下降\n\n当开启 **Apply Root Motion** 后，主线程中Animator.Update函数开销会增加很多，主要增加开销的函数是ApplyBuiltinRootMotion。有没有办法优化这块呢，答案是肯定的。只要勾选上Optimize Game Objects，这个函数的大部分计算就会放到子线程Worker Thread中去运算了。所以当你要用到Apply Root Motion时，记得一定要开启Optimize Game Objects。\n\n推荐大家使用Optimal来进行动画压缩。\n\n### 多角色场景解决方案\n\n#### Bake Mesh\n\n利用SkinnedMeshRender.BakeMesh来对场景中同种模型角色进行烘焙，将蒙皮网格SkinnedMesh转换成普通Mesh。根据所要播放的动画及播放时间可以在网格中获取对应的网格数据从而进行渲染。\n使用Bake Mesh的优点是能大幅降低CPU的开销，但是同时也会增加运行时的内存占用，具体的内存占用跟Mesh的面片数和动画片段长度成正比，因此在使用此方案时要特别注意降低Mesh的面片数和动画片段。\n\n#### GPU Skinning\n\nSkinning过程转移到GPU中\n\n## Ref\n\n<https://www.jianshu.com/p/6fc0332357e8>\n<https://zhuanlan.zhihu.com/p/105029905>\n"
}
