[{"data":1,"prerenderedAt":914},["ShallowReactive",2],{"page-UE4-16":3,"page-count-UE4":913},[4,234,471,530,825],{"id":5,"title":6,"body":7,"date":210,"description":13,"extension":211,"meta":212,"navigation":215,"path":227,"seo":228,"stem":229,"tags":230,"__hash__":233},"blogs\u002F_legacy\u002F2015\u002F2015-01-31-%e7%89%a9%e7%90%86%e6%a8%a1%e6%8b%9f.md","物理模拟",{"type":8,"value":9,"toc":198},"minimark",[10,14,18,21,24,27,34,37,40,45,56,60,63,67,70,74,77,81,84,90,93,98,101,155,159,162,167,171,174,179,188,191,194],[11,12,13],"p",{},"当前UE4使用PhysX3.3作为物理引擎。",[15,16,17],"h2",{"id":17},"碰撞体生成",[11,19,20],{},"碰撞体的生成方式有三种",[11,22,23],{},"第一种是，简单图形碰撞，提供球体、方体和胶囊三种形状的选择。碰撞成本最低，在很多情况下效果也很不错。",[11,25,26],{},"第二种是，基于离散定向多面体的生成方式。K-DOP的方式中，K的值越高的话，理论上碰撞的精度就会提高。但是同时的，碰撞的运算量耗费也会提升。官方的配图非常的形象：",[11,28,29],{},[30,31],"img",{"alt":32,"src":33},"kdop_sizes.jpg","\u002Fwp-content\u002Fuploads\u002F2015\u002F01\u002Fkdop_sizes.jpg",[11,35,36],{},"第三种是凸面碰撞，用的是凸包方法。生成的碰撞图形非常的精确，对于模型不规则又要求精确碰撞的情形比较有效。不过相对的，碰撞成本也非常的高。",[11,38,39],{},"游戏预览中可以使用控制台来打开碰撞调试的开关，打开之后可以看到场景中各个物体的碰撞图形。可以方便进行碰撞的调试。",[41,42,44],"h3",{"id":43},"physics-constraint","Physics Constraint",[11,46,47,48,55],{},"物理约束提供物体之间的连接，根据属性的设置不同会有不同的效果。可以指定连接某个物体的组件，当和人物骨架连接时需要指定连接的骨骼名。连接可以设置选择或者拉伸极限。详细设定可以参照",[49,50,54],"a",{"href":51,"rel":52},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FINT\u002FEngine\u002FPhysics\u002FConstraints\u002FConstraintsReference\u002Findex.html",[53],"nofollow","文档","在引擎中测试。",[41,57,59],{"id":58},"physics-damping","Physics Damping",[11,61,62],{},"阻尼分为线性的和旋转的两种。30的线性阻尼足以使物体在初始化时抵挡9.8的重力而不下落。使得有力量作用的运动物体停止的最小线性阻尼是100。在没有旋转阻尼的情况下，旋转会永远进行下去。而100的旋转阻尼几乎会立刻停止旋转。在物理约束上也可以应用阻尼，使得运动超过约束设定的限度之后得以作出相应。应用于约束的阻尼的主要选项分别是刚度和阻尼。",[15,64,66],{"id":65},"vehicles","Vehicles",[11,68,69],{},"UE4文档和范例中提供了专门的汽车演示，游戏中需要要到时可以直接新建一个sample查看官方的实现即可。",[15,71,73],{"id":72},"physical-materials","Physical Materials",[11,75,76],{},"物理材质是面向物理模拟的材质。可以设定材质的摩擦系数、反弹恢复系数、密度等一些列基本的物理属性。",[41,78,80],{"id":79},"surface-type","Surface Type",[11,82,83],{},"表面类型，可以在代码中用来判别的表面类型枚举。",[11,85,86],{},[30,87],{"alt":88,"src":89},"image","\u002Fwp-content\u002Fuploads\u002F2015\u002F01\u002Fimage_thumb1.png",[11,91,92],{},"可以在项目属性中设置",[11,94,95],{},[30,96],{"alt":88,"src":97},"\u002Fwp-content\u002Fuploads\u002F2015\u002F01\u002Fimage_thumb2.png",[11,99,100],{},"或者在项目的Config\\DefaultEngine.ini中添加，如果不觉得麻烦的话：",[102,103,108],"pre",{"className":104,"code":105,"language":106,"meta":107,"style":107},"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","",[109,110,111,119,125,131,137,143,149],"code",{"__ignoreMap":107},[112,113,116],"span",{"class":114,"line":115},"line",1,[112,117,118],{},"[PhysicalMaterial.SurfaceTypes]\n",[112,120,122],{"class":114,"line":121},2,[112,123,124],{},"SurfaceType1=Glass\n",[112,126,128],{"class":114,"line":127},3,[112,129,130],{},"SurfaceType2=Metal\n",[112,132,134],{"class":114,"line":133},4,[112,135,136],{},"SurfaceType3=Wood\n",[112,138,140],{"class":114,"line":139},5,[112,141,142],{},"SurfaceType4=Concrete\n",[112,144,146],{"class":114,"line":145},6,[112,147,148],{},"...\n",[112,150,152],{"class":114,"line":151},7,[112,153,154],{},"SurfaceType30=CollapsedStar\n",[41,156,158],{"id":157},"physics-sub-stepping","Physics Sub-Stepping",[11,160,161],{},"如果打开这个功能，物理模拟会在一个与游戏逻辑独立的线程中运行。这样在同一帧中就能够就行多次物理演算，其结果是，物理模拟会变得更加的精确和真实。但是对系统资源的消耗也会同步上升。",[11,163,164],{},[30,165],{"alt":88,"src":166},"\u002Fwp-content\u002Fuploads\u002F2015\u002F01\u002Fimage_thumb3.png",[41,168,170],{"id":169},"destructible-mesh","Destructible Mesh",[11,172,173],{},"可破坏的网格，在任意一个网格物体上点击右键即可创建可破坏的网格物体",[11,175,176],{},[30,177],{"alt":88,"src":178},"\u002Fwp-content\u002Fuploads\u002F2015\u002F01\u002Fimage_thumb4.png",[11,180,181,182,187],{},"破坏网格在接受到伤害事件后就会破碎，详细的文档在",[49,183,186],{"href":184,"rel":185},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FINT\u002FEngine\u002FPhysics\u002FDestructibles\u002FDestructibleProperties\u002Findex.html",[53],"这里","。想要做出复杂的破坏效果的话，需要用到NVIDIA的Apex。",[189,190],"hr",{},[11,192,193],{},"物理模拟部分大体上就是这些了，如果要做出华丽的效果还需要和粒子系统、音效进行配合。毕竟物理引擎只是对真实环境进行模拟，很多地方还是要依靠代码来进行的。",[195,196,197],"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":107,"searchDepth":121,"depth":127,"links":199},[200,204,205],{"id":17,"depth":121,"text":17,"children":201},[202,203],{"id":43,"depth":127,"text":44},{"id":58,"depth":127,"text":59},{"id":65,"depth":121,"text":66},{"id":72,"depth":121,"text":73,"children":206},[207,208,209],{"id":79,"depth":127,"text":80},{"id":157,"depth":127,"text":158},{"id":169,"depth":127,"text":170},"2015-01-31","md",{"layout":213,"status":214,"published":215,"author":216,"author_login":217,"author_email":218,"author_url":219,"wordpress_id":220,"wordpress_url":221,"date_gmt":222,"excerpt":223},"post","publish",true,{"display_name":217,"login":217,"email":218,"url":219},"chaoshikari","chaoshikari@gmail.com","\u002F",1126,"\u002F\u002F?p=1126","2015-01-31 15:17:49 +0000",{"type":8,"value":224},[225],[11,226,13],{},"\u002F2015-01-31-物理模拟",{"title":6,"description":13},"_legacy\u002F2015\u002F2015-01-31-%e7%89%a9%e7%90%86%e6%a8%a1%e6%8b%9f",[231,232],"UE4","物理","e84-jjijwAB6dEac9QTh7MW51RS5Wak5_-CBsED1OXI",{"id":235,"title":236,"body":237,"date":455,"description":241,"extension":211,"meta":456,"navigation":215,"path":465,"seo":466,"stem":467,"tags":468,"__hash__":470},"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":238,"toc":453},[239,242,245,251,254,259,262,267,275,280,283,288,297,302,311,316,319,325,330,333,338,341,346,349,354,359,362,367,372,375,381,384,390,397,402,405,411,414,420,423,428,431,445,448,450],[11,240,241],{},"工欲善其事必先利其器，最近一段开始了对UE4动画功能的系统性整理和学习。好在现在UE4的文档中文化已经开始了，有的文档是中文的，读起来也轻松很多。",[11,243,244],{},"当前使用的UE4版本为4.6.1。",[11,246,247],{},[248,249,250],"strong",{},"AnimBlueprints",[11,252,253],{},"动画蓝图分为通常的事件图表和专有的动画蓝图两种，其中动画蓝图主要负责通过读取到的变量进行相应的动画播放。事件图表则是负责更新数值和状态变量。",[11,255,256],{},[248,257,258],{},"Animation Composite",[11,260,261],{},"动画合成的作用是将多个动画进行组合变成新的合成动画，对于经常性的会进行序列播放的动画将其整合成一个进行管理和使用比较方便。",[11,263,264],{},[248,265,266],{},"Skeletal Controls",[11,268,269,270,274],{},"骨骼控制可以实现在动画播放的过程中精确到单个骨骼的播放控制，这样可以使得代码对动画的播放拥有更多的灵活性。操作相对简单，可以在使用到时参考",[49,271,54],{"href":272,"rel":273},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FCHN\u002FEngine\u002FAnimation\u002FNodeReference\u002FSkeletalControls\u002Findex.html",[53],"。",[11,276,277],{},[248,278,279],{},"Physics-Based Animation",[11,281,282],{},"基于物理的动画，可以对骨架中的部分骨骼开启物理模拟。不过要正常的打开物理模拟需要为物体指定物理资源。",[11,284,285],{},[248,286,287],{},"IK",[11,289,290,291,296],{},"IK的作用相信玩过相关游戏的童鞋都比较清楚，简单的来说就是用脚来控制大腿的感觉。通过脚、手的位置来逆向的沿着骨架调整动画。其作用是让动画变得更加真实，和骨骼控制相配合即可。需要用到时参照",[49,292,295],{"href":293,"rel":294},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FCHN\u002FEngine\u002FAnimation\u002FIKSetups\u002Findex.html",[53],"官方的示例","即可。",[11,298,299],{},[248,300,301],{},"Animation Retargeting",[11,303,304,305,310],{},"就是将动画共享给其他模型，减少动画制作的成本。主要分为两种形式，一种是在骨骼相同的模型之间使用相同的动画。另一种是通过Rig这个中间件使得骨骼结构不同的模型得以使用共享的动画。Rig的原理类似于对骨骼进行映射，相对的同骨骼架构本身就是可以共享动画的。这个部分相对简单，需要实际应用时参照",[49,306,309],{"href":307,"rel":308},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FINT\u002FEngine\u002FAnimation\u002FAnimHowTo\u002FRetargeting\u002Findex.html",[53],"官方文档","操作即可。",[11,312,313],{},[248,314,315],{},"Animation Notifications",[11,317,318],{},"动画通知可以使得我们在动画播放的某个阶段进行声音的播放、粒子系统的演出或者触发事件接口。",[11,320,321],{},[30,322],{"alt":323,"src":324},"PlayParticleEffectNotify.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FAnimation\u002FSequences\u002FNotifies\u002FPlayParticleEffectNotify.jpg",[11,326,327],{},[248,328,329],{},"Animation Curves",[11,331,332],{},"通过曲线来对变形动画动画的数值进行更改和控制。",[11,334,335],{},[248,336,337],{},"AnimMontage",[11,339,340],{},"Montage的主要功能是动画的管理和组织，通过将放置于slot中的一个或多个动画在sections中重组，可以让代码更好的对动画播放进行控制。同时Montage还提供了section播放时的分支点功能，分支点的功能和动画通知事件类似，区别之处在于分支点是同步的。因此分支点在时间上将会更加精确，同时也更加消耗系统资源。AnimMontage的一个重要作用之一，就是通过Slot的形式给予了代码层对AnimGraph的动画播放的控制权限。",[11,342,343],{},[248,344,345],{},"Root Motion",[11,347,348],{},"根骨骼的功能是为会产生移动的动画提供锁定。例如美术资源的动画是包含位移的情况，直接应用这个动画就会导致角色的碰撞检测实体和显示的物体之间的分离。官方的演示图片很直观的展示了这个问题：",[11,350,351],{},[30,352],{"alt":107,"src":353},"http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FAnimation\u002FRootMotion\u002FHammerSlam_NoRootMotion_Wall.gif",[11,355,356],{},[248,357,358],{},"Blend Space",[11,360,361],{},"动画混合可以将两个或多个动画混合起来，通过调整暴露出来的值来调节混合的程度。例如当速度小于100时播放行走动画，当速度大于300时播放奔跑动画。而在100~300之间则播放行走和奔跑动画的混合。而如果进一步的混合向左、向右和向后的行走和奔跑动画的话，就可以轻松的实现八方向行走动画了",[11,363,364],{},[30,365],{"alt":88,"src":366},"\u002Fwp-content\u002Fuploads\u002F2015\u002F01\u002Fimage_thumb.png",[11,368,369],{},[248,370,371],{},"Additive Animations",[11,373,374],{},"UE4可以在动画混合时将动画单独指定给某个骨骼以及其所有的子节点。这样以来就可以实现只给上半身播放特定的动画，而人物可以进行行走、下蹲或者站立不受其影响。其核心的部分是Layered blend per bone结点：",[11,376,377],{},[30,378],{"alt":379,"src":380},"Animations16.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FAnimation\u002FAnimHowTo\u002FAdditiveAnimations\u002FAnimations16.jpg",[11,382,383],{},"在其属性LayerSetup中进行指定：",[11,385,386],{},[30,387],{"alt":388,"src":389},"Animations18.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FAnimation\u002FAnimHowTo\u002FAdditiveAnimations\u002FAnimations18.jpg",[11,391,392,393,274],{},"就可以实现只将射击动画传递到上半身。详细的实现可参照",[49,394,54],{"href":395,"rel":396},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FINT\u002FEngine\u002FAnimation\u002FAnimHowTo\u002FAdditiveAnimations\u002Findex.html",[53],[11,398,399],{},[248,400,401],{},"Aim Offset",[11,403,404],{},"Aim Offset是用来实现多方向瞄准的动画混合。和其他的动画混合一样，需要提供面向各个方向瞄准的动画作为blend的基础。官方的示例中演示了如何从动画中通过删除帧数来生成这些动画的过程。",[11,406,407],{},[30,408],{"alt":409,"src":410},"AimOffset22.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FAnimation\u002FAnimHowTo\u002FAimOffset\u002FAimOffset22.jpg",[11,412,413],{},"得到上面那些动画之后，给每一个动画指定Additive Settings为正射的动画即可新建Aim Offset了。",[11,415,416],{},[30,417],{"alt":418,"src":419},"AimOffset30.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FAnimation\u002FAnimHowTo\u002FAimOffset\u002FAimOffset30.jpg",[11,421,422],{},"操作模式是blend通用的。",[11,424,425],{},[248,426,427],{},"Socket",[11,429,430],{},"通过在骨骼上附加Socket，可以使得额外的物体可以附加在骨骼上。",[11,432,433,437,441],{},[30,434],{"alt":435,"src":436},"AttachActorToActor.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FContent\u002FTypes\u002FSkeletalMeshes\u002FSockets\u002FAttachActorToActor.jpg",[30,438],{"alt":439,"src":440},"AttachActorToComponent.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FContent\u002FTypes\u002FSkeletalMeshes\u002FSockets\u002FAttachActorToComponent.jpg",[30,442],{"alt":443,"src":444},"AttachTo.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FContent\u002FTypes\u002FSkeletalMeshes\u002FSockets\u002FAttachTo.jpg",[11,446,447],{},"可以在游戏逻辑中通过蓝图进行附加操作，也可以直接在编辑其中进行附加以检测或改变模型的外观。",[189,449],{},[11,451,452],{},"总体而言，UE4提供的动画工具都是比较直观明了的。主要的概念也就上面总结的这些，有需要具体使用时再详细的参照文档进行实现。操作过两三遍之后应该就能熟练掌握了。",{"title":107,"searchDepth":121,"depth":127,"links":454},[],"2015-01-29",{"layout":213,"status":214,"published":215,"author":457,"author_login":217,"author_email":218,"author_url":219,"wordpress_id":458,"wordpress_url":459,"date_gmt":460,"excerpt":461},{"display_name":217,"login":217,"email":218,"url":219},1112,"\u002F\u002F?p=1112","2015-01-29 15:29:53 +0000",{"type":8,"value":462},[463],[11,464,241],{},"\u002F2015-01-29-ue4动画功能整理",{"title":236,"description":241},"_legacy\u002F2015\u002F2015-01-29-ue4%e5%8a%a8%e7%94%bb%e5%8a%9f%e8%83%bd%e6%95%b4%e7%90%86",[231,469],"动画","lCLJ6vtXPL1lcQosSeqM4r_dSDjfw8YRuZ9Rn4Yckt4",{"id":472,"title":473,"body":474,"date":515,"description":478,"extension":211,"meta":516,"navigation":215,"path":525,"seo":526,"stem":527,"tags":528,"__hash__":529},"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":475,"toc":513},[476,479,482,485,493,496,502,505,510],[11,477,478],{},"蓝图函数库的功能非常强劲，如果在项目中使用的话有时能达到事半功倍的效果。",[11,480,481],{},"蓝图函数库，Blueprint Function Library。可以非常方便的将代码中的函数暴露给所有的蓝图使用，同时也提供了很好的代码复用性。完成的蓝图函数库可以非常轻易的在其他项目中使用或者共享给其他人。由于在函数库中定义的所有函数都能在其他的蓝图中访问，可以说是和单例模式的C++代码接合的天然素材。也可以防止为了定义一些泛用的函数而频繁的使用接口继承。",[11,483,484],{},"使用起来也是非常的简单明了。类似下面的代码就可以完成一个蓝图函数库了。",[102,486,491],{"className":487,"code":489,"language":490},[488],"language-text","#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","text",[109,492,489],{"__ignoreMap":107},[11,494,495],{},"上面的是头文件，如果没有打算在蓝图中继承这个函数库的话可以选择去掉这个声明。",[102,497,500],{"className":498,"code":499,"language":490},[488],"#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",[109,501,499],{"__ignoreMap":107},[11,503,504],{},"上面的代码实现通过访问存储有miPlayerHp的单例来进行HP的访问和调整。编译后运行，随便打开一个蓝图都能访问到这两个函数。注意，上面代码中并没有给出StateCenter的定义，如果有想要直接尝试的童鞋请去掉相关的代码。",[11,506,507],{},[30,508],{"alt":88,"src":509},"\u002Fwp-content\u002Fuploads\u002F2014\u002F12\u002Fimage_thumb2.png",[11,511,512],{},"有了蓝图函数库，我们在进行游戏逻辑设计时就又多了很多选择。",{"title":107,"searchDepth":121,"depth":127,"links":514},[],"2014-12-24",{"layout":213,"status":214,"published":215,"author":517,"author_login":217,"author_email":218,"author_url":219,"wordpress_id":518,"wordpress_url":519,"date_gmt":520,"excerpt":521},{"display_name":217,"login":217,"email":218,"url":219},1098,"\u002F\u002F?p=1098","2014-12-24 14:15:16 +0000",{"type":8,"value":522},[523],[11,524,478],{},"\u002F2014-12-24-蓝图函数库小结",{"title":473,"description":478},"_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",[231],"IEvLVqspmaFpcc3HuUS6l-ozw7OWbXd9NXUKeAJp-_Q",{"id":531,"title":532,"body":533,"date":809,"description":537,"extension":211,"meta":810,"navigation":215,"path":819,"seo":820,"stem":821,"tags":822,"__hash__":824},"blogs\u002F_legacy\u002F2014\u002F2014-12-23-ue4-event-overview.md","UE4事件相关总结",{"type":8,"value":534,"toc":804},[535,538,544,548,557,560,563,570,573,576,579,582,589,592,595,598,601,604,607,610,617,620,623,626,633,636,639,642,645,648,651,654,657,660,664,667,670,673,676,679,682,685,688,691,694,697,700,703,706,713,717,722,725,731,734,739,742,747,750,755,758,763,766,769,778,781,784,787,790,793,796,799,801],[11,536,537],{},"事件机制是实现游戏内逻辑的重要部分，在开始进行游戏逻辑的设计和实现之前，对UE4的事件机制进行理解是非常必要的。于是在这里对UE4的事件相关内容全部整理一下。",[11,539,540,541],{},"当前使用的UE版本是",[248,542,543],{},"4.6.0。",[41,545,547],{"id":546},"ue4的内置事件","① UE4的内置事件",[549,550,551],"ul",{},[552,553,554],"li",{},[248,555,556],{},"Event Level Reset",[11,558,559],{},"这个事件如其名称，只存在于Level Blueprint。只能在服务端运行。",[11,561,562],{},"事件发出在关卡被重置时，例如玩家死亡后地图没有重新载入而是重置的情况。",[549,564,565],{},[552,566,567],{},[248,568,569],{},"碰撞检测系列",[11,571,572],{},"Event Actor Begin Overlap",[11,574,575],{},"Event Actor End Overlap",[11,577,578],{},"Event Hit",[11,580,581],{},"Overlap事件仅在两个物体的碰撞属性为Overlap且勾选了Generate Overlap Events时才会发生。而Hit事件则必须有Simulation Generates Hit Events的设置才会发出。碰撞检测事件是游戏逻辑的一个重要的触发点。",[549,583,584],{},[552,585,586],{},[248,587,588],{},"伤害事件",[11,590,591],{},"Event Any Damage",[11,593,594],{},"由环境等因素造成的附加伤害，例如持续性伤害的沼泽地。",[11,596,597],{},"Event Point Damage",[11,599,600],{},"点伤害，是由抛物体引起的伤害。通常用于子弹的伤害以及某些近战武器。",[11,602,603],{},"Event Radial Damage",[11,605,606],{},"辐射状伤害，通常应用于爆炸伤害或其他的间接伤害类型。",[11,608,609],{},"伤害事件只在服务器端发起。",[549,611,612],{},[552,613,614],{},[248,615,616],{},"交互事件",[11,618,619],{},"Event Actor Begin Cursor Over",[11,621,622],{},"Event Actor End Cursor Over",[11,624,625],{},"如其名字所描述的鼠标和物体的交互事件。",[549,627,628],{},[552,629,630],{},[248,631,632],{},"逻辑事件",[11,634,635],{},"Event Begin Play",[11,637,638],{},"Event End Play",[11,640,641],{},"比较经常用到的两个事件，在Actor于世界中初始化和被消去时触发。",[11,643,644],{},"Event Destroyed",[11,646,647],{},"当Actor被销毁时触发，这个事件已经被官方标记了，功能合并到了End Play中。",[11,649,650],{},"Event Tick",[11,652,653],{},"时钟事件，每一帧都会触发。",[11,655,656],{},"Event Receive Draw HUD",[11,658,659],{},"只有在Hud类中才有的事件，可以用于Hud的逻辑和显示设计。",[41,661,663],{"id":662},"碰撞检测相关","② 碰撞检测相关",[11,665,666],{},"碰撞的逻辑和射线追踪使用的逻辑是大体相同的。唯一不同的是追踪扫描线本身也可以拥有响应属性，使得物体可以选择是否阻挡或者忽略这条扫描线。",[11,668,669],{},"一些比较重要的属性包括：",[11,671,672],{},"CCD",[11,674,675],{},"连续碰撞检测。提高碰撞检测的精度，用于防止穿墙和防止二次碰撞。通常在高速移动物体例如子弹的模拟中会用到。",[11,677,678],{},"Always Create Physics State",[11,680,681],{},"在世界载入时而不是碰撞发生时创建物理属性，可以防止游戏运行中突发的大量物理属性初始化引起的卡顿，代价是载入时间的变长。",[11,683,684],{},"Check Async Scene on Move",[11,686,687],{},"同时检查同步物理空间和异步物理空间，异步物理空间主要被用于可破坏物体被破坏后的模拟。",[11,689,690],{},"Trace Complex on Move",[11,692,693],{},"如果使用复杂追踪，则将采用多边形级的模拟。通常采用简单模拟，碰撞图形可以在编辑器中定义。",[11,695,696],{},"碰撞属性的优先如下：",[11,698,699],{},"Ignore>Overlap>Block",[11,701,702],{},"只有在两个参与模拟的物体具有相同的属性时才会触发相应的逻辑，否则采用优先级高的碰撞逻辑。例如两个物体相互的碰撞设置为overlap和block，则会被判定为overlap。",[11,704,705],{},"对于场景中的高速移动物体，即时设定了Block有时也会触发Overlap事件，所以并不建议同时使用这两种类型的事件。",[11,707,708,709,274],{},"更多的实例可以参考",[49,710,309],{"href":711,"rel":712},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FCHN\u002FEngine\u002FPhysics\u002FCollision\u002Findex.html",[53],[41,714,716],{"id":715},"蓝图通信相关","③ 蓝图通信相关",[11,718,719],{},[248,720,721],{},"自定义事件",[11,723,724],{},"UE4允许在蓝图中自定义事件。事件的定义只在该蓝图内部有效。",[11,726,727],{},[30,728],{"alt":729,"src":730},"add_custom_event.png","http:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002Fimages\u002FEngine\u002FBlueprints\u002FUserGuide\u002FEvents\u002FCustom\u002Fadd_custom_event.jpg",[11,732,733],{},"自定义事件的使用方法基本和自定义函数相同。",[11,735,736],{},[248,737,738],{},"事件调度器",[11,740,741],{},"事件调度器会在被调用后触发所有绑定在其上的事件。",[11,743,744],{},[30,745],{"alt":88,"src":746},"\u002Fwp-content\u002Fuploads\u002F2014\u002F12\u002Fimage_thumb.png",[11,748,749],{},"可以绑定、解绑、解绑所有事件，同时如果定义的事件不绑定的话那么就不会被调度器调用。",[11,751,752],{},[248,753,754],{},"蓝图接口",[11,756,757],{},"蓝图接口可以使得不同的物体类型提供相同的功能但是拥有各自的实现，和C++的接口功能类似。在蓝图中定义时没什么太大的问题，唯一需要留意的是对于没有输出的函数会被自动在转化为事件。如下图：",[11,759,760],{},[30,761],{"alt":88,"src":762},"\u002Fwp-content\u002Fuploads\u002F2014\u002F12\u002Fimage_thumb1.png",[11,764,765],{},"如果要在C++中使用，则需要参考文档进行。",[11,767,768],{},"MinimalAPI",[11,770,771,772,777],{},"尽量的不向外暴露内部的函数。在这个情况下，可以通过为函数指定RequiredAPI来将其暴露出去。虽然官方是这么说明的，但是RequiredAPI的使用方式不明，直接使用会提示错误，有可能是包含问题。",[49,773,776],{"href":774,"rel":775},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FINT\u002FProgramming\u002FUnrealArchitecture\u002FReference\u002FFunctions\u002FSpecifiers\u002Findex.html",[53],"Function Specifiers","中亦没有说明，手上也没UE4的源码，由于不太可能用到这个设定所以不再研究。",[11,779,780],{},"DependsOn",[11,782,783],{},"声明依赖关系。当接口要使用到别的类中的定义时需要用到。",[11,785,786],{},"DependsOn=(ClassName, Classname, ...)",[11,788,789],{},"CannotImplementInterfaceInBlueprint",[11,791,792],{},"蓝图不能实现的接口，该接口只能在C++中实现。使用了这个指定之后，不能在接口中将函数指定为BlueprintImplementableEvent。相对的，在没有指定亦即可以被蓝图实现的接口中不能使用BlueprintCallable。",[11,794,795],{},"UINTERFACE(…, meta = (CannotImplementInterfaceInBlueprint))",[11,797,798],{},"需要注意的是，定义的接口不能暴露属性同时如果不使用CannotImplementInterfaceInBlueprint的话也无法将函数暴露给蓝图。功能上真的就只是一个单纯的接口。",[189,800],{},[11,802,803],{},"以上就是对事件相关部分的整理。",{"title":107,"searchDepth":121,"depth":127,"links":805},[806,807,808],{"id":546,"depth":127,"text":547},{"id":662,"depth":127,"text":663},{"id":715,"depth":127,"text":716},"2014-12-23",{"layout":213,"status":214,"published":215,"author":811,"author_login":217,"author_email":218,"author_url":219,"wordpress_id":812,"wordpress_url":813,"date_gmt":814,"excerpt":815},{"display_name":217,"login":217,"email":218,"url":219},1090,"\u002F\u002F?p=1090","2014-12-23 03:55:19 +0000",{"type":8,"value":816},[817],[11,818,537],{},"\u002F2014-12-23-ue4-event-overview",{"title":532,"description":537},"_legacy\u002F2014\u002F2014-12-23-ue4-event-overview",[231,823],"事件","QNqf2up7GIKwITeZx0gkYQrdMv-h2rVnfImH6eP3hsY",{"id":826,"title":827,"body":828,"date":897,"description":832,"extension":211,"meta":898,"navigation":215,"path":907,"seo":908,"stem":909,"tags":910,"__hash__":912},"blogs\u002F_legacy\u002F2014\u002F2014-11-30-umg%e5%9c%a84-6-0%e7%89%88%e6%9c%ac%e4%b8%ad%e7%9a%84%e5%8d%87%e7%ba%a7%e5%8f%98%e5%8a%a8.md","UMG在4.6.0版本中的升级变动",{"type":8,"value":829,"toc":895},[830,833,836,842,845,850,853,858,863,866,871,876,879,884,887,892],[11,831,832],{},"UE4目前处在一个非常活跃的开发阶段，在升级到4.6.0版本之后。UMG功能已经离开了实验性功能模块，同时这个版本已经支持中文语言了。",[11,834,835],{},"才过了1个多月就有这么大的变动，就只能从断掉的地方从新开始了。好在UMG本身从上一次到现在这个版本并没有什么大的变动。对原有的代码进行检查，目前能找到的变动有下面这些。",[837,838,839],"ol",{},[552,840,841],{},"按钮的绑定函数改为了事件绑定",[11,843,844],{},"原有的绑定函数的形式不再有效，所以要在蓝图中作出相应的修改。",[11,846,847],{},[30,848],{"alt":88,"src":849},"\u002Fwp-content\u002Fuploads\u002F2014\u002F11\u002Fimage_thumb.png",[11,851,852],{},"修改为了事件模式之后，按钮和响应函数之间的关系变得更加直观了。",[11,854,855],{},[30,856],{"alt":88,"src":857},"\u002Fwp-content\u002Fuploads\u002F2014\u002F11\u002Fimage_thumb1.png",[837,859,860],{"start":121},[552,861,862],{},"Border的颜色属性变动",[11,864,865],{},"Border现在默认是白色不透明了，如果原来有使用Border进行布局的话升级之后就会看到界面一片白了。要使用透明效果就必须对颜色修改：",[11,867,868],{},[30,869],{"alt":88,"src":870},"\u002Fwp-content\u002Fuploads\u002F2014\u002F11\u002Fimage_thumb2.png",[837,872,873],{"start":127},[552,874,875],{},"Add to Viewport 函数变更",[11,877,878],{},"AddtoViewPort函数中原本的Modal和Show Cursor参数已经没有了。要实现这两个功能，就必须通过PlayerController进行控制。模态的控制如下：",[11,880,881],{},[30,882],{"alt":88,"src":883},"\u002Fwp-content\u002Fuploads\u002F2014\u002F11\u002Fimage_thumb3.png",[11,885,886],{},"模态相关的话是一个Game和UI的控制权分配问题，通过下面的这组函数进行控制：",[11,888,889],{},[30,890],{"alt":88,"src":891},"\u002Fwp-content\u002Fuploads\u002F2014\u002F11\u002Fimage_thumb4.png",[11,893,894],{},"对上面的改动进行相应的修正之后，原本的代码就可以在新的版本中正常的工作 了。",{"title":107,"searchDepth":121,"depth":127,"links":896},[],"2014-11-30",{"layout":213,"status":214,"published":215,"author":899,"author_login":217,"author_email":218,"author_url":219,"wordpress_id":900,"wordpress_url":901,"date_gmt":902,"excerpt":903},{"display_name":217,"login":217,"email":218,"url":219},1079,"\u002F\u002F?p=1079","2014-11-30 05:08:11 +0000",{"type":8,"value":904},[905],[11,906,832],{},"\u002F2014-11-30-umg在4-6-0版本中的升级变动",{"title":827,"description":832},"_legacy\u002F2014\u002F2014-11-30-umg%e5%9c%a84-6-0%e7%89%88%e6%9c%ac%e4%b8%ad%e7%9a%84%e5%8d%87%e7%ba%a7%e5%8f%98%e5%8a%a8",[231,911],"UMG","211uQ_hHtqukg9a475OoGFpORkJgoSXNDZZUDjoLQh0",85,1788763178453]