[{"data":1,"prerenderedAt":919},["ShallowReactive",2],{"blog-page-25":3,"blog-count":918},[4,138,417,625,861],{"id":5,"title":6,"body":7,"date":114,"description":13,"extension":115,"meta":116,"navigation":119,"path":131,"seo":132,"stem":133,"tags":134,"__hash__":137},"blogs\u002F_legacy\u002F2015\u002F2015-03-28-ubuntu%e4%b8%8blnmp%e7%8e%af%e5%a2%83%e5%ae%89%e8%a3%85%e9%85%8d%e7%bd%aephalconphp.md","Ubuntu下Lnmp环境安装配置PhalconPHP",{"type":8,"value":9,"toc":110},"minimark",[10,14,17,20,23,34,37,43,46,52,55,58,61,68,71,81,92,98,101,107],[11,12,13],"p",{},"Lnmp在快速搭建网站环境方面特别方便，基本不用自己去研究各个软件的安装和配置。由于对Linux半生不熟，在安装Phalcon时却遇到了一些问题，在这里总结下经验。",[11,15,16],{},"当前Lnmp版本:1.1。当前Phalcon版本:1.3.4。PHP版本：5.6.6。",[11,18,19],{},"要使用PhalconPHP，升级下php版本比较好，按照lnmp官方的提示进行即可。",[11,21,22],{},"Phalcon的缓存系统可以使用Memcache，在升级了php版本之后，如果使用官方的安装脚本会有问题。将原本从48行开始的版本检测语句添加新的php版本即可：",[24,25,30],"pre",{"className":26,"code":28,"language":29},[27],"language-text","if echo \"$cur_php_version\" | grep -q \"5.2.\" \nthen \nsed -i 's#extension_dir = \".\u002F\"#extension_dir = \"\u002Fusr\u002Flocal\u002Fphp\u002Flib\u002Fphp\u002Fextensions\u002Fno-debug-non-zts-20060613\u002F\"\\nextension = \"memcache.so\"\\n#' \u002Fusr\u002Flocal\u002Fphp\u002Fetc\u002Fphp.ini \nelif echo \"$cur_php_version\" | grep -q \"5.3.\" \nthen \nsed -i 's#extension_dir = \".\u002F\"#extension_dir = \"\u002Fusr\u002Flocal\u002Fphp\u002Flib\u002Fphp\u002Fextensions\u002Fno-debug-non-zts-20090626\u002F\"\\nextension = \"memcache.so\"\\n#' \u002Fusr\u002Flocal\u002Fphp\u002Fetc\u002Fphp.ini \nelif echo \"$cur_php_version\" | grep -q \"5.4.\" \nthen \nsed -i 's#extension_dir = \".\u002F\"#extension_dir = \"\u002Fusr\u002Flocal\u002Fphp\u002Flib\u002Fphp\u002Fextensions\u002Fno-debug-non-zts-20100525\u002F\"\\nextension = \"memcache.so\"\\n#' \u002Fusr\u002Flocal\u002Fphp\u002Fetc\u002Fphp.ini \nelif echo \"$cur_php_version\" | grep -q \"5.6.\" \nthen \nsed -i 's#extension_dir = \".\u002F\"#extension_dir = \"\u002Fusr\u002Flocal\u002Fphp\u002Flib\u002Fphp\u002Fextensions\u002Fno-debug-non-zts-20131226\u002F\"\\nextension = \"memcache.so\"\\n#' \u002Fusr\u002Flocal\u002Fphp\u002Fetc\u002Fphp.ini \nelse \n&nbsp;&nbsp;&nbsp; echo \"Error: can't get php version!\" \n&nbsp;&nbsp;&nbsp; echo \"Maybe your php was didn't install or php configuration file has errors.Please check.\" \n&nbsp;&nbsp;&nbsp; sleep 3 \n&nbsp;&nbsp;&nbsp; exit 1 \nfi\n","text",[31,32,28],"code",{"__ignoreMap":33},"",[11,35,36],{},"通过apt-get install php5-phalcon安装的Phalcon是编译给PHP5.4的，由于没有实际使用过所以也不知道该Phalcon的版本是多少。按照官方的要求进行编译安装：",[24,38,41],{"className":39,"code":40,"language":29},[27],"git clone --depth=1 git:\u002F\u002Fgithub.com\u002Fphalcon\u002Fcphalcon.git\n\ncd cphalcon\u002Fbuild\n\nsudo .\u002Finstall\n",[31,42,40],{"__ignoreMap":33},[11,44,45],{},"这个时候会遇到错误，大体意思是找不到php目录。打开install脚本进行编辑，在第64行按照提示添加php-config",[24,47,50],{"className":48,"code":49,"language":29},[27],"\u002Fusr\u002Flocal\u002Fphp\u002Fbin\u002Fphpize && .\u002Fconfigure  --with-php-config=\u002Fusr\u002Flocal\u002Fphp\u002Fbin\u002Fphp-config --enable-phalcon && make && make install && echo -e \"\\nThanks for compiling Phalcon!\\nBuild succeed: Please restart your web server to complete the installation\"\n",[31,51,49],{"__ignoreMap":33},[11,53,54],{},"这个时候安装就能正确进行了，安装完成之后在php.ini中添加",[11,56,57],{},"extension = phalcon.so",[11,59,60],{},"重置lnmp，在phpinfo()中就能看到Phalcon已经启用成功。",[11,62,63],{},[64,65],"img",{"alt":66,"src":67},"image","\u002Fwp-content\u002Fuploads\u002F2015\u002F03\u002Fimage_thumb.png",[11,69,70],{},"使用lnmp的添加域名脚本添加好之后，需要对生成的配置文件进行修改。如果处理不当将可能导致以下两种情况：",[72,73,74,78],"ol",{},[75,76,77],"li",{},"所有的控制器都无法访问，全部被当作index\u002Findex来处理",[75,79,80],{},"无法正常的通过get、getQuery等函数获取url参数，全部返回null",[11,82,83,84,91],{},"具体的设定可以参考官方的",[85,86,90],"a",{"href":87,"rel":88},"http:\u002F\u002Fdocs.phalconphp.com\u002Fzh\u002Flatest\u002Freference\u002Fnginx.html",[89],"nofollow","安装说明","进行，下面给出的是本次配置服务器所使用的配置。",[24,93,96],{"className":94,"code":95,"language":29},[27],"server \n    { \n        listen 80; \n        #listen [::]:80; \n        server_name www.xxxx.com xxxx.com; \n        index index.html index.htm index.php default.html default.htm default.php; \n        set $root_path '\u002Fhome\u002Fwwwroot\u002Fwww.xxxx.com\u002Fpublic'; \n        root $root_path;\n\n        location \u002F { \n            try_files $uri $uri\u002F \u002Findex.php?_url=$uri&$args; \n        }\n\n        location ~ \\.php$ { \n                try_files $uri =404; \n                fastcgi_split_path_info ^(.+\\.php)(\u002F.+)$; \n                fastcgi_pass  unix:\u002Ftmp\u002Fphp-cgi.sock; \n                fastcgi_index index.php; \n                fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name; \n                include fastcgi.conf; \n        }\n\n \n\n        location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf)$ \n        { \n            root          $root_path; \n            expires      30d; \n        }\n\n \n\n        location ~ .*\\.(js|css)?$ \n        { \n            root          $root_path; \n            expires      12h; \n        }\n\n        location ~ \u002F\\.ht { \n            deny all; \n        } \n    }\n",[31,97,95],{"__ignoreMap":33},[11,99,100],{},"同时对Router进行设置：",[24,102,105],{"className":103,"code":104,"language":29},[27],"$di->set('router', function () use($routes) {\n\n    $router = new \\Phalcon\\Mvc\\Router(); \n    $router->setUriSource(\\Phalcon\\Mvc\\Router::URI_SOURCE_SERVER_REQUEST_URI);\n\n    return $router; \n});\n",[31,106,104],{"__ignoreMap":33},[11,108,109],{},"上面的步骤完成后，Phalcon就已经能够正常的在Lnmp上运行了。",{"title":33,"searchDepth":111,"depth":112,"links":113},2,3,[],"2015-03-28","md",{"layout":117,"status":118,"published":119,"author":120,"author_login":121,"author_email":122,"author_url":123,"wordpress_id":124,"wordpress_url":125,"date_gmt":126,"excerpt":127},"post","publish",true,{"display_name":121,"login":121,"email":122,"url":123},"chaoshikari","chaoshikari@gmail.com","\u002F",1186,"\u002F\u002F?p=1186","2015-03-28 07:15:02 +0000",{"type":8,"value":128},[129],[11,130,13],{},"\u002F2015-03-28-ubuntu下lnmp环境安装配置phalconphp",{"title":6,"description":13},"_legacy\u002F2015\u002F2015-03-28-ubuntu%e4%b8%8blnmp%e7%8e%af%e5%a2%83%e5%ae%89%e8%a3%85%e9%85%8d%e7%bd%aephalconphp",[135,136],"phalcon","lnmp","HmJ18hPsIxa_Lbn8la3vHsHxD27rrcuuacqrFRuJL9I",{"id":139,"title":140,"body":141,"date":399,"description":145,"extension":115,"meta":400,"navigation":119,"path":409,"seo":410,"stem":411,"tags":412,"__hash__":416},"blogs\u002F_legacy\u002F2015\u002F2015-02-11-apex%e7%9b%b8%e5%85%b3.md","APEX相关",{"type":8,"value":142,"toc":395},[143,146,149,154,157,163,170,173,176,179,184,187,192,195,198,203,206,211,214,219,222,225,228,231,234,239,245,248,251,256,259,264,267,270,275,278,283,286,291,294,297,300,305,308,313,316,319,324,327,331,334,337,342,345,348,353,356,359,365,368,373,376,381,384,389,392],[11,144,145],{},"由于UE4使用的是PhysX引擎，因此一些相关的特性需要使用其相关的工具才能实现。当前（4.6.1）版本UE4只支持两个Apex特性，分别是Destruct和Cloth。",[11,147,148],{},"对官方的讲解视频以及部分文档进行总结，方便以后使用到时可以进行快速的索引。",[150,151,153],"h3",{"id":152},"破碎","① 破碎",[11,155,156],{},"破碎方面使用PhysX的工具可以获得额外的两种制作方式，同时可以得到当前引擎中没有的多级别破碎效果。",[11,158,159],{},[160,161,162],"strong",{},"Slice模式切割",[11,164,165,166],{},"官方视频地址：",[85,167,168],{"href":168,"rel":169,"title":168},"http:\u002F\u002Fv.youku.com\u002Fv_show\u002Fid_XNDEzMTM3Mzky.html",[89],[11,171,172],{},"示例文件目录为PhysXLab目录下的DestructionSamples\\Pillar。",[11,174,175],{},"在文件菜单中选择Import 3D Mesh导入BrickPillar.FBX（其实可以直接打开官方提供的project文件，这样就不用进行文件的导入了）。",[11,177,178],{},"在上面的工具栏中选择刀形状的切割工具，在右边的工具栏就会出现相应的属性。",[11,180,181],{},[64,182],{"alt":66,"src":183},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb.png",[11,185,186],{},"直接点击Fracture按钮或者右上角跳动的F图标，就会生成Slice的破碎",[11,188,189],{},[64,190],{"alt":66,"src":191},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb1.png",[11,193,194],{},"由于没有切面贴图，切面的效果很不理想。因此先在文件菜单中点击Load Texture as Materia来导入材质BrickPillarInt_d.tga。",[11,196,197],{},"导入之后到Graphic工具中应用切面贴图即可。需要注意的是示例提供的贴图应用时和默认的UV Scale有所不同。",[11,199,200],{},[64,201],{"alt":66,"src":202},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb2.png",[11,204,205],{},"在Slice属性中，展开高级模式，可以手动的设置各个坐标上的切割数",[11,207,208],{},[64,209],{"alt":66,"src":210},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb3.png",[11,212,213],{},"通过设置切割深度，可以做出层次更多的切割结果。在工具栏中的预览深度可以调节当前预览的切割效果层次。",[11,215,216],{},[64,217],{"alt":66,"src":218},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb4.png",[11,220,221],{},"其他的一些属性：",[11,223,224],{},"Use Target Proportions - 使得碎片尽量的保持给定的长宽高比例，这个设置会优先于切割线设置来保持比例。",[11,226,227],{},"Seams Variation - 使得切割线的分布变得更加的不均匀，有平移和角度两个选项",[11,229,230],{},"Noise - 有幅度、频率和网格尺寸3个选项，可以使切面表面出现凹凸效果。",[11,232,233],{},"属性之间的组合能够实现不同的材质破碎效果，在编辑器中进行尝试即可。按F12可以进入预览模式，用锤子进行破坏来模拟实际的效果。",[11,235,236],{},[160,237,238],{},"Cut-Out模式切割",[11,240,165,241],{},[85,242,243],{"href":243,"rel":244,"title":243},"http:\u002F\u002Fv.youku.com\u002Fv_show\u002Fid_XMzU1NDY0NTMy.html",[89],[11,246,247],{},"示例文件目录为PhysXLab目录下的DestructionSamples\\Wall。",[11,249,250],{},"这个模式有两个设置的地方，一个是要调整切割的挡板的位置，另外一个是要选择切割图。全部设置过之后会自动生成两个层次的分割效果。第一层是设置好的挡板的分离，第二层是对分离出来的表面应用切割图进一步分割。",[11,252,253],{},[64,254],{"alt":66,"src":255},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb5.png",[11,257,258],{},"生成之后的效果就是完全按照墙面的砖块进行分割破碎。",[11,260,261],{},[64,262],{"alt":66,"src":263},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb6.png",[11,265,266],{},"切面贴图和Noise的设置基本和Slice模式的相同。",[11,268,269],{},"切换到Assets工具栏，在第一层级为后面的墙面设置Dont Frature属性，保证其静态。为前面的墙面设置Dont Damage属性，使得所有的伤害被传递到下一个层级，而不是整个墙面对伤害有响应。在第二层级，设置Support Depth为2，同时打开World Overlap，这样一来砖块就会受到世界的支撑。不会出现不自然的瓦解的情况。",[11,271,272],{},[64,273],{"alt":66,"src":274},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb7.png",[11,276,277],{},"可以对这个分割进行进一步的Slice来达到更好的效果",[11,279,280],{},[64,281],{"alt":66,"src":282},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb8.png",[11,284,285],{},"加上一定的随机之后，砖块就变得可以敲碎了。",[11,287,288],{},[64,289],{"alt":66,"src":290},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb9.png",[11,292,293],{},"可以通过Export Assets导出apb格式的破碎设置供UE4导入。",[11,295,296],{},"导入时先导入网格文件，然后点击生成可破坏网格之后在其中导入apb文件。在UE4中进行快捷测试的步骤：",[11,298,299],{},"首先在可破坏物体中",[11,301,302],{},[64,303],{"alt":66,"src":304},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb10.png",[11,306,307],{},"打开并修改Impact Damage，然后将这个物体拖到地图中。",[11,309,310],{},[64,311],{"alt":66,"src":312},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb11.png",[11,314,315],{},"打开物理模拟和碰撞事件。将物体拖到一定的高度。然后开始模拟，坠落的冲击产生的伤害会使得物体破碎。如果使用的是上面生成的破碎，由于一瞬间产生了很多碎片，并且都在进行物理模拟。很可能会引起卡顿。其实对于小碎片，最好使用粒子效果来替换掉。系统的开销就会大幅度下降了。",[11,317,318],{},"同时，导入apb时切面材质如果没有的话需要手动导入。也可以直接指定成其他的材质。",[11,320,321],{},[64,322],{"alt":66,"src":323},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb12.png",[11,325,326],{},"上面的导入中，第二个材质就是切面材质了。",[150,328,330],{"id":329},"衣料","② 衣料",[11,332,333],{},"衣料的材质制作NVIDIA官方提供了针对3ds max和maya的插件，虽然官方社区有直接使用Physx自带的制作程序的相关说法。但是还是存在不少问题，这里还是直接使用官方提供的流程进行操作比较好。在NVIDIA官方下载好插件并安装后，可以在目录中看到官方提供的文档。详细的参数及其作用可以到其中去参考。",[11,335,336],{},"制作Cloth材质可以在toolbar上点击这个按钮：",[11,338,339],{},[64,340],{"alt":66,"src":341},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb13.png",[11,343,344],{},"这样的话就会在当前修改器栈中添加一个新的衣料材质修改器，可以在其中进行属性的设置等操作。",[11,346,347],{},"最主要的属性操作是max distance的喷涂，设定好值之后直接点击按钮即可在材质上喷涂上设定的值。",[11,349,350],{},[64,351],{"alt":66,"src":352},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb14.png",[11,354,355],{},"如果要看模拟的效果，可以直接点击插件提供的模拟按钮。",[11,357,358],{},"操作完毕之后可以对衣料材质进行导出。当前版本使用下面的配置可以正常的工作：",[11,360,361],{},[64,362],{"alt":363,"src":364},"SNAGHTML8aa3b0","\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002FSNAGHTML8aa3b0_thumb.png",[11,366,367],{},"然后就是在UE4中进行导入了，衣料材质不需要导入到内容管理器中。直接在需要使用到的模型中点击下面的添加材质按钮即可。",[11,369,370],{},[64,371],{"alt":66,"src":372},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb15.png",[11,374,375],{},"添加完毕之后就可以在材质的下方看到Cloth的选框，在其中选择对应的即可。",[11,377,378],{},[64,379],{"alt":66,"src":380},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb16.png",[11,382,383],{},"最终的结果如下，由于是静态图片不怎么能看出效果。",[11,385,386],{},[64,387],{"alt":66,"src":388},"\u002Fwp-content\u002Fuploads\u002F2015\u002F02\u002Fimage_thumb17.png",[390,391],"hr",{},[11,393,394],{},"总体而言，作为UE4外部的制作流程，APEX的操作还是相对简单的。",{"title":33,"searchDepth":111,"depth":112,"links":396},[397,398],{"id":152,"depth":112,"text":153},{"id":329,"depth":112,"text":330},"2015-02-11",{"layout":117,"status":118,"published":119,"author":401,"author_login":121,"author_email":122,"author_url":123,"wordpress_id":402,"wordpress_url":403,"date_gmt":404,"excerpt":405},{"display_name":121,"login":121,"email":122,"url":123},1168,"\u002F\u002F?p=1168","2015-02-11 13:46:43 +0000",{"type":8,"value":406},[407],[11,408,145],{},"\u002F2015-02-11-apex相关",{"title":140,"description":145},"_legacy\u002F2015\u002F2015-02-11-apex%e7%9b%b8%e5%85%b3",[413,414,415],"UE4","物理","APEX","4kaRlxLuoGhZbAs6po6nUVnEZ4T0qvvXWw-Tu2sFeec",{"id":418,"title":419,"body":420,"date":610,"description":424,"extension":115,"meta":611,"navigation":119,"path":620,"seo":621,"stem":622,"tags":623,"__hash__":624},"blogs\u002F_legacy\u002F2015\u002F2015-01-31-%e7%89%a9%e7%90%86%e6%a8%a1%e6%8b%9f.md","物理模拟",{"type":8,"value":421,"toc":598},[422,425,429,432,435,438,444,447,450,454,463,467,470,474,477,481,484,488,491,496,499,504,507,556,560,563,568,572,575,580,589,591,594],[11,423,424],{},"当前UE4使用PhysX3.3作为物理引擎。",[426,427,428],"h2",{"id":428},"碰撞体生成",[11,430,431],{},"碰撞体的生成方式有三种",[11,433,434],{},"第一种是，简单图形碰撞，提供球体、方体和胶囊三种形状的选择。碰撞成本最低，在很多情况下效果也很不错。",[11,436,437],{},"第二种是，基于离散定向多面体的生成方式。K-DOP的方式中，K的值越高的话，理论上碰撞的精度就会提高。但是同时的，碰撞的运算量耗费也会提升。官方的配图非常的形象：",[11,439,440],{},[64,441],{"alt":442,"src":443},"kdop_sizes.jpg","\u002Fwp-content\u002Fuploads\u002F2015\u002F01\u002Fkdop_sizes.jpg",[11,445,446],{},"第三种是凸面碰撞，用的是凸包方法。生成的碰撞图形非常的精确，对于模型不规则又要求精确碰撞的情形比较有效。不过相对的，碰撞成本也非常的高。",[11,448,449],{},"游戏预览中可以使用控制台来打开碰撞调试的开关，打开之后可以看到场景中各个物体的碰撞图形。可以方便进行碰撞的调试。",[150,451,453],{"id":452},"physics-constraint","Physics Constraint",[11,455,456,457,462],{},"物理约束提供物体之间的连接，根据属性的设置不同会有不同的效果。可以指定连接某个物体的组件，当和人物骨架连接时需要指定连接的骨骼名。连接可以设置选择或者拉伸极限。详细设定可以参照",[85,458,461],{"href":459,"rel":460},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FINT\u002FEngine\u002FPhysics\u002FConstraints\u002FConstraintsReference\u002Findex.html",[89],"文档","在引擎中测试。",[150,464,466],{"id":465},"physics-damping","Physics Damping",[11,468,469],{},"阻尼分为线性的和旋转的两种。30的线性阻尼足以使物体在初始化时抵挡9.8的重力而不下落。使得有力量作用的运动物体停止的最小线性阻尼是100。在没有旋转阻尼的情况下，旋转会永远进行下去。而100的旋转阻尼几乎会立刻停止旋转。在物理约束上也可以应用阻尼，使得运动超过约束设定的限度之后得以作出相应。应用于约束的阻尼的主要选项分别是刚度和阻尼。",[426,471,473],{"id":472},"vehicles","Vehicles",[11,475,476],{},"UE4文档和范例中提供了专门的汽车演示，游戏中需要要到时可以直接新建一个sample查看官方的实现即可。",[426,478,480],{"id":479},"physical-materials","Physical Materials",[11,482,483],{},"物理材质是面向物理模拟的材质。可以设定材质的摩擦系数、反弹恢复系数、密度等一些列基本的物理属性。",[150,485,487],{"id":486},"surface-type","Surface Type",[11,489,490],{},"表面类型，可以在代码中用来判别的表面类型枚举。",[11,492,493],{},[64,494],{"alt":66,"src":495},"\u002Fwp-content\u002Fuploads\u002F2015\u002F01\u002Fimage_thumb1.png",[11,497,498],{},"可以在项目属性中设置",[11,500,501],{},[64,502],{"alt":66,"src":503},"\u002Fwp-content\u002Fuploads\u002F2015\u002F01\u002Fimage_thumb2.png",[11,505,506],{},"或者在项目的Config\\DefaultEngine.ini中添加，如果不觉得麻烦的话：",[24,508,512],{"className":509,"code":510,"language":511,"meta":33,"style":33},"language-ini shiki shiki-themes github-light-high-contrast github-dark monokai","[PhysicalMaterial.SurfaceTypes]\nSurfaceType1=Glass\nSurfaceType2=Metal\nSurfaceType3=Wood\nSurfaceType4=Concrete\n...\nSurfaceType30=CollapsedStar\n","ini",[31,513,514,522,527,532,538,544,550],{"__ignoreMap":33},[515,516,519],"span",{"class":517,"line":518},"line",1,[515,520,521],{},"[PhysicalMaterial.SurfaceTypes]\n",[515,523,524],{"class":517,"line":111},[515,525,526],{},"SurfaceType1=Glass\n",[515,528,529],{"class":517,"line":112},[515,530,531],{},"SurfaceType2=Metal\n",[515,533,535],{"class":517,"line":534},4,[515,536,537],{},"SurfaceType3=Wood\n",[515,539,541],{"class":517,"line":540},5,[515,542,543],{},"SurfaceType4=Concrete\n",[515,545,547],{"class":517,"line":546},6,[515,548,549],{},"...\n",[515,551,553],{"class":517,"line":552},7,[515,554,555],{},"SurfaceType30=CollapsedStar\n",[150,557,559],{"id":558},"physics-sub-stepping","Physics Sub-Stepping",[11,561,562],{},"如果打开这个功能，物理模拟会在一个与游戏逻辑独立的线程中运行。这样在同一帧中就能够就行多次物理演算，其结果是，物理模拟会变得更加的精确和真实。但是对系统资源的消耗也会同步上升。",[11,564,565],{},[64,566],{"alt":66,"src":567},"\u002Fwp-content\u002Fuploads\u002F2015\u002F01\u002Fimage_thumb3.png",[150,569,571],{"id":570},"destructible-mesh","Destructible Mesh",[11,573,574],{},"可破坏的网格，在任意一个网格物体上点击右键即可创建可破坏的网格物体",[11,576,577],{},[64,578],{"alt":66,"src":579},"\u002Fwp-content\u002Fuploads\u002F2015\u002F01\u002Fimage_thumb4.png",[11,581,582,583,588],{},"破坏网格在接受到伤害事件后就会破碎，详细的文档在",[85,584,587],{"href":585,"rel":586},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FINT\u002FEngine\u002FPhysics\u002FDestructibles\u002FDestructibleProperties\u002Findex.html",[89],"这里","。想要做出复杂的破坏效果的话，需要用到NVIDIA的Apex。",[390,590],{},[11,592,593],{},"物理模拟部分大体上就是这些了，如果要做出华丽的效果还需要和粒子系统、音效进行配合。毕竟物理引擎只是对真实环境进行模拟，很多地方还是要依靠代码来进行的。",[595,596,597],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"title":33,"searchDepth":111,"depth":112,"links":599},[600,604,605],{"id":428,"depth":111,"text":428,"children":601},[602,603],{"id":452,"depth":112,"text":453},{"id":465,"depth":112,"text":466},{"id":472,"depth":111,"text":473},{"id":479,"depth":111,"text":480,"children":606},[607,608,609],{"id":486,"depth":112,"text":487},{"id":558,"depth":112,"text":559},{"id":570,"depth":112,"text":571},"2015-01-31",{"layout":117,"status":118,"published":119,"author":612,"author_login":121,"author_email":122,"author_url":123,"wordpress_id":613,"wordpress_url":614,"date_gmt":615,"excerpt":616},{"display_name":121,"login":121,"email":122,"url":123},1126,"\u002F\u002F?p=1126","2015-01-31 15:17:49 +0000",{"type":8,"value":617},[618],[11,619,424],{},"\u002F2015-01-31-物理模拟",{"title":419,"description":424},"_legacy\u002F2015\u002F2015-01-31-%e7%89%a9%e7%90%86%e6%a8%a1%e6%8b%9f",[413,414],"e84-jjijwAB6dEac9QTh7MW51RS5Wak5_-CBsED1OXI",{"id":626,"title":627,"body":628,"date":845,"description":632,"extension":115,"meta":846,"navigation":119,"path":855,"seo":856,"stem":857,"tags":858,"__hash__":860},"blogs\u002F_legacy\u002F2015\u002F2015-01-29-ue4%e5%8a%a8%e7%94%bb%e5%8a%9f%e8%83%bd%e6%95%b4%e7%90%86.md","UE4动画功能整理",{"type":8,"value":629,"toc":843},[630,633,636,641,644,649,652,657,665,670,673,678,687,692,701,706,709,715,720,723,728,731,736,739,744,749,752,757,762,765,771,774,780,787,792,795,801,804,810,813,818,821,835,838,840],[11,631,632],{},"工欲善其事必先利其器，最近一段开始了对UE4动画功能的系统性整理和学习。好在现在UE4的文档中文化已经开始了，有的文档是中文的，读起来也轻松很多。",[11,634,635],{},"当前使用的UE4版本为4.6.1。",[11,637,638],{},[160,639,640],{},"AnimBlueprints",[11,642,643],{},"动画蓝图分为通常的事件图表和专有的动画蓝图两种，其中动画蓝图主要负责通过读取到的变量进行相应的动画播放。事件图表则是负责更新数值和状态变量。",[11,645,646],{},[160,647,648],{},"Animation Composite",[11,650,651],{},"动画合成的作用是将多个动画进行组合变成新的合成动画，对于经常性的会进行序列播放的动画将其整合成一个进行管理和使用比较方便。",[11,653,654],{},[160,655,656],{},"Skeletal Controls",[11,658,659,660,664],{},"骨骼控制可以实现在动画播放的过程中精确到单个骨骼的播放控制，这样可以使得代码对动画的播放拥有更多的灵活性。操作相对简单，可以在使用到时参考",[85,661,461],{"href":662,"rel":663},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FCHN\u002FEngine\u002FAnimation\u002FNodeReference\u002FSkeletalControls\u002Findex.html",[89],"。",[11,666,667],{},[160,668,669],{},"Physics-Based Animation",[11,671,672],{},"基于物理的动画，可以对骨架中的部分骨骼开启物理模拟。不过要正常的打开物理模拟需要为物体指定物理资源。",[11,674,675],{},[160,676,677],{},"IK",[11,679,680,681,686],{},"IK的作用相信玩过相关游戏的童鞋都比较清楚，简单的来说就是用脚来控制大腿的感觉。通过脚、手的位置来逆向的沿着骨架调整动画。其作用是让动画变得更加真实，和骨骼控制相配合即可。需要用到时参照",[85,682,685],{"href":683,"rel":684},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FCHN\u002FEngine\u002FAnimation\u002FIKSetups\u002Findex.html",[89],"官方的示例","即可。",[11,688,689],{},[160,690,691],{},"Animation Retargeting",[11,693,694,695,700],{},"就是将动画共享给其他模型，减少动画制作的成本。主要分为两种形式，一种是在骨骼相同的模型之间使用相同的动画。另一种是通过Rig这个中间件使得骨骼结构不同的模型得以使用共享的动画。Rig的原理类似于对骨骼进行映射，相对的同骨骼架构本身就是可以共享动画的。这个部分相对简单，需要实际应用时参照",[85,696,699],{"href":697,"rel":698},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FINT\u002FEngine\u002FAnimation\u002FAnimHowTo\u002FRetargeting\u002Findex.html",[89],"官方文档","操作即可。",[11,702,703],{},[160,704,705],{},"Animation Notifications",[11,707,708],{},"动画通知可以使得我们在动画播放的某个阶段进行声音的播放、粒子系统的演出或者触发事件接口。",[11,710,711],{},[64,712],{"alt":713,"src":714},"PlayParticleEffectNotify.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FAnimation\u002FSequences\u002FNotifies\u002FPlayParticleEffectNotify.jpg",[11,716,717],{},[160,718,719],{},"Animation Curves",[11,721,722],{},"通过曲线来对变形动画动画的数值进行更改和控制。",[11,724,725],{},[160,726,727],{},"AnimMontage",[11,729,730],{},"Montage的主要功能是动画的管理和组织，通过将放置于slot中的一个或多个动画在sections中重组，可以让代码更好的对动画播放进行控制。同时Montage还提供了section播放时的分支点功能，分支点的功能和动画通知事件类似，区别之处在于分支点是同步的。因此分支点在时间上将会更加精确，同时也更加消耗系统资源。AnimMontage的一个重要作用之一，就是通过Slot的形式给予了代码层对AnimGraph的动画播放的控制权限。",[11,732,733],{},[160,734,735],{},"Root Motion",[11,737,738],{},"根骨骼的功能是为会产生移动的动画提供锁定。例如美术资源的动画是包含位移的情况，直接应用这个动画就会导致角色的碰撞检测实体和显示的物体之间的分离。官方的演示图片很直观的展示了这个问题：",[11,740,741],{},[64,742],{"alt":33,"src":743},"http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FAnimation\u002FRootMotion\u002FHammerSlam_NoRootMotion_Wall.gif",[11,745,746],{},[160,747,748],{},"Blend Space",[11,750,751],{},"动画混合可以将两个或多个动画混合起来，通过调整暴露出来的值来调节混合的程度。例如当速度小于100时播放行走动画，当速度大于300时播放奔跑动画。而在100~300之间则播放行走和奔跑动画的混合。而如果进一步的混合向左、向右和向后的行走和奔跑动画的话，就可以轻松的实现八方向行走动画了",[11,753,754],{},[64,755],{"alt":66,"src":756},"\u002Fwp-content\u002Fuploads\u002F2015\u002F01\u002Fimage_thumb.png",[11,758,759],{},[160,760,761],{},"Additive Animations",[11,763,764],{},"UE4可以在动画混合时将动画单独指定给某个骨骼以及其所有的子节点。这样以来就可以实现只给上半身播放特定的动画，而人物可以进行行走、下蹲或者站立不受其影响。其核心的部分是Layered blend per bone结点：",[11,766,767],{},[64,768],{"alt":769,"src":770},"Animations16.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FAnimation\u002FAnimHowTo\u002FAdditiveAnimations\u002FAnimations16.jpg",[11,772,773],{},"在其属性LayerSetup中进行指定：",[11,775,776],{},[64,777],{"alt":778,"src":779},"Animations18.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FAnimation\u002FAnimHowTo\u002FAdditiveAnimations\u002FAnimations18.jpg",[11,781,782,783,664],{},"就可以实现只将射击动画传递到上半身。详细的实现可参照",[85,784,461],{"href":785,"rel":786},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FINT\u002FEngine\u002FAnimation\u002FAnimHowTo\u002FAdditiveAnimations\u002Findex.html",[89],[11,788,789],{},[160,790,791],{},"Aim Offset",[11,793,794],{},"Aim Offset是用来实现多方向瞄准的动画混合。和其他的动画混合一样，需要提供面向各个方向瞄准的动画作为blend的基础。官方的示例中演示了如何从动画中通过删除帧数来生成这些动画的过程。",[11,796,797],{},[64,798],{"alt":799,"src":800},"AimOffset22.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FAnimation\u002FAnimHowTo\u002FAimOffset\u002FAimOffset22.jpg",[11,802,803],{},"得到上面那些动画之后，给每一个动画指定Additive Settings为正射的动画即可新建Aim Offset了。",[11,805,806],{},[64,807],{"alt":808,"src":809},"AimOffset30.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FAnimation\u002FAnimHowTo\u002FAimOffset\u002FAimOffset30.jpg",[11,811,812],{},"操作模式是blend通用的。",[11,814,815],{},[160,816,817],{},"Socket",[11,819,820],{},"通过在骨骼上附加Socket，可以使得额外的物体可以附加在骨骼上。",[11,822,823,827,831],{},[64,824],{"alt":825,"src":826},"AttachActorToActor.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FContent\u002FTypes\u002FSkeletalMeshes\u002FSockets\u002FAttachActorToActor.jpg",[64,828],{"alt":829,"src":830},"AttachActorToComponent.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FContent\u002FTypes\u002FSkeletalMeshes\u002FSockets\u002FAttachActorToComponent.jpg",[64,832],{"alt":833,"src":834},"AttachTo.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FContent\u002FTypes\u002FSkeletalMeshes\u002FSockets\u002FAttachTo.jpg",[11,836,837],{},"可以在游戏逻辑中通过蓝图进行附加操作，也可以直接在编辑其中进行附加以检测或改变模型的外观。",[390,839],{},[11,841,842],{},"总体而言，UE4提供的动画工具都是比较直观明了的。主要的概念也就上面总结的这些，有需要具体使用时再详细的参照文档进行实现。操作过两三遍之后应该就能熟练掌握了。",{"title":33,"searchDepth":111,"depth":112,"links":844},[],"2015-01-29",{"layout":117,"status":118,"published":119,"author":847,"author_login":121,"author_email":122,"author_url":123,"wordpress_id":848,"wordpress_url":849,"date_gmt":850,"excerpt":851},{"display_name":121,"login":121,"email":122,"url":123},1112,"\u002F\u002F?p=1112","2015-01-29 15:29:53 +0000",{"type":8,"value":852},[853],[11,854,632],{},"\u002F2015-01-29-ue4动画功能整理",{"title":627,"description":632},"_legacy\u002F2015\u002F2015-01-29-ue4%e5%8a%a8%e7%94%bb%e5%8a%9f%e8%83%bd%e6%95%b4%e7%90%86",[413,859],"动画","lCLJ6vtXPL1lcQosSeqM4r_dSDjfw8YRuZ9Rn4Yckt4",{"id":862,"title":863,"body":864,"date":903,"description":868,"extension":115,"meta":904,"navigation":119,"path":913,"seo":914,"stem":915,"tags":916,"__hash__":917},"blogs\u002F_legacy\u002F2014\u002F2014-12-24-%e8%93%9d%e5%9b%be%e5%87%bd%e6%95%b0%e5%ba%93%e5%b0%8f%e7%bb%93.md","蓝图函数库小结",{"type":8,"value":865,"toc":901},[866,869,872,875,881,884,890,893,898],[11,867,868],{},"蓝图函数库的功能非常强劲，如果在项目中使用的话有时能达到事半功倍的效果。",[11,870,871],{},"蓝图函数库，Blueprint Function Library。可以非常方便的将代码中的函数暴露给所有的蓝图使用，同时也提供了很好的代码复用性。完成的蓝图函数库可以非常轻易的在其他项目中使用或者共享给其他人。由于在函数库中定义的所有函数都能在其他的蓝图中访问，可以说是和单例模式的C++代码接合的天然素材。也可以防止为了定义一些泛用的函数而频繁的使用接口继承。",[11,873,874],{},"使用起来也是非常的简单明了。类似下面的代码就可以完成一个蓝图函数库了。",[24,876,879],{"className":877,"code":878,"language":29},[27],"#pragma once\n\n#include \"CoBpFuncLib.generated.h\"\n\n\u002F** Blueprintable并不是必须的 *\u002F\nUCLASS(Blueprintable) \nclass UCoBpFuncLib : public UBlueprintFunctionLibrary \n{ \n    GENERATED_UCLASS_BODY()\n\npublic: \n    \u002F** \u003C测试函数组 *\u002F \n    UFUNCTION(BlueprintCallable, Category = \"UCoBpFuncLib\") \n        static int32 GetHp();\n\n    UFUNCTION(BlueprintCallable, Category = \"UCoBpFuncLib\") \n        static void AddHp(int32 Val);\n};\n",[31,880,878],{"__ignoreMap":33},[11,882,883],{},"上面的是头文件，如果没有打算在蓝图中继承这个函数库的话可以选择去掉这个声明。",[24,885,888],{"className":886,"code":887,"language":29},[27],"#include \"CoBpFuncLib.h\" \n#include \"LogicMisc\u002FStateCenter.h\"\n\n\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F \n\u002F\u002F UCoBpFuncLib\n\nUCoBpFuncLib::UCoBpFuncLib(const class FObjectInitializer& PCIP) \n    : Super(PCIP) \n{\n\n}\n\nint32 UCoBpFuncLib::GetHp() \n{ \n    return StateCenter::sharedStateCenter()->miPlayerHp; \n}\n\nvoid UCoBpFuncLib::AddHp(int32 Val) \n{ \n    StateCenter::sharedStateCenter()->miPlayerHp += Val; \n}\n",[31,889,887],{"__ignoreMap":33},[11,891,892],{},"上面的代码实现通过访问存储有miPlayerHp的单例来进行HP的访问和调整。编译后运行，随便打开一个蓝图都能访问到这两个函数。注意，上面代码中并没有给出StateCenter的定义，如果有想要直接尝试的童鞋请去掉相关的代码。",[11,894,895],{},[64,896],{"alt":66,"src":897},"\u002Fwp-content\u002Fuploads\u002F2014\u002F12\u002Fimage_thumb2.png",[11,899,900],{},"有了蓝图函数库，我们在进行游戏逻辑设计时就又多了很多选择。",{"title":33,"searchDepth":111,"depth":112,"links":902},[],"2014-12-24",{"layout":117,"status":118,"published":119,"author":905,"author_login":121,"author_email":122,"author_url":123,"wordpress_id":906,"wordpress_url":907,"date_gmt":908,"excerpt":909},{"display_name":121,"login":121,"email":122,"url":123},1098,"\u002F\u002F?p=1098","2014-12-24 14:15:16 +0000",{"type":8,"value":910},[911],[11,912,868],{},"\u002F2014-12-24-蓝图函数库小结",{"title":863,"description":868},"_legacy\u002F2014\u002F2014-12-24-%e8%93%9d%e5%9b%be%e5%87%bd%e6%95%b0%e5%ba%93%e5%b0%8f%e7%bb%93",[413],"IEvLVqspmaFpcc3HuUS6l-ozw7OWbXd9NXUKeAJp-_Q",222,1788763184134]