[{"data":1,"prerenderedAt":154},["ShallowReactive",2],{"\u002F2015-08-18-hello-slate":3},{"id":4,"title":5,"body":6,"date":130,"description":12,"extension":131,"meta":132,"navigation":135,"path":147,"seo":148,"stem":149,"tags":150,"__hash__":153},"blogs\u002F_legacy\u002F2015\u002F2015-08-18-hello-slate.md","Hello Slate",{"type":7,"value":8,"toc":122},"minimark",[9,13,16,19,30,34,37,48,51,55,58,67,70,76,79,85,88,92,95,98,101,107,110,116,119],[10,11,12],"p",{},"UE4中通常的游戏内逻辑使用UMG就可以了，当需要一些独特的功能时就会需要用到Slate。",[10,14,15],{},"当前UE4版本4.8.3。",[10,17,18],{},"Slate是UE4的用户界面系统，UE4编辑器的大部分界面都是由Slate构建的。同时，在编辑器中使用的UMG也是在Slate的基础上封装的。",[10,20,21,22,29],{},"本文参照官方社区文档",[23,24,28],"a",{"href":25,"rel":26},"https:\u002F\u002Fwiki.unrealengine.com\u002FSlate,_Hello",[27],"nofollow","Slate, Hello","完成。",[31,32,33],"h2",{"id":33},"准备工作",[10,35,36],{},"要使用Slate，第一步是将其API开放到项目。在项目对应的Build.cs中将下面的代码的注释去掉即可",[38,39,44],"pre",{"className":40,"code":42,"language":43},[41],"language-text","\u002F\u002F Uncomment if you are using Slate UI\n\nPrivateDependencyModuleNames.AddRange(new string[] { \"Slate\", \"SlateCore\" });\n","text",[45,46,42],"code",{"__ignoreMap":47},"",[10,49,50],{},"根据UE4版本的不同如果没有这行的直接加上就好了。",[31,52,54],{"id":53},"slatewidget","SlateWidget",[10,56,57],{},"创建用于显示文字的Slate控件。",[10,59,60,61,66],{},"Slate控件的一些特殊的宏和界面定义方式的详情可以参考官方的",[23,62,65],{"href":63,"rel":64},"https:\u002F\u002Fdocs.unrealengine.com\u002Flatest\u002FCHN\u002FProgramming\u002FSlate\u002FOverview\u002Findex.html",[27],"Slate概述","。",[10,68,69],{},"StandardSlateWidget.h",[38,71,74],{"className":72,"code":73,"language":43},[41],"#pragma once\n#include \"Test_mp.h\" \u002F* \u003C项目头文件 *\u002F\n\nclass SStandardSlateWidget: public SCompoundWidget\n{\nSLATE_BEGIN_ARGS(SStandardSlateWidget){}\n\n\u002F*\u003C参照下面的OwnerHUD的声明 *\u002F\nSLATE_ARGUMENT(TWeakObjectPtr\u003Cclass AHUD>,OwnerHUD)\n\n\nSLATE_END_ARGS()\n\npublic:\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\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\u002F\u002F\u002F\u003C每一个控件都必须要有这个函数\n\u002F\u002F\u002F\u002F\u002F\u003C构建控件及其子控件\nvoid Construct(const FArguments& InArgs);\nprivate:\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\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\u002F\u002F\u002F\u003C指向控件的持有者Hud\n\u002F\u002F\u002F\u002F\u002F\u003C使用弱引用持有HUD的指针，因为HUD是使用强引用来持有Widget的。\n\u002F\u002F\u002F\u002F\u002F\u003C如果双方都为强引用的话将会导致解构时形成循环引用并引发内存泄露\nTWeakObjectPtr\u003Cclass AHUD> OwnerHUD;\n\n};\n",[45,75,73],{"__ignoreMap":47},[10,77,78],{},"StandardSlateWidget.cpp",[38,80,83],{"className":81,"code":82,"language":43},[41],"#include \"Test_mp.h\"\n#include \"Plugin\u002FStandardSlateWidget.h\"\n \nvoid SStandardSlateWidget::Construct(const FArguments& InArgs)\n{\n    OwnerHUD = InArgs._OwnerHUD;\n \n    ChildSlot\n        .VAlign(VAlign_Fill)\n        .HAlign(HAlign_Fill)\n        [\n            SNew(SOverlay)\n            + SOverlay::Slot()\n            .VAlign(VAlign_Top)\n            .HAlign(HAlign_Center)\n             [\n                 SNew(STextBlock)\n                 .ShadowColorAndOpacity(FLinearColor::Black)\n                 .ColorAndOpacity(FLinearColor::Red)\n                 .ShadowOffset(FIntPoint(-5, 5))\n                 .Font(FSlateFontInfo(\"Veranda\", 24))\n                 .Text(FText::FromString(\"Hello, Slate!\"))\n             ]\n        ];\n \n}\n",[45,84,82],{"__ignoreMap":47},[10,86,87],{},"在这里使用OwnerHUD并不是必须的，主要的作用是作为参数传递的示范。",[31,89,91],{"id":90},"hud","HUD",[10,93,94],{},"通过自定义一个HUD用于Slate控件的展示。添加HUD代码没有什么特殊的地方。",[10,96,97],{},"添加好之后直接在BeginPlay中将Widget输出到屏幕即可。",[10,99,100],{},"StandardHud.h",[38,102,105],{"className":103,"code":104,"language":43},[41],"#pragma once\n#include \"GameFramework\u002FHUD.h\"\n#include \"StandardHUD.generated.h\"\n \nclass SStandardSlateWidget;\n \nUCLASS()\nclass AStandardHUD : public AHUD\n{\n    GENERATED_BODY()\n \npublic:\n    AStandardHUD();\n    TSharedPtr\u003CSStandardSlateWidget> myUIWidget;\n \n    void BeginPlay();\n};\n\n",[45,106,104],{"__ignoreMap":47},[10,108,109],{},"StandardHud.cpp",[38,111,114],{"className":112,"code":113,"language":43},[41],"#pragma once\n \u002F\u002F Fill out your copyright notice in the Description page of Project Settings.   \n #include \"Test_mp.h\" \n #include \"Plugin\u002FStandardSlateWidget.h\" \n #include \"Plugin\u002FStandardHUD.h\"   \n \nAStandardHUD::AStandardHUD() \n{   \n\n}\n\nvoid AStandardHUD::BeginPlay() \n{     \n    SAssignNew(myUIWidget, SStandardSlateWidget).OwnerHUD(this);       \n    if (GEngine->IsValidLowLevel())     \n    {         \n        GEngine->GameViewport->AddViewportWidgetContent(SNew(SWeakWidget).PossiblyNullContent(myUIWidget.ToSharedRef()));     \n    }       \n    if (myUIWidget.IsValid())     \n    {         \n        myUIWidget->SetVisibility(EVisibility::Visible);     \n    } \n}\n\n",[45,115,113],{"__ignoreMap":47},[31,117,118],{"id":118},"最终结果",[10,120,121],{},"原始的教程中还有自定义GameMode的部分，在这里就不执行了。直接在编辑器中将HUD指定为刚刚定义的StandardHud即可。\n指定完成后，点击运行即可在屏幕上方看到“Hello, Slate!”的文字输出了。",{"title":47,"searchDepth":123,"depth":124,"links":125},2,3,[126,127,128,129],{"id":33,"depth":123,"text":33},{"id":53,"depth":123,"text":54},{"id":90,"depth":123,"text":91},{"id":118,"depth":123,"text":118},"2015-08-18","md",{"layout":133,"status":134,"published":135,"author":136,"author_login":137,"author_email":138,"author_url":139,"wordpress_id":140,"wordpress_url":141,"date_gmt":142,"excerpt":143},"post","publish",true,{"display_name":137,"login":137,"email":138,"url":139},"chaoshikari","chaoshikari@gmail.com","\u002F",1472,"\u002F\u002F?p=1472","2015-08-18 11:56:34 +0000",{"type":7,"value":144},[145],[10,146,12],{},"\u002F2015-08-18-hello-slate",{"title":5,"description":12},"_legacy\u002F2015\u002F2015-08-18-hello-slate",[151,152],"UE4","Slate","nMQL2MFSDju9LkcCXygpyjn248xCbtlgOGdlwP5Xquk",1788763180451]