{"id":3033,"date":"2021-01-02T13:45:58","date_gmt":"2021-01-02T05:45:58","guid":{"rendered":"http:\/\/blog.coolcoding.cn\/?p=3033"},"modified":"2021-01-02T19:44:46","modified_gmt":"2021-01-02T11:44:46","slug":"creating-c-enums-that-can-be-used-in-blueprint","status":"publish","type":"post","link":"https:\/\/blog.coolcoding.cn\/?p=3033","title":{"rendered":"Creating C++ enums that can be used in Blueprint"},"content":{"rendered":"\n<p>Enums are commonly used in C++ as flags or inputs to switch statements. However, what if you want to pass an\u00a0enum\u00a0value to or from C++ from a Blueprint? Alternatively, if you want to use a\u00a0switch\u00a0statement in Blueprint that uses an\u00a0enum\u00a0from C++, how do you let the Blueprint editor know that your\u00a0enum\u00a0should be accessible within the editor? This recipe shows you how to make enums visible in Blueprint.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How to do it&#8230;<\/h1>\n\n\n\n<ol><li>Create a new&nbsp;StaticMeshActor&nbsp;class called&nbsp;Tree&nbsp;using the editor.<\/li><li>Insert the following code above the class declaration:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#pragma once<br><br>#include \"CoreMinimal.h\"<br>#include \"Engine\/StaticMeshActor.h\"<br>#include \"Tree.generated.h\"<br><br><strong>UENUM(BlueprintType)<\/strong><br><strong>enum TreeType<\/strong><br><strong>{<\/strong><br><strong>    Tree_Poplar,<\/strong><br><strong>    Tree_Spruce,<\/strong><br><strong>    Tree_Eucalyptus,<\/strong><br><strong>    Tree_Redwood<\/strong><br><strong>};<\/strong><br><br>UCLASS()<br>class CHAPTER_09_API ATree : public AStaticMeshActor<br>{<\/pre>\n\n\n\n<ol><li>Add the following to&nbsp;the&nbsp;Tree&nbsp;class:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">UCLASS()<br>class CHAPTER_09_API ATree : public AStaticMeshActor<br>{<br>    GENERATED_BODY()<br>    <br><strong>public:<\/strong><br><strong>    \/\/ Sets default values for this actor's properties<\/strong><br><strong>    ATree();<\/strong><br><br><strong>    UPROPERTY(BlueprintReadWrite)<\/strong><br><strong>    TEnumAsByte&lt;TreeType&gt; Type;<\/strong><br>};<\/pre>\n\n\n\n<ol><li>Add the following to the&nbsp;Tree&nbsp;constructor:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#include \"Tree.h\"<br><br><strong>#include \"ConstructorHelpers.h\"<\/strong><br><br><strong>\/\/ Sets default values<\/strong><br><strong>ATree::ATree()<\/strong><br><strong>{<\/strong><br><strong>    \/\/ Set this actor to call Tick() every frame. You can turn<br>    \/\/ this off to improve performance if you don't need it.<\/strong><br><strong>    PrimaryActorTick.bCanEverTick = true;<\/strong><br><br><strong>    auto MeshAsset = ConstructorHelpers::FObjectFinder&lt;UStaticMesh&gt;<br>    (TEXT(\"StaticMesh'\/Engine\/BasicShapes\/Cylinder.Cylinder'\"));<\/strong><br><br><strong>    UStaticMeshComponent * SM = GetStaticMeshComponent();<\/strong><br><br><strong>    if (SM != nullptr)<\/strong><br><strong>    {<\/strong><br><strong>        if (MeshAsset.Object != nullptr)<\/strong><br><strong>        {<\/strong><br><strong>            SM-&gt;SetStaticMesh(MeshAsset.Object);<\/strong><br><strong>            SM-&gt;SetGenerateOverlapEvents(true);<\/strong><br><strong>        }<\/strong><br><strong>        SM-&gt;SetMobility(EComponentMobility::Movable);<\/strong><br><strong>    }<\/strong><br><strong>}<\/strong><br><br><\/pre>\n\n\n\n<ol><li>Return to the Unreal Editor and compile your code.<\/li><li>Create a new Blueprint class called&nbsp;MyTree, based on&nbsp;Tree, by right-clicking on the Tree object and selecting&nbsp;Create Blueprint class based on Tree. Once the menu comes up, click on the&nbsp;Create Blueprint Class&nbsp;button.<\/li><li>Inside the blueprint editor for&nbsp;MyTree, click on the&nbsp;Construction Script&nbsp;tab.<\/li><li>Right-click in the empty window and type&nbsp;treetype. There is a&nbsp;Get number of entries in TreeType&nbsp;node:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/8a5f09a0-43b0-4d0e-852f-f28683ca8a5c.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>Where and then connect its&nbsp;Return value&nbsp;output pin to the&nbsp;Max&nbsp;property of a new&nbsp;Random Integer&nbsp;node:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/aa62d8f0-eac4-4978-903c-33be135516cc.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>Connect the&nbsp;Return Value&nbsp;output of the random integer to a&nbsp;ToByte (Integer)&nbsp;node:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/learning.oreilly.com\/library\/view\/unreal-engine-4x\/9781789809503\/assets\/e638984a-344d-4bcb-9d28-dc2bbdcfe361.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>In the&nbsp;Variables&nbsp;section of the&nbsp;My Blueprint&nbsp;panel, click on the&nbsp;+&nbsp;button. From there, go to the&nbsp;Details&nbsp;tab and set the&nbsp;Variable Type&nbsp;to&nbsp;Tree Type. Afterward, set the&nbsp;Variable Name&nbsp;to&nbsp;RandomTree:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/43c68378-cfe8-4485-8e5f-1a654392ffb4.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>Drag the&nbsp;RandomTree&nbsp;variable into the graph and select&nbsp;Set Random Tree&nbsp;when you see a small context menu appear.<\/li><li>Connect the&nbsp;Return Value&nbsp;output of the&nbsp;ToByte&nbsp;node to the input of the&nbsp;SET Type&nbsp;node. You&#8217;ll see an extra conversion node automatically appear.<\/li><li>Lastly, connect the execution pin of&nbsp;Construction Script&nbsp;to the&nbsp;SET Type&nbsp;node&#8217;s execution pin. Your Blueprint should look as follows:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/17bd491f-612b-4926-9485-76609cd128da.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>To verify that the blueprint is correctly functioning and randomly assigning a type to our tree, we are going to add some nodes to the Event Graph.<\/li><li>Place a&nbsp;Print String&nbsp;node after the&nbsp;Event BeginPlay&nbsp;event node:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/155d1518-6a95-478b-89db-c434fbb4a3ea.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>Place a&nbsp;Format Text&nbsp;node and connect its output to the input of the&nbsp;Print String&nbsp;node. A conversion node will be added for you:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/825ac029-d5de-496c-87fe-2f17a6ebcd72.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>Inside the&nbsp;Format Text&nbsp;node, add&nbsp;My Type is {0}!&nbsp;to the&nbsp;Format&nbsp;text box:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/d1b858b3-6f18-4cba-a7c8-8d54f5137af8.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>You should see that it adds a new parameter,&nbsp;0, which we can now set.<\/p>\n\n\n\n<ol><li>Drag the&nbsp;RandomTree&nbsp;variable from the&nbsp;Variables&nbsp;section of the&nbsp;My Blueprint&nbsp;window into the graph and select&nbsp;Get&nbsp;from the menu:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/76fab5b0-2f7d-4c0e-a8d4-0ed39f776c22.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>Add an&nbsp;Enum to Name&nbsp;node to the&nbsp;Type&nbsp;output pin:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/d92b7665-d8ed-4b79-b03a-ad3b56eb5f9f.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>The&nbsp;Format Text&nbsp;node will not use a Name, so we will need to convert it into Text.&nbsp;Add a&nbsp;ToText (name)&nbsp;node to&nbsp;the&nbsp;Enum to Name&nbsp;output pin.<\/li><li>Connect the&nbsp;Return Value&nbsp;output of the&nbsp;ToText (name)&nbsp;node to the&nbsp;0&nbsp;input pin on the&nbsp;Format Text&nbsp;node. Your Event Graph should now look as follows:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/f79e30f9-f9b9-46cf-8784-a4a7e93d8c40.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>The completed Blueprint graph<\/p>\n\n\n\n<ol><li>Compile your Blueprint and then return to the Unreal Editor.<\/li><li>Drag a few copies of your Blueprint into the level and hit&nbsp;Play. You should see a number of trees printing information regarding their type, verifying that types are being randomly assigned by the Blueprint code that we created:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/learning.oreilly.com\/library\/view\/unreal-engine-4x\/9781789809503\/assets\/b1534f7b-f726-4577-92d5-380d72ddacf2.png\" alt=\"\"\/><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\">How it works&#8230;<\/h1>\n\n\n\n<p>As usual, we use&nbsp;StaticMeshActor&nbsp;as the base class for our&nbsp;Actor&nbsp;so that we can easily give it a visual representation in the level.<\/p>\n\n\n\n<p>Enumerated types are exposed to the reflection system using the&nbsp;UENUM&nbsp;macro.<\/p>\n\n\n\n<p>We mark the&nbsp;enum&nbsp;as Blueprint-available using the&nbsp;BlueprintType&nbsp;specifier.<\/p>\n\n\n\n<p>The&nbsp;enum&nbsp;declaration is just the same as we would use in any other context.<\/p>\n\n\n\n<p>Our&nbsp;Tree&nbsp;requires a&nbsp;TreeType. Because&nbsp;<em>tree has tree-type<\/em>&nbsp;is the relationship we want to embody, we include an instance of&nbsp;TreeType&nbsp;in our&nbsp;Tree&nbsp;class.<\/p>\n\n\n\n<p>As usual, we need to use&nbsp;UPROPERTY()&nbsp;to make the member variable accessible to the reflection system.<\/p>\n\n\n\n<p>We use the&nbsp;BlueprintReadWrite&nbsp;specifier to mark the property as having both get and set support within Blueprint.<\/p>\n\n\n\n<p>Enumerated types require being wrapped in the&nbsp;TEnumAsByte&nbsp;template when used in&nbsp;UPROPERTY, so we declare an instance of&nbsp;TEnumAsByte&lt;TreeType&gt;&nbsp;as the Tree&#8217;s&nbsp;Type&nbsp;variable.<\/p>\n\n\n\n<p>The constructor changes for&nbsp;Tree&nbsp;are simply the standard load and initialize our static mesh component preamble that&#8217;s used in other recipes.<\/p>\n\n\n\n<p>We create a Blueprint that inherits from our&nbsp;Tree&nbsp;class so that we can demonstrate the Blueprint-accessibility of the&nbsp;TreeType enum.<\/p>\n\n\n\n<p>To have the Blueprint assign a type to the tree at random when we create an instance, we need to use the&nbsp;Construction Script&nbsp;Blueprint.<\/p>\n\n\n\n<p>Within the&nbsp;Construction Script, we calculate the number of entries in the&nbsp;TreeType enum.<\/p>\n\n\n\n<p>We generate a random number and use that as an index in the&nbsp;TreeType enum&nbsp;type to retrieve a value to store as our&nbsp;Type.<\/p>\n\n\n\n<p>The Random number node, however, returns integers. Enumerated types are treated as bytes in Blueprint, so we need to use a&nbsp;ToByte&nbsp;node, which can then be implicitly converted by Blueprint into an&nbsp;enum&nbsp;value.<\/p>\n\n\n\n<p>Now that we have&nbsp;Construction Script&nbsp;assigning a type to our tree instances as they are created, we need to display the tree&#8217;s type at runtime.<\/p>\n\n\n\n<p>We do so with the graph attached to the&nbsp;BeginPlay&nbsp;event within the Event Graph tab.<\/p>\n\n\n\n<p>To display text on screen, we use a&nbsp;Print String&nbsp;node.<\/p>\n\n\n\n<p>To perform string substitution and print our type out as a human-readable string, we use the&nbsp;Format Text&nbsp;node.<\/p>\n\n\n\n<p>The&nbsp;Format Text&nbsp;node takes terms enclosed in curly braces and allows you to substitute other values for those terms by returning the final string.<\/p>\n\n\n\n<p>To substitute our&nbsp;Type&nbsp;into the&nbsp;Format Text&nbsp;node, we need to convert our variable stores from the&nbsp;enum&nbsp;value into the actual name of the value.<\/p>\n\n\n\n<p>We can do so by accessing our&nbsp;Type&nbsp;variable and then using the&nbsp;Enum to Name&nbsp;node.<\/p>\n\n\n\n<p>Names, or&nbsp;FNames&nbsp;in native code, are a type of variable that can be converted into strings by Blueprint so that we can connect our&nbsp;Name&nbsp;to the input on the&nbsp;Format Text&nbsp;node.<\/p>\n\n\n\n<p>When we hit Play, the graph executes, retrieving the type of tree instances that have been placed in the level and printing the names to the screen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Enums are commonly used in C++ as flags or inputs to sw [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27,1],"tags":[26],"_links":{"self":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/3033"}],"collection":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3033"}],"version-history":[{"count":3,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/3033\/revisions"}],"predecessor-version":[{"id":3352,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/3033\/revisions\/3352"}],"wp:attachment":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3033"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3033"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3033"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}