[{"data":1,"prerenderedAt":1931},["ShallowReactive",2],{"page-Animation-1":3,"page-count-Animation":1930},[4,567,1011,1396,1704],{"id":5,"title":6,"body":7,"date":544,"description":13,"extension":545,"meta":546,"navigation":549,"path":561,"seo":562,"stem":563,"tags":564,"__hash__":566},"blogs\u002F_legacy\u002F2020\u002F2020-10-25-kine-driver-note.md","辅助骨骼系统KineDriver笔记",{"type":8,"value":9,"toc":514},"minimark",[10,14,24,28,32,35,38,41,44,47,50,53,56,60,63,66,70,73,83,86,95,102,105,108,111,114,120,123,126,129,147,150,153,156,159,170,173,176,179,182,186,189,192,195,198,201,204,208,211,214,220,223,231,234,237,240,245,249,252,255,258,261,264,267,270,273,278,281,284,293,296,300,315,318,321,324,333,336,339,344,347,368,371,374,377,382,385,394,397,402,405,411,414,417,429,434,437,440,443,446,451,456,459,463,466,471,474,479,482,487,490,496,499,505,508,511],[11,12,13],"p",{},"这个是Square Enix在2019年分享的角色动画相关的笔记。",[11,15,16,17],{},"原文：",[18,19,23],"a",{"href":20,"rel":21},"http:\u002F\u002Fwww.jp.square-enix.com\u002Ftech\u002Flibrary\u002Fpdf\u002FCEDEC2019_KineDriver.pdf",[22],"nofollow","www.jp.square-enix.com\u002Ftech\u002Flibrary\u002Fpdf\u002FCEDEC2019_KineDriver.pdf",[25,26,27],"h2",{"id":27},"系统概要",[29,30,31],"h3",{"id":31},"辅助骨骼系统简介",[11,33,34],{},"辅助骨骼系统主要用于提升蒙皮动画的效果，其目的是为了提高骨骼动画的表现，所以并不与实际存在的骨骼完全对应。",[11,36,37],{},"在设计上，由骨骼进行驱动。通过骨骼的运动驱动数值，其结果不仅可以用于蒙皮动画的表现，也可以用于Shader和材质等特效。",[11,39,40],{},"因此，辅助骨骼系统并不仅是一个工作于资源制作环境下的工具，而是一个在资源制作和实际运行环境中同时存在，并且能够保证在两个环境下的运行效果一致性的系统。",[11,42,43],{},"这么做的好处主要有两个，首先，可以降低动画资源的大小，同时，还可以方便在运行时进行动态的调整。",[11,45,46],{},"版本历史上看，一开始是使用softimage的，后面换到了maya上，到3.0版本已经支持使用图形化界面来拖节点的编辑形式了。",[11,48,49],{},"由于提供了中间文件，可以方便的在各种引擎环境下运行，也能导入到MotionBuilder中，但是辅助骨骼的制作还是使用的Maya。",[29,51,52],{"id":52},"功能和概念",[11,54,55],{},"系统内共有三种控制器(operator)，source、target和constraint。",[57,58,59],"h4",{"id":59},"源和目标控制器",[11,61,62],{},"源控制器可以从多个骨骼获取需要的状态并对其进行插值混合。",[11,64,65],{},"坐标空间上，默认使用父节点作为local space的坐标参考，同时也支持指定其他骨骼作为坐标参照。",[67,68,69],"h5",{"id":69},"旋转表现",[11,71,72],{},"旋转表现有两种方式",[74,75,76,80],"ol",{},[77,78,79],"li",{},"Bend&Roll，将旋转分解到水平方向和竖直方向，方便美术理解",[77,81,82],{},"Expmap，使用四元数的对数，主要用于程序自动生成逻辑",[11,84,85],{},"对于Bend&Roll，在欧拉角的处理上有一些问题。首先，欧拉角在计算上具有一些复杂度，而且同一个状态所对应的欧拉角并不唯一，例如(0,90,60)和(-30,90,30)是同一个姿势。同时，在运行时通常引擎内部都是采用四元数的，将其转换回欧拉角时便无法保证能够回到预期的那个欧拉角。",[11,87,88,89,94],{},"因此最终采用了",[18,90,93],{"href":91,"rel":92},"https:\u002F\u002Fzh.wikipedia.org\u002Fzh\u002F%E7%90%83%E6%A5%B5%E5%B9%B3%E9%9D%A2%E6%8A%95%E5%BD%B1",[22],"球极平面投影","的方法，来对旋转角度中的水平角度进行处理。处理方式上，将起始位置的朝向分解为vx，vy和vz。将到达目标旋转vx'所需要的角度分解为θh和θv。详细的公式可以看图：",[11,96,97],{},[98,99],"img",{"alt":100,"src":101},"旋转转换","\u002Fwp-content\u002Fuploads\u002F2020\u002F10\u002F%E5%9C%96%E7%89%87.png",[11,103,104],{},"Bend&Roll在实际使用时，水平旋转和竖直旋转的应用顺序可以根据不同的骨骼进行配置，方便在使用时进行直观的理解。",[11,106,107],{},"Expmap则没有顺序上的问题，程序内部直接计算结果并进行控制。",[67,109,110],{"id":110},"缩放表现",[11,112,113],{},"缩放同样采用对数空间进行内部控制，采用对数是为了获得更大的精度空间，如下图所示：",[11,115,116],{},[98,117],{"alt":118,"src":119},"对数空间的优势","\u002Fwp-content\u002Fuploads\u002F2020\u002F10\u002F%E5%9C%96%E7%89%87-1.png",[11,121,122],{},"不过ppt里面说没有实装。",[67,124,125],{"id":125},"节点图支持",[11,127,128],{},"可以使用图形化的方式对控制器进行操作，主要提供了以下的节点：",[130,131,132,135,138,141,144],"ul",{},[77,133,134],{},"EZParamLinkLinear(线性插值)",[77,136,137],{},"EZParamLink(简单贝塞尔插值)",[77,139,140],{},"LinkWith(DrivenKey位置链接)",[77,142,143],{},"RBFInterp(支持多个输入输出的链接)",[77,145,146],{},"Expr(自定义表达式)",[11,148,149],{},"节点名和功能微妙的没有对上，但是原文就是这样的。",[11,151,152],{},"DrivenKey，查了下是maya的功能，就不详细的去看了。RBF后面有说明。",[57,154,155],{"id":155},"约束控制器",[11,157,158],{},"与节点图不同的，基于约束的控制器。",[130,160,161,164,167],{},[77,162,163],{},"Position：位置约束，可以基于多个源进行计算",[77,165,166],{},"Orientation：朝向约束，可以基于多个源进行计算",[77,168,169],{},"Dirction：让旋转指向目标，3点模式可以额外控制水平旋转",[67,171,172],{"id":172},"紧贴表面",[11,174,175],{},"约束控制器也提供紧贴表面的功能，根据Position和Orientation约束以及目标表面的骨骼权重进行计算。",[11,177,178],{},"在制作Bonamik的引导骨骼的时候经常用到。",[25,180,181],{"id":181},"工作流",[29,183,185],{"id":184},"maya中的资源制作","Maya中的资源制作",[11,187,188],{},"似乎是使用了maya的插件功能，节点图部分使用了C++的实现，导出和界面之类的功能使用了Python。",[11,190,191],{},"节点在显示时使用的是惯用的单位，在连接节点时会自动插入UnitConversion统一进行单位换算。",[29,193,194],{"id":194},"中间文件",[11,196,197],{},"中间文件采用xml的形式进行输出。",[11,199,200],{},"文件中保存了各种控制器的的节点的输出，以及节点之间的连接。",[11,202,203],{},"在进行文件输出时，可以指定缩放倍数，方便在使用不同单位的引擎中进行使用。",[29,205,207],{"id":206},"ue4插件","UE4插件",[11,209,210],{},"为了方便在项目中复用，进行了插件化。",[11,212,213],{},"模块构成，直接上图：",[11,215,216],{},[98,217],{"alt":218,"src":219},"image","\u002Fwp-content\u002Fuploads\u002F2020\u002F10\u002Fimage_thumb.png",[11,221,222],{},"使用上提供了两种方式",[74,224,225,228],{},[77,226,227],{},"动画节点：使用标准的动画控制流程，无法预览KineDriver的功能",[77,229,230],{},"Component版：作为SkeletonMesh的子组件，在tick中对骨骼进行更新，可以预览效果",[11,232,233],{},"提供了动画通知用于在动画的分段中关闭KineDriver。",[11,235,236],{},"对于与Bonamik的兼容关系，分开使用的时候会使用AddTickPrequist来决定调用顺序。另外似乎还有将KineDriver和Bonamik统合在一起的插件。",[11,238,239],{},"数据流程直接上图：",[11,241,242],{},[98,243],{"alt":218,"src":244},"\u002Fwp-content\u002Fuploads\u002F2020\u002F10\u002Fimage_thumb-1.png",[57,246,248],{"id":247},"assetuserdata","AssetUserData",[11,250,251],{},"使用了AssetUserData进行数据的存储，方便在骨骼数据上直接添加和修改数据，通过引用指向具体的导入资源。",[11,253,254],{},"将数据放在骨骼上的好处是可以不必调整componnet的属性就直接对辅助骨骼的资源进行修改。",[57,256,257],{"id":257},"缩放传递",[11,259,260],{},"在Maya中，对骨骼的缩放不会传递到子骨骼。",[11,262,263],{},"而在UE4中则会进行缩放的传递，为了保持效果的一致性，在UE4中作了处理，对于TargetScaleOp的骨骼的子骨骼进行缩放的重新设置。",[25,265,266],{"id":266},"功能实装",[29,268,269],{"id":269},"表达式",[11,271,272],{},"提供基本的表达式支持，语法尽量的精简化了，不会使用for这些循环的语句。",[11,274,275],{},[98,276],{"alt":218,"src":277},"\u002Fwp-content\u002Fuploads\u002F2020\u002F10\u002Fimage_thumb-2.png",[11,279,280],{},"主要使用一些内置的函数，同时添加对三维向量和四元数的支持。运算上支持了基本的四则运算和括号。",[11,282,283],{},"对于输入的参数，则转换到x1,x2,...,xn的形式进行记录。",[11,285,286,287,292],{},"在maya内部使用时，会将转换后的表达式使用[",[18,288,291],{"href":289,"rel":290},"https:\u002F\u002Fzh.wikipedia.org\u002Fwiki\u002F%E8%B0%83%E5%BA%A6%E5%9C%BA%E7%AE%97%E6%B3%95",[22],"调度场算法","]进行转换和计算。如果要存储到中间文件的话，会将二进制代码转换为汇编语句的格式。各个游戏引擎加载时则重新将汇编语句转换为二进制代码。",[11,294,295],{},"之所以会用到表达式是因为有很多的分支需求，同时有的用几行表达式就能做好的事情用节点就要拖半天，所以需求也比较大。即便初期有预先设置很多功能节点，但是最后还是使用表达式具有更高的灵活性。",[29,297,299],{"id":298},"rbf插值","RBF插值",[11,301,302,303,308,309,314],{},"RBF总之就是一种拟合的方式，RBF本身可以参考[",[18,304,307],{"href":305,"rel":306},"https:\u002F\u002Fzh.wikipedia.org\u002Fwiki\u002F%E5%BE%84%E5%90%91%E5%9F%BA%E5%87%BD%E6%95%B0",[22],"径向基函数","]，RBF插值可以参考[",[18,310,313],{"href":311,"rel":312},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FRadial_basis_function_interpolation",[22],"Radial basis function interpolation","]。",[11,316,317],{},"这边有很大的篇幅中介绍这个算法的实现和原理，其实主要的目的是让插值变得更加平滑。",[29,319,320],{"id":320},"辅助骨骼自动生成",[11,322,323],{},"通过在特定姿态时美术已经调好的mesh状态，与完全没有调节的默认骨骼在这个状态的表现之间对比，自动的生成辅助骨骼。",[11,325,326,327,332],{},"使用了[",[18,328,331],{"href":329,"rel":330},"http:\u002F\u002Fgraphics.cs.uh.edu\u002Fwp-content\u002Fpapers\u002F2012\u002F2012_SA_SSDR_preprint.pdf",[22],"Smooth Skinning Decompostion with Rigid Bones","] ，简称SSDR。",[11,334,335],{},"主要的功能就是，对具有J个顶点的模型，使用N个形变示例动画，尝试生成D个骨骼来做一个蒙皮的操作。",[11,337,338],{},"由于很难同时对骨骼的位置和蒙皮的权重同时进行最优化处理，所以会分别进行十次来试图逼近最优解。",[11,340,341],{},[98,342],{"alt":218,"src":343},"\u002Fwp-content\u002Fuploads\u002F2020\u002F10\u002Fimage_thumb-3.png",[11,345,346],{},"进行简单的列出",[348,349,350,353,356,359,362,365],"blockquote",{},[11,351,352],{},"a. 主骨骼没有调整的情况下，使用SSDR对权重进行最优化处理",[11,354,355],{},"b. 添加指定数量的辅助骨骼",[11,357,358],{},"c1. 使用SSDR进行权重最优化处理",[11,360,361],{},"c2. 暂时指定辅助骨骼的父骨骼",[11,363,364],{},"c3. 使用SSDR对辅助骨骼的位置进行最优化处理",[11,366,367],{},"d. 决定辅助骨骼的父骨骼，以及自动控制用的RBF插值设定。",[11,369,370],{},"其中c的步骤就是要执行10次的步骤。",[57,372,373],{"id":373},"添加指定数量的辅助骨骼",[11,375,376],{},"这个过程只会执行一次，但是其操作内部需要进行多次迭代才能完成。",[11,378,379],{},[98,380],{"alt":218,"src":381},"\u002Fwp-content\u002Fuploads\u002F2020\u002F10\u002Fimage_thumb-4.png",[57,383,384],{"id":384},"蒙皮权重最优化",[11,386,387,388,393],{},"对一开始的公式中的[",[18,389,392],{"href":390,"rel":391},"https:\u002F\u002Fzh.wikipedia.org\u002Fwiki\u002F%E4%BA%8C%E6%AC%A1%E8%A7%84%E5%88%92",[22],"二次规划","]中的w进行单独求解。",[11,395,396],{},"在整个过程中会多次使用到，虽然角标写的是SSDR。但是额外参考了Computer Graphics Gems JP 2015的向井老师的分享。在辅助骨骼的生成中，为了使得最优化的求解过程更加安定，进行了以下的优化：",[74,398,399],{},[77,400,401],{},"移除参考动画中的重复顶点",[11,403,404],{},"在对角色的姿态进行学习时，从单独的顶点来看会有完全没有移动的帧存在",[74,406,408],{"start":407},2,[77,409,410],{},"对骨骼进行合并",[11,412,413],{},"会出现对于某一个顶点而样，有多个骨骼的给出的变换结果相同的情况。此时对这些骨骼进行合并作为一个骨骼来计算，获得的最优化权重结果则按照原本的权重比例分散回去。",[57,415,416],{"id":416},"辅助骨骼的位置最优化",[11,418,419,420,424,425,428],{},"步骤c3，参考的还是上面的CGG JP2015的分享，同时参考了",[421,422,423],"span",{},"Horn 1987","以及",[421,426,427],{},"Mukai 2018","的缩放传递控制。",[11,430,431],{},[98,432],{"alt":218,"src":433},"\u002Fwp-content\u002Fuploads\u002F2020\u002F10\u002Fimage_thumb-5.png",[11,435,436],{},"以点群为单位进行适配，来获得最佳的位置、旋转和缩放。",[11,438,439],{},"这里面原文是Transform，所以包含了Translation，Rotation和Scale。只是一时找不到合适的中文替代所以翻成了位置。",[57,441,442],{"id":442},"暂时指定辅助骨骼的父骨骼",[11,444,445],{},"步骤c2，这个步骤只有在使用了scale的计算时才会需要，在进行辅助骨骼计算时，为了计算的稳定性，是在本地旋转为0的情况下进行的。此时应用缩放会产生较大的误差，因此要暂时寻找到父骨骼并转换到骨骼空间之后再进行缩放处理，这个父骨骼可以随便找一个，主要的目的是为了将计算转换到骨骼空间去。",[11,447,448],{},[98,449],{"alt":218,"src":450},"\u002Fwp-content\u002Fuploads\u002F2020\u002F10\u002Fimage_thumb-6.png",[11,452,453],{},[98,454],{"alt":218,"src":455},"\u002Fwp-content\u002Fuploads\u002F2020\u002F10\u002Fimage_thumb-7.png",[11,457,458],{},"说实话还没有仔细看过计算过程，所以只是把自己的猜测描述了下。",[57,460,462],{"id":461},"决定父骨骼以及rbf配置","决定父骨骼以及RBF配置",[11,464,465],{},"最终的步骤d，计算出辅助骨骼以及其被主骨骼驱动的形式。",[11,467,468],{},[98,469],{"alt":218,"src":470},"\u002Fwp-content\u002Fuploads\u002F2020\u002F10\u002Fimage_thumb-8.png",[11,472,473],{},"生成辅助骨骼的自动控制总共有四个步骤：",[74,475,476],{},[77,477,478],{},"从蒙皮权重来寻找候补驱动者",[11,480,481],{},"从本辅助骨骼所驱动的顶点来寻找原本驱动这些顶点的主骨骼",[74,483,484],{"start":407},[77,485,486],{},"从候补驱动中寻找父骨骼",[11,488,489],{},"在所有的候补中寻找误差最小的",[74,491,493],{"start":492},3,[77,494,495],{},"从剩余的候补中选择RBF用骨骼",[11,497,498],{},"选择能够尽量覆盖RBF插值的1~2个骨骼",[74,500,502],{"start":501},4,[77,503,504],{},"RBF关键点修正",[11,506,507],{},"从没有关键点的情况下误差最大的地方开始插入关键点",[25,509,510],{"id":510},"总结",[11,512,513],{},"本来是从FF7的动画分享过来的，整个系统的原理其实还是挺清晰的。只是后面自动生成的部分使用了很复杂的计算逻辑，由于没有太过深入的打算，所以详细的公式以及额外引用的论文就没有去参考了，所以可能会有意思不明确的地方。",{"title":515,"searchDepth":407,"depth":492,"links":516},"",[517,524,532,543],{"id":27,"depth":407,"text":27,"children":518},[519,520],{"id":31,"depth":492,"text":31},{"id":52,"depth":492,"text":52,"children":521},[522,523],{"id":59,"depth":501,"text":59},{"id":155,"depth":501,"text":155},{"id":181,"depth":407,"text":181,"children":525},[526,527,528],{"id":184,"depth":492,"text":185},{"id":194,"depth":492,"text":194},{"id":206,"depth":492,"text":207,"children":529},[530,531],{"id":247,"depth":501,"text":248},{"id":257,"depth":501,"text":257},{"id":266,"depth":407,"text":266,"children":533},[534,535,536],{"id":269,"depth":492,"text":269},{"id":298,"depth":492,"text":299},{"id":320,"depth":492,"text":320,"children":537},[538,539,540,541,542],{"id":373,"depth":501,"text":373},{"id":384,"depth":501,"text":384},{"id":416,"depth":501,"text":416},{"id":442,"depth":501,"text":442},{"id":461,"depth":501,"text":462},{"id":510,"depth":407,"text":510},"2020-10-25","md",{"layout":547,"status":548,"published":549,"author":550,"author_login":552,"author_email":553,"wordpress_id":554,"wordpress_url":555,"date_gmt":556,"excerpt":557},"post","publish",true,{"display_name":551,"login":552,"email":553,"url":515},"风铃","flinkor","flinkor@foxmail.com",3087,"\u002F?p=3087","2020-10-25 13:24:15 +0000",{"type":8,"value":558},[559],[11,560,13],{},"\u002F2020-10-25-kine-driver-note",{"title":6,"description":13},"_legacy\u002F2020\u002F2020-10-25-kine-driver-note",[565],"Animation","TfXlUuRjzV9y-L1RkRFoOxZUtX1_A8Nk1XSHmiIagGE",{"id":568,"title":569,"body":570,"date":993,"description":574,"extension":545,"meta":994,"navigation":549,"path":1006,"seo":1007,"stem":1008,"tags":1009,"__hash__":1010},"blogs\u002F_legacy\u002F2020\u002F2020-09-17-note-cedec2020-final-fantasy-vii-remake-animation.md","FF7重置版动画技术笔记",{"type":8,"value":571,"toc":956},[572,575,582,585,588,591,597,600,603,606,610,613,616,619,625,629,632,636,639,643,651,654,663,672,676,679,682,685,689,692,695,698,701,705,708,711,715,718,721,725,728,731,735,738,741,747,750,753,756,767,770,776,779,783,786,790,793,796,799,802,805,808,811,815,823,827,835,839,842,846,849,862,866,869,872,875,878,881,885,888,891,894,897,901,904,907,910,914,917,920,923,926,929,932,938,945,948,950,953],[11,573,574],{},"CEDEC2020上的FF7的技术分享的笔记，不过我没赶上直播，事后看的PPT。",[11,576,577,578],{},"CEDEC页面：",[18,579,580],{"href":580,"rel":581},"https:\u002F\u002Fcedec.cesa.or.jp\u002F2020\u002Fsession\u002Fdetail\u002Fs5e58c8811bc98",[22],[11,583,584],{},"FF7是UE4做的，所以可以参考的部分就会多一些。",[25,586,587],{"id":587},"动画结构",[11,589,590],{},"首先是整个角色动画的结构的概览，如果只是想要粗略的了解的话，看这张图就够了：",[11,592,593],{},[98,594],{"alt":595,"src":596},"animation-struct","\u002Fwp-content\u002Fuploads\u002F2020\u002F09\u002Fimage-300x121.png",[11,598,599],{},"左边上边两个，首先是游戏场景动画，然后到过场动画的动画。这两个是串行的，由于没有玩过FF7R，猜测可能过场动画是以游戏场景为基础直接播放的，而不是作出固定的Sequence动画。",[11,601,602],{},"左边下边的两个，是LipSync到过场动画的Facial动画，也就是嘴唇的动作叠加到过场动画的表情动画上。",[11,604,605],{},"其他的都和中文的表意差不多，下面会有列出，就不赘述了。",[25,607,609],{"id":608},"primary-animation","Primary Animation",[11,611,612],{},"主动画部分根据当前角色的状态完成主要的动作更新，例如当前的行走、攻击等动作的播放应该都在这边。",[29,614,615],{"id":615},"游戏场景动画",[11,617,618],{},"上面那张图左上角的Filed Body(フィールドボディ)，就只是简单的列出了下结构",[11,620,621],{},[98,622],{"alt":623,"src":624},"field-animation","\u002Fwp-content\u002Fuploads\u002F2020\u002F09\u002Fimage-1-300x140.png",[57,626,628],{"id":627},"locomotion","Locomotion",[11,630,631],{},"Locomotion上是针对所有角色的基础移动动画逻辑，这个应该和大多数游戏的实现是一样的，根据StateMachine以及其他State的差分来应用不同的动画叠加。通过切换动作的配置可以实现动态的切换，这里的MotionPack不是很确定具体指的是什么。从实现上看，动画蓝图中引入的motion是可以在C++层面动态指定的。但FF7R具体在什么时间切换这些并没有具体说明，不过这个根据游戏逻辑不同会有不同，写出来其实也没什么太大的参考意义。",[57,633,635],{"id":634},"action","Action",[11,637,638],{},"角色固有的动作动画。根据运行时游戏逻辑中玩家的输入进行动态的切换，通常的攻击动画应该都是在这里进入动画逻辑的。动作根据类型定义，可以根据不同的角色进行任意的状态管理。对于同一层的Action，如果有新的玩家输入进来的话，会进行中断和替换处理。",[57,640,642],{"id":641},"resident","Resident",[11,644,645,646,650],{},"一些装饰性物品的动画，比如尾巴这些与Locomotion的状态管理无关的东西的动画处理。由于用的是",[647,648,649],"em",{},"常驻","这样的描述，不是很确定头发和衣服是否在其中。尾巴应当算是装饰物，可能我对词语的理解有偏差，话说有角色有尾巴的吗？没玩过原作不是很确定。总之实际上就是那些与主动画循环关系不大的部分放在主动画更新完成后进行一次更新。",[29,652,653],{"id":653},"惯性补间",[11,655,656,657,662],{},"在混合的时候不考虑源动画，只朝着目标动画进行计算的方式。在减少运算量的同时提高动画的流畅感，但是会增加一些内存消耗。PPT里面列了很多计算的公式和内部的设计的原理，由于在UE4.24已经作为引擎功能提供了，直接在动画蓝图中使用",[18,658,661],{"href":659,"rel":660},"https:\u002F\u002Fdocs.unrealengine.com\u002Fzh-CN\u002FEngine\u002FAnimation\u002FNodeReference\u002FBlend\u002Findex.html",[22],"Inertialization","动画混合方式就可以了。",[11,664,665,666,671],{},"想要详细的了解技术方面可以参考之前的GDC分享：",[18,667,670],{"href":668,"rel":669},"https:\u002F\u002Fwww.gdcvault.com\u002Fplay\u002F1025331\u002FInertialization-High-Performance-Animation-Transitions",[22],"Inertialization-High Performance Animation Transitions","，当然也可以去看UE4的源码实现方式。",[29,673,675],{"id":674},"pose-matching","Pose Matching",[11,677,678],{},"在目标动画有好几个候补的时候，通过对这几个动画进行比较来决定使用哪一个动画。例如，从行走到停止的状态，会事先设定一些候补的动画，然后根据当时状态选择一个最合适的。",[11,680,681],{},"候补的动画列表可以按照角色进行不同的配置，同时也可以使用动画通知对候补列表进行追加和限制。",[11,683,684],{},"进行动画比较时并不是使用全体的骨骼进行评估，而是使用事先设定的骨骼进行比较。例如，二足行走的时候使用下半身的基础骨骼进行比较。",[25,686,688],{"id":687},"secondary-animation","Secondary Animation",[11,690,691],{},"次要动画在主要动作确立之后对动作进行微调，通常的足IK、手部IK都在这里。",[29,693,694],{"id":694},"输入补正",[11,696,697],{},"根据来自玩家或者AI的输入对骨骼进行动态的旋转补正，通过IK Control Rig进行配置所以可以在角色间公用，同时可以在编辑器中进行动态的预览。这个记得之前ALS里面也有类似的实现，可以给用户输入一个细节上的反馈，例如在向前加速的过程中有一个向前倾的动作。",[11,699,700],{},"输入补正的配置资源保存在IK Control Rig中，运行时直接进行叠加。",[29,702,704],{"id":703},"look-at","Look At",[11,706,707],{},"LookAt的处理只使用惯性补间和线性补间，可以针对每个骨骼进行其重量和角速度的设定。使用惯性补间时，对其到达时间进行一个随机的基础数值叠加。在角度的限制上区分了Pitch和Yaw。在进行姿态维持时，可以将骨骼的目标按照Mesh的空间进行指定。",[11,709,710],{},"LookAt在操作上可以在具体的动作中通过动画通知暂时的关掉。",[29,712,714],{"id":713},"aim","Aim",[11,716,717],{},"Aim的处理只使用EaseOut和线性补间，不使用惯性补间的原因是目标在不断的进行移动时惯性补间的效果很差。通过AimGroup来针对每个骨骼进行重量和角度设定，并在动画蓝图通知中对不同的AimGroup进行选择。",[11,719,720],{},"Aim的设定主要在AimGroup中，动画只能指定不使用Aim，运行时也不会调整这些参数。",[29,722,724],{"id":723},"hand-ik","Hand IK",[11,726,727],{},"使用FABRIK算法，IK的目标分为两种：指定世界坐标的固定目标和使用特效等的相对位置的锁定目标。使用锁定目标的IK时，由于使用的是补间之前的位置，可以充当LookAt和FootIK的反动作。",[11,729,730],{},"与Aim相同，运行时只能使用设定好的HandGroup，具体的配置是在资源中固化的。",[29,732,734],{"id":733},"footik-hip-control","FootIK & Hip Control",[11,736,737],{},"与其他游戏一样检出地面的凹凸来调整脚的位置，同时根据脚的目标位置(FootLock)对腰的骨骼施加一个动态的偏移。战斗中防御动作时，对腰部施加了一个额外的向下10cm的偏移来表现重心的下落。",[11,739,740],{},"为了避免滑步移动的现象，会对当前脚的最低点到地面的距离Base Height进行维护。",[11,742,743],{},[98,744],{"alt":745,"src":746},"foot-ik-base-hegith","\u002Fwp-content\u002Fuploads\u002F2020\u002F09\u002Fimage-2-150x150.png",[11,748,749],{},"在站立或行走时，会根据脚接触地面的最低的位置来调整腰部的下落。同时根据地面的倾斜度来调整root骨骼的旋转以反应腰部的骨骼位置补正。",[29,751,752],{"id":752},"平衡控制",[11,754,755],{},"由于Foot Ik与Hip Control导致角色的中心出现偏移时，通过倾斜角度对骨骼的旋转进行调整。调整的内容包括：",[130,757,758,761,764],{},[77,759,760],{},"根据Pitch计算补正值",[77,762,763],{},"根据Pitch的绝对值进行补正",[77,765,766],{},"根据Roll进行补正",[11,768,769],{},"这个中心偏移，原文描述的是类似人物的中轴线的感觉。当人站在斜坡上时，为了保持平衡，其站立方向应该还是向上的。如下图：",[11,771,772],{},[98,773],{"alt":774,"src":775},"ballance-control","\u002Fwp-content\u002Fuploads\u002F2020\u002F09\u002Fimage-3-150x150.png",[11,777,778],{},"模拟的是人在斜坡上的一种后倾的维持平衡的动作。",[29,780,782],{"id":781},"control-rig的必要性","Control Rig的必要性",[11,784,785],{},"Control Rig可以方便对动画蓝图中的补正进行运行时效果进行观察和调整，有时这种运行时的效果调试比设定专门的预览环境更加能够有效的达到目的。尤其是根据背景物体和周围角色而表现不同的地方，在游戏环境中直接测试能够更好的对效果进行控制和调整。",[29,787,789],{"id":788},"bodydriver","BodyDriver",[11,791,792],{},"是内部研发的一种物理动画特效。用于击倒动画中，与通常的RagDoll不同，会有角色按住受击部位的同时后退的演出。",[11,794,795],{},"目测，应该就是在击倒动画时有一部分骨骼是开启了物理的，然后另一部分叠加了按住受击部分等的动画控制。通过这样可以为击倒动画添加不同的表现，提升演出效果。",[11,797,798],{},"一般的RagDoll直接打开的话总是会有很大的概率出现非常鬼畜的效果，所以FF7R的对应方式值得参考一下。",[29,800,801],{"id":801},"物理拘束补正",[11,803,804],{},"通过Position base dynamice添加基于物理拘束的补正处理。通过将约束条件进行Preset化并保存到Mesh的用户数据中。",[11,806,807],{},"通过物理拘束补正，可以表现鱼在沿着Spline移动时身体的扭动。对于与部分的角色，会将物理拘束补正与受击反馈结合起来，表现出更好的受击效果。由于是工作在Mesh空间的，成本较低，对于一些简单的背景物体也可以使用。",[11,809,810],{},"PBD本身使用物体的速度计算出位置，然后将所有的约束叠加到物体上得到新的位置，根据这个位置重新推断出速度来。可以在运行时调整物理的开关以及速度和重力等属性。",[29,812,814],{"id":813},"kinedriver","KineDriver",[11,816,817,818,822],{},"辅助骨骼：",[18,819,820],{"href":820,"rel":821},"https:\u002F\u002Fcedil.cesa.or.jp\u002Fcedil_sessions\u002Fview\u002F2007",[22],"，这个还没仔细看过，大体上是由实际的运动骨骼去驱动一个虚拟的骨骼，然后这个虚拟的骨骼可以决定Mesh的显示、特效等其他的参数。看演示效果，应该主要是用于实现一些无法单纯用骨架来实现的模型形变。",[29,824,826],{"id":825},"bonamik","Bonamik",[11,828,829,830,834],{},"参考资料：",[18,831,832],{"href":832,"rel":833},"https:\u002F\u002Fcedil.cesa.or.jp\u002Fcedil_sessions\u002Fview\u002F1583",[22],"。这个挺复杂的，简单的看了下，似乎是基于Position Based Dynamic的原理来基于骨骼进行一些物理模拟的辅助，主要用于防止衣服等物体穿模。",[25,836,838],{"id":837},"facial-animation","Facial Animation",[11,840,841],{},"表情动画能够让角色的表现更加自然，FF7R制定了一套程序化生成的表情动画流程。",[29,843,845],{"id":844},"saccade","Saccade",[11,847,848],{},"眼球運動，人的眼球在稳定凝视点和转移凝视点的时候的一种非自主反射运动……总之在FF7中专注于两种眼球运动的模拟，一种是在视角移动时的眼球运动，频率在12.5～17.5Hz，单次移动的角度是有限制的。另一种是注视的时候的微小眼动，频率和幅度更小的线性运动。",[11,850,851,852,424,856,861],{},"想要详细了解的可以参考维基百科的描述，由于是专业外，很多术语并不是很明确的了解，就不去强行解释了。参考链接：",[18,853,845],{"href":854,"rel":855},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSaccade",[22],[18,857,860],{"href":858,"rel":859},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FMicrosaccade",[22],"Microsaccade","。",[57,863,865],{"id":864},"saccade眼睑联动","Saccade眼睑联动",[11,867,868],{},"眼球运动的话会带动眼睑的运动，实际过程应该是相反的？我不是很了解生物学也就不去纠结了。",[11,870,871],{},"添加这个联动主要是为了让Saccade的运动变得更加明显，将Yaw和Pitch作为输入对眼皮的上下左右运动进行Blend。",[57,873,874],{"id":874},"自动生成",[11,876,877],{},"Saccade可以使用身体和脸的朝向自动生成的，使用jenkins对所有的角色动画进行曲线的烘培。",[11,879,880],{},"自动生成的流程只在动画不被LookAt控制的时候使用，通常用于攻击动画等时机。原理上面有提到，在视角目标变动的时候会有额外的眼动逻辑。",[29,882,884],{"id":883},"gaze-diversion","Gaze diversion",[11,886,887],{},"人在注视的时候会无意识的移开视线的现象，尤其在对话中的非语言交流更加能体现，因为凝视会被视为敌对表现。由于详细的对条件进行设定在实现上会有很多麻烦，实际上只是添加了在表现过程中随机的移开视线。",[29,889,890],{"id":890},"眨眼",[11,892,893],{},"眨眼以2～10秒的间隔周期性的随机发生，当视角大规模移动时的反射性眨眼则在LookAt的对象移动位置很大的时候发生。",[11,895,896],{},"眨眼没有很多动画，在闭眼动作的基础上进行blend来实现。单次眨眼并不一定完全闭上眼睛，而是在0.5～1.0之间进行随机。",[29,898,900],{"id":899},"happysadface","HappySadFace",[11,902,903],{},"是一套LipSync系统，通过语音和文本生成统一的格式，可以在Maya和UE4中进行嘴唇动画的控制。可以处理日语、英语、法语和德语。",[11,905,906],{},"从语音中抽出音素，使用音素对形变动画生成时间轴变化。针对每种语言的音素到形变采用的是不同的映射方式。同时，针对语音的情感状态，也会采用不同的形变预设。也就是说，根据下面的情感推定的结果，会针对不同的情感状态采用不同的嘴唇动画。",[11,908,909],{},"这个系统的一个问题是在流程上容易出错，如果文本有误或者声优进行了即兴演出的话，会导致生成的精读下降。同时，虽然在没有语音时产生嘴唇动画很容易排查，但是如果出现嘴形对不上的问题很难逐一进行目视确认。",[29,911,913],{"id":912},"voiceattack","VoiceAttack",[11,915,916],{},"通过对话的音量对眉毛进行控制，动画上只是通过音量值传入然后对眉毛向上的动画进行blend。",[11,918,919],{},"同时也会通过音量来让上体和头部有一个额外的摇动动作，这个动作是配在Ik control rig中的，在运行时会随机的决定一个预设来使用。",[29,921,922],{"id":922},"表情生成",[11,924,925],{},"使用ST Emotion通过语音来推定情感，通过情感的指数对各个表情动画进行混合。推定的情感指数是一种时间线数据，并不是针对单句语音，而是会在一个语音中有表情的变化。",[11,927,928],{},"情感推定的精读在70%左右，但是单单只是给表情添加了变化就能带来很大的表现提升。",[11,930,931],{},"情绪指数参考Russel的情感圆环模型针对所有的角色进行设置。根据情绪指数的不同其在情感圆环中的采样位置就会不同，为了避免线性插值导致的生硬变化，使用自定义的曲线进行插值。",[11,933,934],{},[98,935],{"alt":936,"src":937},"emotion-circle","\u002Fwp-content\u002Fuploads\u002F2020\u002F09\u002FFF7-circle-150x150.png",[11,939,940,941,861],{},"Russel情感圆环应该是这篇：",[18,942,943],{"href":943,"rel":944},"https:\u002F\u002Fpsycnet.apa.org\u002Frecord\u002F1981-25062-001",[22],[11,946,947],{},"ST Emotion可以实时的对情感进行检出，对五种情感每一种检出到10个精度上。对应的情感为：喜悦、愤怒、悲伤、平常和兴奋。",[25,949,510],{"id":510},[11,951,952],{},"FF7R的整体角色动画流程的处理有非常多的值得参考的部分，虽然一些技术细节并没有公布，但是并没有什么影响。因为根据项目需求的不同其实很多地方也会不一样，即便拿到源代码后面能用的部分也不多。",[11,954,955],{},"ST Emotion是商业项目，由于官方网站没有标价所以不是很确定使用成本，不过情感推定作为人工智能领域的一个广泛研究的主题，应该也能找到好的替代品，如果对开发周期特别敏感的话也可以尝试购买使用。",{"title":515,"searchDepth":407,"depth":492,"links":957},[958,959,968,981,992],{"id":587,"depth":407,"text":587},{"id":608,"depth":407,"text":609,"children":960},[961,966,967],{"id":615,"depth":492,"text":615,"children":962},[963,964,965],{"id":627,"depth":501,"text":628},{"id":634,"depth":501,"text":635},{"id":641,"depth":501,"text":642},{"id":653,"depth":492,"text":653},{"id":674,"depth":492,"text":675},{"id":687,"depth":407,"text":688,"children":969},[970,971,972,973,974,975,976,977,978,979,980],{"id":694,"depth":492,"text":694},{"id":703,"depth":492,"text":704},{"id":713,"depth":492,"text":714},{"id":723,"depth":492,"text":724},{"id":733,"depth":492,"text":734},{"id":752,"depth":492,"text":752},{"id":781,"depth":492,"text":782},{"id":788,"depth":492,"text":789},{"id":801,"depth":492,"text":801},{"id":813,"depth":492,"text":814},{"id":825,"depth":492,"text":826},{"id":837,"depth":407,"text":838,"children":982},[983,987,988,989,990,991],{"id":844,"depth":492,"text":845,"children":984},[985,986],{"id":864,"depth":501,"text":865},{"id":874,"depth":501,"text":874},{"id":883,"depth":492,"text":884},{"id":890,"depth":492,"text":890},{"id":899,"depth":492,"text":900},{"id":912,"depth":492,"text":913},{"id":922,"depth":492,"text":922},{"id":510,"depth":407,"text":510},"2020-09-17",{"layout":547,"status":548,"published":549,"author":995,"author_login":996,"author_email":997,"author_url":998,"wordpress_id":999,"wordpress_url":1000,"date_gmt":1001,"excerpt":1002},{"display_name":996,"login":996,"email":997,"url":998},"chaoshikari","chaoshikari@gmail.com","\u002F",2939,"\u002F?p=2939","2020-09-17 15:05:58 +0000",{"type":8,"value":1003},[1004],[11,1005,574],{},"\u002F2020-09-17-note-cedec2020-final-fantasy-vii-remake-animation",{"title":569,"description":574},"_legacy\u002F2020\u002F2020-09-17-note-cedec2020-final-fantasy-vii-remake-animation",[565],"Q3LKOb2a2Rno6CG5WMb56TEjju4Tp3M8biDAcy2nBEo",{"id":1012,"title":1013,"body":1014,"date":1380,"description":1018,"extension":545,"meta":1381,"navigation":549,"path":1390,"seo":1391,"stem":1392,"tags":1393,"__hash__":1395},"blogs\u002F_legacy\u002F2017\u002F2017-11-11-animatioinstarterpack-note-01.md","AnimatioinStarterPack的使用（上）",{"type":8,"value":1015,"toc":1362},[1016,1019,1022,1025,1028,1031,1034,1037,1040,1044,1047,1050,1056,1059,1062,1065,1068,1074,1077,1080,1086,1089,1092,1095,1098,1101,1107,1110,1113,1116,1119,1122,1125,1128,1131,1134,1137,1140,1144,1147,1153,1156,1159,1162,1165,1168,1171,1174,1177,1180,1183,1186,1189,1192,1195,1198,1204,1207,1210,1213,1216,1222,1225,1228,1231,1234,1237,1240,1243,1249,1252,1258,1261,1267,1270,1276,1279,1282,1285,1291,1294,1298,1301,1304,1307,1311,1314,1317,1323,1326,1332,1335,1338,1341,1344,1354,1356,1359],[11,1017,1018],{},"虚幻商城能看到官方提供的AnimationStarterPack，对于制作游戏原型非常的有用，毕竟如果一直用一个立方体来代替角色多少还是有些不足的。",[11,1020,1021],{},"当前使用的UE4版本为4.18.0。",[11,1023,1024],{},"4.18的升级中对角色动画相关的功能进行了改进，不过主要的改动是在PhysicAsset上的。刚好趁着这次开坑，对动画系统重新熟悉一下。",[11,1026,1027],{},"PS：这里只是操作笔记，并不会有很多细节上的说明哦~",[25,1029,1030],{"id":1030},"基础准备",[11,1032,1033],{},"首先当然是通过EpicLaucher添加AnimationStarterPack到项目中。",[11,1035,1036],{},"添加完成后能够看到动画包中有做好的基础角色蓝图，那么第一步就是参照着自己实现一遍。",[11,1038,1039],{},"动画蓝图的操作分别位于角色的蓝图和动画蓝图本身两个部分，这两者会互相交互来对状态进行更新。",[29,1041,1043],{"id":1042},"character","Character",[11,1045,1046],{},"角色蓝图直接新建一个Character即可，由于目标的系统是顶部的上帝视角的，所以会和官方的第一人称(?)的有些不同。",[11,1048,1049],{},"照例，先添加SpringArm和摄像",[11,1051,1052],{},[98,1053],{"alt":1054,"src":1055},"clip_image001","\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image001_thumb.png",[11,1057,1058],{},"记得在SpringArm上设置Use Pawn Control Rotation。",[11,1060,1061],{},"之后，在Mesh中将Skeletal Mesh指定为SK_Mannequin，动画蓝图那里随便指定一个Asset，方便预览。",[11,1063,1064],{},"根据官方提供的Character将位置设为(0,0,-100)，同时将旋转设为(0,0,-90)以保持朝向与Arrow一致。",[11,1066,1067],{},"这里如果直接运行的话会发现角色穿到地面以下了，原因是胶囊体的大小不一致。由于不清楚官方设定的理由，这里暂且按照官方的来，修改为",[11,1069,1070],{},[98,1071],{"alt":1072,"src":1073},"clip_image002","\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image002_thumb.png",[11,1075,1076],{},"这样就基本差不多了，然后将官方的角色蓝图中事件图表全部拷贝过来。这些蓝图都是些操作角色的输入处理，从Input拉到Character以及标志位的设置之类的，没有什么特别的地方呢。",[11,1078,1079],{},"没有的变量直接点右键生成，没有的输入直接到项目设置中添加。唯一要注意的是",[11,1081,1082],{},[98,1083],{"alt":1084,"src":1085},"clip_image003","\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image003_thumb.png",[11,1087,1088],{},"Lookup的Scale是-1，要不然操作起来和通常的FPS是相反的。",[29,1090,1091],{"id":1091},"动画蓝图",[11,1093,1094],{},"然后新建一个C++类，继承自AnimInstance，这样做主要是考虑到之后动画蓝图的逻辑可能会变得复杂。",[11,1096,1097],{},"接下来在蓝图中新建一个动画蓝图，父类选择刚刚构建的CharaAnimate，骨架选择UE4_Mannequin_Skeleton。",[11,1099,1100],{},"然后在Character蓝图的Mesh里面将动画指定为刚刚新建的动画蓝图",[11,1102,1103],{},[98,1104],{"alt":1105,"src":1106},"clip_image0014","\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image0014_thumb.png",[11,1108,1109],{},"指定完成后运行时就是个T字了，因为动画蓝图还是空的。",[11,1111,1112],{},"到达动画图表，添加一个简单的状态机。",[11,1114,1115],{},"状态机是动画蓝图的核心功能之一，可以通过设定的条件，根据变量的值等，跳转到不同的状态值，而不用自己根据众多的值对状态进行控制。",[11,1117,1118],{},"在动画图表中右键，新建一个状态机，名字就模仿官方的动画蓝图叫LocoMotion，并将它连到“最终动画姿势”上。",[11,1120,1121],{},"然后打开LocoMotion，右键新建一个状态，名为Idle。",[11,1123,1124],{},"打开Idle的状态，从右边的动画列表直接拖一个Idle_Rifle_Hip连接到Result上。",[11,1126,1127],{},"这样的话预览有些就能看到角色播放静止动画了。",[25,1129,1130],{"id":1130},"混合空间",[11,1132,1133],{},"混合空间是最基础的动画蓝图操作，大部分时候行走的动画都是靠其实现的。",[11,1135,1136],{},"新建一个混合空间，骨骼选择SK_Mannequin。",[11,1138,1139],{},"混合空间是2D的，通常的行走混合就是通过前进速度和前进方向来混合出八方向行走动画。",[29,1141,1143],{"id":1142},"blendspace","BlendSpace",[11,1145,1146],{},"打开混合空间，在左侧切换到Asset Detail标签，首先将混合用的两个坐标轴设置好。",[11,1148,1149],{},[98,1150],{"alt":1151,"src":1152},"clip_image0016","\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image0016_thumb.png",[11,1154,1155],{},"方向是从-180~180之间，而速度则需要根据Character的设定来决定，由于这里是默认的，就保持和官方示例的一样就好了。",[11,1157,1158],{},"这里的坐标名称是随意的，之后会通过蓝图来设置当前的坐标值。",[29,1160,1161],{"id":1161},"状态机",[11,1163,1164],{},"在进一步操作混合空间前，先将动画蓝图设置好。",[11,1166,1167],{},"动画图表的状态机中新建一个状态，命名为Move。",[11,1169,1170],{},"新建两个变量Speed、Direction，",[11,1172,1173],{},"从Idle的边缘拉一根线到Move，就会自动生成一个Transition。然后在Transition中添加条件为Speed>10.0则执行状态迁移，也就是由Idle变为Move。",[11,1175,1176],{},"然后从Move拉一个Transition到Idle，条件设置为Speed\u003C=10.0。",[11,1178,1179],{},"打开Move的状态，直接拖入刚刚新建的混合空间，把Speed和Direction分别接到混合空间的两个坐标轴上。可以在右边的动画预览页调整两个值来查看效果，不过现在混合空间是空的，会变成摆T字。",[11,1181,1182],{},"这样状态机的部分就设置完了。",[29,1184,1185],{"id":1185},"关键帧",[11,1187,1188],{},"然后回到混合空间中，在坐标系的各个位置添加混合节点。",[11,1190,1191],{},"一般情况下在角度(-180, -90, 0, 90, 180)和(行走速度,跑步速度)上添加关键性的混合用节点就可以了。",[11,1193,1194],{},"但是AnimationStarterPack中似乎没有跑步动画，不过这个版本的引擎中可以在左侧对节点的速度缩放进行调节，某种程度上可以代替跑步，不过反正是用来做原型的，也不用太在意。",[11,1196,1197],{},"在Speed 270上拖放动画，按角度来区分的话-180和180都是向后采用BWD，0则采用FWD，-90是LT而90是RT，然后在Speed 0上放一样的动画，但是将Rate Scale调低一些，变成0.8。",[11,1199,1200],{},[98,1201],{"alt":1202,"src":1203},"clip_image0024","\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image0024_thumb.png",[11,1205,1206],{},"然后将Target Weight Interpolation Speed Per Sec设定为2.0，这样混合空间的准备就完成了。",[29,1208,1209],{"id":1209},"状态绑定",[11,1211,1212],{},"此时在动画蓝图中调节预览的两个值，就可以看到效果了。",[11,1214,1215],{},"然后参照官方的动画蓝图中的节点，将速度和方向从Character那边读取过来。",[11,1217,1218],{},[98,1219],{"alt":1220,"src":1221},"clip_image0034","\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image0034_thumb.png",[11,1223,1224],{},"直接运行游戏，就可以看到行走的动画切换了。",[25,1226,1227],{"id":1227},"额外动作",[11,1229,1230],{},"在基本的行走动画之外，还有一些额外的动作可以加入到动画蓝图的状态机中，通常的FPS中会有跳跃、蹲伏、趴下之类的动作。",[11,1232,1233],{},"AnimationStarterPack中虽然有提供趴下的动作，但是是没有移动动画的，所以是一个静止的状态，这里并没有做，其实动画蓝图这边只是新建一个孤立的状态机就可以。主要还是要在角色蓝图中添加静止移动的逻辑，由于并没有做这种功能的打算，这里就放弃了。",[29,1235,1236],{"id":1236},"静止跳跃",[11,1238,1239],{},"这里官方的动画蓝图有一个问题，由于在Idle->Jump的管道中有加上速度条件，而实际上这个速度是包含跳跃速度的，因此导致状态机沿着Idle->Jog->Run Jump的路径前进，Jump这个状态是永远都不可达的。",[11,1241,1242],{},"由于不知道官方的原始设计时什么样的，这里姑且在Speed计算时忽略掉Z轴的速度。",[11,1244,1245],{},[98,1246],{"alt":1247,"src":1248},"clip_image0018","\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image0018_thumb.png",[11,1250,1251],{},"然后在检测到玩家按下跳跃键后，在动画蓝图中记录跳跃标记",[11,1253,1254],{},[98,1255],{"alt":1256,"src":1257},"clip_image0026","\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image0026_thumb.png",[11,1259,1260],{},"基本可以将官方的蓝图中的Jump相关的部分直接抄过来，另外由于修改了Jump的逻辑，要为Jump添加状态进入事件",[11,1262,1263],{},[98,1264],{"alt":1265,"src":1266},"clip_image0036","\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image0036_thumb.png",[11,1268,1269],{},"并在事件蓝图中相应",[11,1271,1272],{},[98,1273],{"alt":1274,"src":1275},"clip_image004","\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image004_thumb.png",[11,1277,1278],{},"在这里的话就能在静止状态下跳起来了，但是如果在行走中按跳跃的话，就会有BUG：在停止运动后额外的播放了一次动画。",[11,1280,1281],{},"这个是因为没有加RunJump状态造成的，不过为了以后添加别的状态不出现这个Bug，需要对CanJump()的实现多加留意。不能跳跃的状态就不要将跳跃标记置为True。",[11,1283,1284],{},"另外一个方面就是，Jump这个动画有一个前摇的过程，但是实际上蓝图的实现是已经跳跃起来了。这里需要对设计进行调整，或者让动画从0.3秒开始播放",[11,1286,1287],{},[98,1288],{"alt":1289,"src":1290},"clip_image005","\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image005_thumb.png",[11,1292,1293],{},"这样调整之后会造成落地有些许的违和感，这个主要是官方没有准备浮空动画而是在跳跃动画播放完后直接切回非跳跃状态造成的。因此大概是为了防止这里的穿帮，官方给的默认跳跃高度还是比较低的。记得以前的某个示例中是有的，但是在AnimationStarterPack中并没有找到这个呢。由于是用来做游戏原型的，这个细节就不管了。",[29,1295,1297],{"id":1296},"runjump","RunJump",[11,1299,1300],{},"然后就是RunJump的添加。",[11,1302,1303],{},"这里大部分的逻辑可以按照Jump的一样的流程，也可以从官方的示例里面抄过来。不过从Move->Jump的状态其实没有必要对速度进行限制了。直接检测到跳跃标记就切换到RunJump状态就可以了。",[11,1305,1306],{},"RunJump的切换非常的流畅，所以很怀疑官方让Jump状态失效是故意而为的。",[29,1308,1310],{"id":1309},"crouching","Crouching",[11,1312,1313],{},"下蹲状态和跳跃状态有些类似，不过下蹲状态被当作了一个持续性状态来处理。",[11,1315,1316],{},"所以下蹲分为静止下蹲和下蹲移动两个状态，下蹲移动中也还是一个负责移动处理的BlendSpace，参照Move的BlendeSpace即可",[11,1318,1319],{},[98,1320],{"alt":1321,"src":1322},"clip_image006","\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image006_thumb.png",[11,1324,1325],{},"总体上而言下蹲的静止和移动与Stand->Run是一个对应的关系。",[11,1327,1328],{},[98,1329],{"alt":1330,"src":1331},"clip_image007","\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image007_thumb.png",[11,1333,1334],{},"因此这里基本上没有什么新的东西。",[11,1336,1337],{},"唯一的不同是，由于前面修改过Speed运算方式。在Crouch的状态下按跳跃，只会有位置上升，而不会有动画的变更。",[11,1339,1340],{},"官方原始的类似于蹲下跳跃的效果，是由于Z轴速度大于10导致状态迁移到Crouch Move而产生的。",[11,1342,1343],{},"在CanJump()中添加CrouchingButtonDown时不允许设定Jump标志的逻辑，就可以防止在站起身之后进入跳跃的问题了。",[1345,1346,1351],"pre",{"className":1347,"code":1349,"language":1350},[1348],"language-text","bool UCharaAnimate::CanJump(bool ShouldJump)\n{\n  return !EnableJump && ShouldJump && !Crouching;\n}\n","text",[1352,1353,1349],"code",{"__ignoreMap":515},[25,1355,510],{"id":510},[11,1357,1358],{},"至此官方的动画蓝图中实现的功能就基本完成了，虽然在实现上和官方少许有些不同，不过功能上已经没有什么缺陷了。",[11,1360,1361],{},"接下来，就是添加上一些额外的动画来与游戏模式相对应了。",{"title":515,"searchDepth":407,"depth":492,"links":1363},[1364,1368,1374,1379],{"id":1030,"depth":407,"text":1030,"children":1365},[1366,1367],{"id":1042,"depth":492,"text":1043},{"id":1091,"depth":492,"text":1091},{"id":1130,"depth":407,"text":1130,"children":1369},[1370,1371,1372,1373],{"id":1142,"depth":492,"text":1143},{"id":1161,"depth":492,"text":1161},{"id":1185,"depth":492,"text":1185},{"id":1209,"depth":492,"text":1209},{"id":1227,"depth":407,"text":1227,"children":1375},[1376,1377,1378],{"id":1236,"depth":492,"text":1236},{"id":1296,"depth":492,"text":1297},{"id":1309,"depth":492,"text":1310},{"id":510,"depth":407,"text":510},"2017-11-11",{"layout":547,"status":548,"published":549,"author":1382,"author_login":552,"author_email":553,"wordpress_id":1383,"wordpress_url":1384,"date_gmt":1385,"excerpt":1386},{"display_name":551,"login":552,"email":553,"url":515},2066,"\u002F\u002F?p=2066","2017-11-11 02:51:55 +0000",{"type":8,"value":1387},[1388],[11,1389,1018],{},"\u002F2017-11-11-animatioinstarterpack-note-01",{"title":1013,"description":1018},"_legacy\u002F2017\u002F2017-11-11-animatioinstarterpack-note-01",[1394,565],"UE4","pkfBqzdfLonxqYHExxcc5TCbq5IXzXFvboJ8DjRg40o",{"id":1397,"title":1398,"body":1399,"date":1380,"description":1403,"extension":545,"meta":1690,"navigation":549,"path":1699,"seo":1700,"stem":1701,"tags":1702,"__hash__":1703},"blogs\u002F_legacy\u002F2017\u002F2017-11-11-animatioinstarterpack-note-02.md","AnimatioinStarterPack的使用（下）",{"type":8,"value":1400,"toc":1679},[1401,1404,1407,1410,1414,1417,1420,1423,1426,1429,1434,1437,1442,1444,1447,1450,1453,1456,1459,1464,1467,1472,1475,1479,1482,1485,1488,1491,1581,1584,1590,1593,1598,1601,1606,1609,1615,1618,1623,1626,1631,1634,1637,1640,1643,1646,1651,1654,1657,1661,1664,1667,1670,1673,1676],[11,1402,1403],{},"前面已经对官方的示例动画蓝图进行了还原，但是要作为原型测试时使用还是有些不足。",[11,1405,1406],{},"当前UE4版本为UE4.18.0。",[11,1408,1409],{},"这里继续对动画蓝图添加一些基本的功能。",[25,1411,1413],{"id":1412},"dead","Dead",[11,1415,1416],{},"死亡动画也是可以放到状态机的，但是如果状态机的结构很复杂的话，就会陷入需要从每个状态拉到Dead状态的窘境。",[11,1418,1419],{},"这里就需要在制作之前对状态机进行规划，例如其实静止和移动这两个状态是可以合并到一个BlendSpace中去的，再加上下蹲动画的合并，同时，将Jump和RunJump状态进行统一，状态机的数量就会减少。这里由于是原型用的，之后动画资源可能会不一样，就不会进行详细的设计和修改了。",[29,1421,1422],{"id":1422},"逻辑绑定",[11,1424,1425],{},"由于这里没有游戏逻辑，所以直接按下P键就判定玩家死亡。",[11,1427,1428],{},"在Character蓝图中，调用Disable Input来关闭玩家输入，设置标志位，3秒之后重置这些状态。在此就不做其他逻辑了。",[11,1430,1431],{},[98,1432],{"alt":1054,"src":1433},"\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image001_thumb-1.png",[11,1435,1436],{},"在动画蓝图的更新函数中，取得Character的死亡标记，并设置到动画蓝图中",[11,1438,1439],{},[98,1440],{"alt":1072,"src":1441},"\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image002_thumb-1.png",[29,1443,1091],{"id":1091},[11,1445,1446],{},"在状态机中添加Dead状态，随便拉一个Dead动画出来播放，不要循环。",[11,1448,1449],{},"然后从Idle->Dead设定条件为PawnDead，而从Dead->Idle为非PawnDead。",[11,1451,1452],{},"这样就有了基本的死亡动画逻辑。",[11,1454,1455],{},"其实官方总共准备了3种略有不同的站立死亡动画，这里可以选择随机的播放一种，使用名为Blend Poses by int的节点即可。",[11,1457,1458],{},"在Dead状态中，对动画进行操作",[11,1460,1461],{},[98,1462],{"alt":1084,"src":1463},"\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image003_thumb-1.png",[11,1465,1466],{},"DeadAnimatType是新建的Int变量，需要在检测到死亡标志位时随机指定到0~2之间。",[11,1468,1469],{},[98,1470],{"alt":1274,"src":1471},"\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image004_thumb-1.png",[11,1473,1474],{},"这样就有了随机死亡动画的功能了，不过这里由于没有添加Respawn的逻辑，3秒的Delay之后是直接原地站起来复活的:D",[25,1476,1478],{"id":1477},"aimoffset","AimOffset",[11,1480,1481],{},"这也是UE4提供的动画Asset之一，其主要作用是在移动-静止动画上叠加的额外的瞄准动画。",[29,1483,1484],{"id":1484},"资源准备",[11,1486,1487],{},"新建一个AimOffset打开编辑，能看到它和BlendSpace一样有两个轴向对动画进行Blend，不同之处在于AimOffset最终是叠加到已有的基础动作之上的。",[11,1489,1490],{},"要做AimOffset首先需要的是制作各个瞄准方向的基础动作，在AnimationStarterPack中，瞄准动画可以从Aim_Space_Hip的动画中取出，其中共有9个动作，帧数分别为：",[1492,1493,1494,1505],"table",{},[1495,1496,1497],"thead",{},[1498,1499,1500,1503],"tr",{},[1501,1502],"th",{},[1501,1504],{},[1506,1507,1508,1517,1525,1533,1541,1549,1557,1565,1573],"tbody",{},[1498,1509,1510,1514],{},[1511,1512,1513],"td",{},"0",[1511,1515,1516],{},"Aim_Center",[1498,1518,1519,1522],{},[1511,1520,1521],{},"10",[1511,1523,1524],{},"Aim_Center_Up",[1498,1526,1527,1530],{},[1511,1528,1529],{},"20",[1511,1531,1532],{},"Aim_Center_Down",[1498,1534,1535,1538],{},[1511,1536,1537],{},"30",[1511,1539,1540],{},"Aim_Left_Center",[1498,1542,1543,1546],{},[1511,1544,1545],{},"40",[1511,1547,1548],{},"Aim_Left_Up",[1498,1550,1551,1554],{},[1511,1552,1553],{},"50",[1511,1555,1556],{},"Aim_Left_Down",[1498,1558,1559,1562],{},[1511,1560,1561],{},"60",[1511,1563,1564],{},"Aim_Right_Center",[1498,1566,1567,1570],{},[1511,1568,1569],{},"70",[1511,1571,1572],{},"Aim_Right_Up",[1498,1574,1575,1578],{},[1511,1576,1577],{},"80",[1511,1579,1580],{},"Aim_Right_Down",[11,1582,1583],{},"操作上，对Anim_Space_Hip进行复制，通过最下方的帧导航到想要的帧。",[11,1585,1586],{},[98,1587],{"alt":1588,"src":1589},"clip_image0015","\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image0015_thumb.png",[11,1591,1592],{},"然后在帧导航条上点击右键，先删除左边的所有帧，再删除右边的所有帧",[11,1594,1595],{},[98,1596],{"alt":1202,"src":1597},"\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image0024_thumb-1.png",[11,1599,1600],{},"这样就能得到9个只有一帧的动画了，全部选中，然后在右键菜单中使用集合编辑功能。",[11,1602,1603],{},[98,1604],{"alt":1220,"src":1605},"\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image0034_thumb-1.png",[11,1607,1608],{},"然后对AdditiveSettings属性进行调整",[11,1610,1611],{},[98,1612],{"alt":1613,"src":1614},"clip_image0044","\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image0044_thumb.png",[11,1616,1617],{},"回到刚刚新建的AnimOffset，与BlendSpace类似，设定两个轴向的名称和范围",[11,1619,1620],{},[98,1621],{"alt":1289,"src":1622},"\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image005_thumb-1.png",[11,1624,1625],{},"然后将刚刚生成的9个动作拖放到关键插值点上去",[11,1627,1628],{},[98,1629],{"alt":1321,"src":1630},"\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image006_thumb-1.png",[11,1632,1633],{},"这样就可以了。",[29,1635,1091],{"id":1636},"动画蓝图-1",[11,1638,1639],{},"接下来，到动画蓝图中对AnimOffset进行使用。",[11,1641,1642],{},"首先添加两个Float变量，分别命名Aim_Yaw和Aim_Pitch",[11,1644,1645],{},"然后到动画图表中，添加AnimOffset的使用",[11,1647,1648],{},[98,1649],{"alt":1330,"src":1650},"\u002Fwp-content\u002Fuploads\u002F2017\u002F11\u002Fclip_image007_thumb-1.png",[11,1652,1653],{},"这时，在动画蓝图的预览中就可以对AimOffset进行调试了。",[11,1655,1656],{},"如果要实际使用的话，还要在BlueprintUpdateAnimation事件或者其他地方，对这两个值进行更新。由于我这边是做的TopDown，就不继续操作了。",[25,1658,1660],{"id":1659},"montage","Montage",[11,1662,1663],{},"其他的一些动画，包括射击动画、装备切换动画都需要用到Montage。",[11,1665,1666],{},"这些动画都是与具体的资源相关性比较强的，在原型制作阶段制作的话就不会进行更多的时间投入了。",[11,1668,1669],{},"包括换枪、持枪、射击在内的动画要使用Motage，是因为身体的基本动作是一致的，不可能为每一个状态做一个对应的动画。",[11,1671,1672],{},"基本的装备切换，都是通过在Montage中添加动画通知，然后将物品切换Socket来做的。",[11,1674,1675],{},"由于只是要做一个动画蓝图来做原型用，而且要使用Montage的话，就必须从资源开始就有做好的规划，在没有进一步需求的情况下暂时就不会继续做下去了。",[11,1677,1678],{},"Montage的教程很多，直接搜索就可以了:D。",{"title":515,"searchDepth":407,"depth":492,"links":1680},[1681,1685,1689],{"id":1412,"depth":407,"text":1413,"children":1682},[1683,1684],{"id":1422,"depth":492,"text":1422},{"id":1091,"depth":492,"text":1091},{"id":1477,"depth":407,"text":1478,"children":1686},[1687,1688],{"id":1484,"depth":492,"text":1484},{"id":1636,"depth":492,"text":1091},{"id":1659,"depth":407,"text":1660},{"layout":547,"status":548,"published":549,"author":1691,"author_login":552,"author_email":553,"wordpress_id":1692,"wordpress_url":1693,"date_gmt":1694,"excerpt":1695},{"display_name":551,"login":552,"email":553,"url":515},2091,"\u002F\u002F?p=2091","2017-11-11 02:52:21 +0000",{"type":8,"value":1696},[1697],[11,1698,1403],{},"\u002F2017-11-11-animatioinstarterpack-note-02",{"title":1398,"description":1403},"_legacy\u002F2017\u002F2017-11-11-animatioinstarterpack-note-02",[1394,565],"yvxgzW9FrlIGR1YF3sTA3p7Scjk6Z2_J6JX0053oKt8",{"id":1705,"title":1706,"body":1707,"date":1915,"description":1711,"extension":545,"meta":1916,"navigation":549,"path":1925,"seo":1926,"stem":1927,"tags":1928,"__hash__":1929},"blogs\u002F_legacy\u002F2017\u002F2017-05-21-ue4-new-animation-and-physics.md","UE4.16新动画与物理功能",{"type":8,"value":1708,"toc":1908},[1709,1712,1721,1725,1728,1731,1734,1739,1742,1747,1750,1755,1758,1761,1766,1769,1775,1778,1781,1785,1788,1793,1796,1801,1804,1808,1811,1814,1819,1822,1827,1830,1834,1837,1840,1845,1848,1853,1856,1861,1864,1869,1872,1877,1880,1885,1888,1893,1896,1899,1902,1905],[11,1710,1711],{},"4.16的Preview更新已经发布有一段时间了，与以往一样，这次的版本更新也带来了很多新的功能与改变。",[11,1713,1714,1715,1720],{},"本文主要参照官方的功能[",[18,1716,1719],{"href":1717,"rel":1718},"https:\u002F\u002Fwww.slideshare.net\u002FEpicGamesJapan\u002Funreal-engine-75203047",[22],"演示文稿","]进行整理完成。",[25,1722,1724],{"id":1723},"基于rig的动画编辑","基于Rig的动画编辑",[11,1726,1727],{},"Rig是一种很方便的驱动骨骼动画的方式，本次的更新中添加了新的Rig动画编辑功能。",[11,1729,1730],{},"这个功能使得在编辑器中对Rig动画进行编辑变得可能，让我们进行更方便对动画调整和原型设计。",[11,1732,1733],{},"要想开启Rig动画编辑功能，首先要开启Control Rig插件：",[11,1735,1736],{},[98,1737],{"alt":218,"src":1738},"\u002Fwp-content\u002Fuploads\u002F2017\u002F05\u002Fimage_thumb-14.png",[11,1740,1741],{},"启用插件之后就可以在编辑器中看到这个模块到功能了：",[11,1743,1744],{},[98,1745],{"alt":218,"src":1746},"\u002Fwp-content\u002Fuploads\u002F2017\u002F05\u002Fimage_thumb-15.png",[11,1748,1749],{},"中这个选项卡中新建一个Rig Sequence，然后拖一个骨骼Mesh进来当作目标，就可以在Sequence到编辑器中进行动画到编辑了：",[11,1751,1752],{},[98,1753],{"alt":218,"src":1754},"\u002Fwp-content\u002Fuploads\u002F2017\u002F05\u002Fimage_thumb-16.png",[11,1756,1757],{},"编辑过程比较直观，也可以在IK与FK模式中进行切换，完成的动画可以导出成动画序列，在这个编辑器中也可以进行Retarget操作。",[11,1759,1760],{},"要导出动画，在Content Manager中找到Control Rig Sequence并点击右键，就可以看到相关到选项",[11,1762,1763],{},[98,1764],{"alt":218,"src":1765},"\u002Fwp-content\u002Fuploads\u002F2017\u002F05\u002Fimage_thumb-17.png",[11,1767,1768],{},"然后就可以进行选择设置了",[11,1770,1771],{},[98,1772],{"alt":1773,"src":1774},"SNAGHTML6685395","\u002Fwp-content\u002Fuploads\u002F2017\u002F05\u002FSNAGHTML6685395_thumb.png",[11,1776,1777],{},"但是似乎没有看到从动画序列转换到Rig Sequence到方法。",[11,1779,1780],{},"Rig相关功能在4.16之后似乎还会增强，使得动画蓝图可以对Rig进行控制以及生成。",[25,1782,1784],{"id":1783},"live-link","Live Link",[11,1786,1787],{},"很强大的功能，使得UE4与其他的3D编辑器可以实时的联动编辑。这样就能更加直观的看到需要做的内容做UE4中是如何工作的。",[11,1789,1790],{},[98,1791],{"alt":218,"src":1792},"\u002Fwp-content\u002Fuploads\u002F2017\u002F05\u002Fimage_thumb-18.png",[11,1794,1795],{},"看起来非常的实用",[11,1797,1798],{},[98,1799],{"alt":218,"src":1800},"\u002Fwp-content\u002Fuploads\u002F2017\u002F05\u002Fimage_thumb-19.png",[11,1802,1803],{},"不过这个似乎要到4.17才会进入试验阶段……",[25,1805,1807],{"id":1806},"immediate-mode","Immediate Mode",[11,1809,1810],{},"之前的Physx是使用所谓保留模式（Retained Mode）工作的，Retained Mode有不少优点，方便实用。但是也有很多缺点，例如中对物体对Deactive逻辑处理时有不少效率上的问题、对物体进行遍历并不方便、很难对特定对物体组进行模拟成本计算等。",[11,1812,1813],{},"而Immediate Mode通过暴露出更多等底层操作接口，使得引擎能够更有效的对物理引擎进行控制和契合，同时也能大幅度的提升LOD以及Culing机制下的物理效率。",[11,1815,1816],{},[98,1817],{"alt":218,"src":1818},"\u002Fwp-content\u002Fuploads\u002F2017\u002F05\u002Fimage_thumb-20.png",[11,1820,1821],{},"这个功能目前的一个主要应用是运动角色模型上的小的物体，这是一个在动画蓝图中的新节点：",[11,1823,1824],{},[98,1825],{"alt":218,"src":1826},"\u002Fwp-content\u002Fuploads\u002F2017\u002F05\u002Fimage_thumb-21.png",[11,1828,1829],{},"它使得在动画蓝图中进行物理资源的模拟变得可能，这种方式比AnimDynamic的方式更方便进行操作，也具有更高的效率。",[25,1831,1833],{"id":1832},"nvcloth","NvCloth",[11,1835,1836],{},"4.16开始UE4中开始使用NVIDIA的新的Cloth框架：NvCloth，它能直接在引擎中进行材质制作，大大的减少了以前必须使用Apex外部制作工具带来的很多麻烦。",[11,1838,1839],{},"同时NvCloth也获得了Immediate Mode的优势，使得Cloth的仿真效能得到增强。NvCloth也应用了新的空气阻力模型",[11,1841,1842],{},[98,1843],{"alt":218,"src":1844},"\u002Fwp-content\u002Fuploads\u002F2017\u002F05\u002Fimage_thumb-22.png",[11,1846,1847],{},"要使用NvCloth首先需要中试验性功能中打开这个功能：",[11,1849,1850],{},[98,1851],{"alt":218,"src":1852},"\u002Fwp-content\u002Fuploads\u002F2017\u002F05\u002Fimage_thumb-23.png",[11,1854,1855],{},"然后就可以在骨骼Mesh的编辑器中选中区域选择：",[11,1857,1858],{},[98,1859],{"alt":218,"src":1860},"\u002Fwp-content\u002Fuploads\u002F2017\u002F05\u002Fimage_thumb-24.png",[11,1862,1863],{},"这之后选择相应的区域就可以对其进行Cloth绘制了：",[11,1865,1866],{},[98,1867],{"alt":218,"src":1868},"\u002Fwp-content\u002Fuploads\u002F2017\u002F05\u002Fimage_thumb-25.png",[11,1870,1871],{},"添加后就能看到新的区域了",[11,1873,1874],{},[98,1875],{"alt":218,"src":1876},"\u002Fwp-content\u002Fuploads\u002F2017\u002F05\u002Fimage_thumb-26.png",[11,1878,1879],{},"不过这里暂时没什么用，最主要的还是绘制的过程：",[11,1881,1882],{},[98,1883],{"alt":218,"src":1884},"\u002Fwp-content\u002Fuploads\u002F2017\u002F05\u002Fimage_thumb-27.png",[11,1886,1887],{},"在窗口中能看到ClothPaint，打开之后进行权重绘制即可。",[11,1889,1890],{},[98,1891],{"alt":218,"src":1892},"\u002Fwp-content\u002Fuploads\u002F2017\u002F05\u002Fimage_thumb-28.png",[11,1894,1895],{},"因为手头没有模型，无法进行绘制测试，看官方的演示的话，NvCloth无论是从效果上还是效率上都比原来的Apex路径强很多。",[25,1897,1898],{"id":1898},"其他",[11,1900,1901],{},"在最近的引擎更新中有很多Robo Recall相关的功能实现被合并到了引擎中。",[11,1903,1904],{},"其中前向渲染的添加、运动物体上的CCD、pose snapshot、Constraint profile以及用于模拟移动有一定重量物体的Spring Lerp等已经在之前的版本中添加到了引擎中。",[11,1906,1907],{},"另外似乎有新的粒子系统在制作中，很期待接下来的版本更新。",{"title":515,"searchDepth":407,"depth":492,"links":1909},[1910,1911,1912,1913,1914],{"id":1723,"depth":407,"text":1724},{"id":1783,"depth":407,"text":1784},{"id":1806,"depth":407,"text":1807},{"id":1832,"depth":407,"text":1833},{"id":1898,"depth":407,"text":1898},"2017-05-21",{"layout":547,"status":548,"published":549,"author":1917,"author_login":552,"author_email":553,"wordpress_id":1918,"wordpress_url":1919,"date_gmt":1920,"excerpt":1921},{"display_name":551,"login":552,"email":553,"url":515},1738,"\u002F\u002F?p=1738","2017-05-21 15:51:45 +0000",{"type":8,"value":1922},[1923],[11,1924,1711],{},"\u002F2017-05-21-ue4-new-animation-and-physics",{"title":1706,"description":1711},"_legacy\u002F2017\u002F2017-05-21-ue4-new-animation-and-physics",[1394,1832,565],"hEJJu0weqtXDxRLWNMRQ6X90OGRMe63j2oph88zyr_s",5,1788763179807]