{"id":3119,"date":"2021-01-02T14:05:17","date_gmt":"2021-01-02T06:05:17","guid":{"rendered":"http:\/\/blog.coolcoding.cn\/?p=3119"},"modified":"2021-01-02T19:43:01","modified_gmt":"2021-01-02T11:43:01","slug":"working-with-ue4-apis","status":"publish","type":"post","link":"https:\/\/blog.coolcoding.cn\/?p=3119","title":{"rendered":"Working with UE4 APIs"},"content":{"rendered":"\n<p>The&nbsp;<strong>application programming interface<\/strong>&nbsp;(<strong>API<\/strong>) is the way in which you, as the programmer, instruct the engine, and therefore the PC, what to do. Some of the interesting APIs that we&#8217;ll explore in the recipes in this chapter are as follows:<\/p>\n\n\n\n<ul><li>Core\/Logging API \u2013 defining a custom log category<\/li><li>Core\/Logging API \u2013 FMessageLog to write messages to the Message Log<\/li><li>Core\/Math API \u2013 rotation using FRotator<\/li><li>Core\/Math API \u2013 rotation using FQuat<\/li><li>Core\/Math API \u2013 rotation using FRotationMatrix to have one object face another<\/li><li>Landscape API \u2013 landscape generation with Perlin noise<\/li><li>Foliage API \u2013 adding trees procedurally to your level<\/li><li>Landscape and Foliage APIs \u2013 map generation using Landscape and Foliage APIs<\/li><li>GameplayAbilities API \u2013 triggering an actor&#8217;s gameplay abilities with game controls<\/li><li>GameplayAbilities API \u2013 implementing stats with AttributeSet<\/li><li>GameplayAbilities API \u2013 implementing buffs with GameplayEffect<\/li><li>GameplayTags API \u2013 attaching GameplayTags to an actor<\/li><li>GameplayTasks API \u2013 making things happen with GameplayTasks<\/li><li>HTTP API \u2013 downloading web pages using web requests<\/li><li>HTTP API \u2013 displaying downloaded progress<\/li><\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">Introduction<\/h1>\n\n\n\n<p>All of UE4&#8217;s functionality is encapsulated in modules, including very basic and core functionality. Each module has an API for it. To use an API, there is a very important linkage step, where you must list all APIs that you will be using in your build in a&nbsp;ProjectName.Build.cs&nbsp;file, which is located in your&nbsp;Solution Explorer&nbsp;window.Do not name any of your UE4 projects with the exact same name as one of the UE4 API names!<\/p>\n\n\n\n<p>There are a variety of APIs inside the UE4 engine that expose functionality to various essential parts of it.&nbsp;<\/p>\n\n\n\n<p>The UE4 engine&#8217;s base functionality, which is available in the editor, is quite broad. The functionality from C++ code is actually grouped into little sections called APIs. There is a separate API module for each important functionality in the UE4 codebase. This is done to keep the codebase highly organized and modular.Using different APIs may require special linkage in your&nbsp;Build.cs&nbsp;file! If you are getting build errors, be sure to check that the linkage with the correct APIs is there!<\/p>\n\n\n\n<p>The complete API listing is located in the following documentation:\u00a0<a href=\"https:\/\/docs.unrealengine.com\/latest\/INT\/API\/\">https:\/\/docs.unrealengine.com\/latest\/INT\/API\/<\/a>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Technical requirements<\/h1>\n\n\n\n<p>This chapter requires the use of Unreal Engine 4 and uses Visual Studio 2017 as the IDE. Instructions on how to install both pieces of software and the requirements for them can be found in\u00a0<a href=\"https:\/\/learning.oreilly.com\/library\/view\/unreal-engine-4x\/9781789809503\/4adb307e-d86f-4d70-b6de-a0893102d1cf.xhtml\">Chapter 1<\/a>,\u00a0<em>UE4 Development Tools<\/em>, of this book.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Core\/Logging API \u2013 defining a custom log category<\/h1>\n\n\n\n<p>UE4 itself defines several logging categories, including categories such as&nbsp;LogActor, which has any log messages to do with the&nbsp;Actor&nbsp;class, and&nbsp;LogAnimation, which logs messages about animations. In general, UE4 defines a separate logging category for each module. This allows developers to output their log messages to different logging streams. Each log stream&#8217;s name is prefixed to the outputted message, as shown in the following example log messages from the engine:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">LogContentBrowser: Native class hierarchy updated for <br> 'HierarchicalLODOutliner' in 0.0011 seconds. Added 1 classes and 2 <br> folders. \nLogLoad: Full Startup: 8.88 seconds (BP compile: 0.07 seconds) \nLogStreaming:Warning: Failed to read file <br> '..\/..\/..\/Engine\/Content\/Editor\/Slate\/Common\/Selection_16x.png' <br> error. \nLogExternalProfiler: Found external profiler: VSPerf <\/pre>\n\n\n\n<p>These log messages&nbsp;are samples&nbsp;from the engine, each prefixed with their log category. Warning messages appear in yellow and have&nbsp;Warning&nbsp;added to the front as well.<\/p>\n\n\n\n<p>The example code you will find on the internet tends to use&nbsp;LogTemp&nbsp;for a UE4 project&#8217;s own messages, as follows:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">UE_LOG( LogTemp, Warning, TEXT( \"Message %d\" ), 1 ); <\/pre>\n\n\n\n<p>We can actually improve upon this formula by defining our own custom\u00a0LogCategory.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Getting ready<\/h1>\n\n\n\n<p>Have a UE4 project ready in which you&#8217;d like to define a custom log. Open a header file that will be included in almost all files using this log.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How to do it&#8230;<\/h1>\n\n\n\n<ol><li>Open the main header file for your project; for example, if your project&#8217;s name is&nbsp;Chapter_11, you&#8217;ll open&nbsp;Chapter_11.h. Add the following line of code:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#pragma once<br><br>#include \"CoreMinimal.h\"<br><br><strong>DECLARE_LOG_CATEGORY_EXTERN(LogCh11, Log, All);<\/strong><\/pre>\n\n\n\n<p>As defined in&nbsp;AssertionMacros.h, there are three arguments to this declaration, which are as follows:<\/p>\n\n\n\n<ul><li>CategoryName: This is the log category name being defined (LogCh11&nbsp;here)<\/li><li>DefaultVerbosity: This is the default verbosity to use on log messages<\/li><li>CompileTimeVerbosity: This is the verbosity to bake into compiled code<\/li><\/ul>\n\n\n\n<ol><li>Inside the main&nbsp;.cpp&nbsp;file for your project (Chapter_11.cpp&nbsp;in our case), include the following line of code:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#include \"Chapter_11.h\"<br>#include \"Modules\/ModuleManager.h\"<br><br>IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, Chapter_11, \"Chapter_11\" );<br><br><strong>DEFINE_LOG_CATEGORY(LogCh11);<\/strong><\/pre>\n\n\n\n<ol><li>Now, we can use this log category in our own scripts. As an example, open up your project&#8217;s&nbsp;GameModeBase&nbsp;file (in this case,&nbsp;Chapter_11GameModeBase.h) and add the following function declaration:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">UCLASS()<br>class CHAPTER_11_API AChapter_11GameModeBase : public AGameModeBase<br>{<br>    GENERATED_BODY()<br>    <br>    <strong>void BeginPlay();<\/strong><br>};<\/pre>\n\n\n\n<ol><li>Then, go to the implementation (Chapter_11GameModeBase.cpp) and use the following code as an example of the various display categories:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#include \"Chapter_11GameModeBase.h\"<br>#include \"Chapter_11.h\"<br><br>void AChapter_11GameModeBase::BeginPlay()<br>{<br><strong>    \/\/ Traditional Logging<\/strong><br><strong>    UE_LOG(LogTemp, Warning, TEXT(\"Message %d\"), 1);<\/strong><br><br><strong>    \/\/ Our custom log type<\/strong><br><strong>    UE_LOG(LogCh11, Display, TEXT(\"A display message, log is working\" ) ); \/\/ shows in gray <\/strong><br><strong>    UE_LOG(LogCh11, Warning, TEXT(\"A warning message\"));<\/strong><br><strong>    UE_LOG(LogCh11, Error, TEXT(\"An error message \"));<\/strong><br>}<\/pre>\n\n\n\n<ol><li>Compile your scripts. Afterwards, open the&nbsp;World Settings&nbsp;menu and set the&nbsp;GameMode Override&nbsp;property to&nbsp;Chapter_11GameModeBase&nbsp;and then run the game:<\/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\/5e64d7dd-1c39-4e0b-80fe-1556f7b9cf2b.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>The location of the logged messages from the Output Log window<\/p>\n\n\n\n<p>As you can see, we can see our custom log messages being displayed!<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How it works&#8230;<\/h1>\n\n\n\n<p>Logging works by outputting messages to the\u00a0Output Log\u00a0(Window\u00a0|\u00a0Developer Tools\u00a0|\u00a0Output Log) as well as a file. All information outputted to the\u00a0Output Log\u00a0is also mirrored to a simple text file that is located in your project&#8217;s\u00a0\/Saved\/Logs\u00a0folder. The extension of the log files is\u00a0.log, with the most recent one being named\u00a0YourProjectName.log.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">There&#8217;s more&#8230;<\/h1>\n\n\n\n<p>You can enable or suppress log messages for a particular log channel from within the editor using the following console commands:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Log LogName off \/\/ Stop LogName from displaying at the output \nLog LogName Log \/\/ Turn LogName's output on again <\/pre>\n\n\n\n<p>If you&#8217;d like to edit the initial values of the output levels of some of the built-in log types, you can use a C++ class to create changes for the&nbsp;engine.ini&nbsp;config file. You can change the initial values in the&nbsp;engine.ini&nbsp;configuration file.See&nbsp;<a href=\"https:\/\/wiki.unrealengine.com\/Logs,_Printing_Messages_To_Yourself_During_Runtime\">https:\/\/wiki.unrealengine.com\/Logs,_Printing_Messages_To_Yourself_During_Runtime<\/a>&nbsp;for more details.<\/p>\n\n\n\n<p>UE_LOG\u00a0sends its output to\u00a0Output Window. If you&#8217;d like to use the more specialized\u00a0Message Log\u00a0window in addition\u00a0to this, you can use the\u00a0FMessageLog\u00a0object to write your output messages.\u00a0FMessageLog\u00a0writes to both the\u00a0Message Log\u00a0and the\u00a0Output Window. See the next recipe for details.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Core\/Logging API \u2013 FMessageLog to write messages to the Message Log<\/h1>\n\n\n\n<p>FMessageLog\u00a0is an object that allows you to write output messages to the\u00a0Message Log\u00a0(Window\u00a0|\u00a0Developer Tools\u00a0|\u00a0Message Log) and\u00a0Output Log\u00a0(Window\u00a0|\u00a0Developer Tools\u00a0|\u00a0Output Log) simultaneously.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Getting ready<\/h1>\n\n\n\n<p>Have your project ready and some information to log to\u00a0Message Log. Display the\u00a0Message Log\u00a0(Window\u00a0|\u00a0Developer Tools\u00a0|\u00a0Message Log)\u00a0in your UE4 Editor.\u00a0<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How to do it&#8230;<\/h1>\n\n\n\n<ol><li>Add&nbsp;#define&nbsp;to your main header file (ProjectName.h), defining&nbsp;LOCTEXT_NAMESPACE&nbsp;as something unique to your codebase:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#define LOCTEXT_NAMESPACE \"Chapter11Namespace\"<\/pre>\n\n\n\n<p>This&nbsp;#define&nbsp;is used by the&nbsp;LOCTEXT()&nbsp;macro, which we use to generate&nbsp;FText&nbsp;objects, but is not seen in output messages.<\/p>\n\n\n\n<ol><li>Declare your&nbsp;FMessageLog&nbsp;by constructing it somewhere very global. You can use&nbsp;extern&nbsp;in your&nbsp;ProjectName.h&nbsp;file. Consider the following piece of code as an example:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#define LOCTEXT_NAMESPACE \"Chapter11Namespace\"<br><strong>#define FTEXT(x) LOCTEXT(x, x) <\/strong><br><br><strong>extern FName LoggerName;<\/strong><br><br><strong>void CreateLog(FName logName);<\/strong><\/pre>\n\n\n\n<ol><li>Then, create your&nbsp;FMessageLog&nbsp;by defining it in a&nbsp;.cpp&nbsp;file and registering it with&nbsp;MessageLogModule. Be sure to give your logger a clear and unique name on construction. It&#8217;s the category of your log that will appear to the left of your log messages in&nbsp;Output Log. For example,&nbsp;ProjectName.cpp:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#include \"Chapter_11.h\"<br>#include \"Modules\/ModuleManager.h\"<br>#include \"MessageLog\/Public\/MessageLogModule.h\"<br>#include \"MessageLog.h\"<br><br>\/\/ ...<br><br>FName LoggerName(\"MessageLogChapter11\");<br><br>void CreateLog(FName logName)<br>{<br>    FMessageLogModule&amp; MessageLogModule = FModuleManager::LoadModuleChecked&lt;FMessageLogModule&gt;(\"MessageLog\");<br>    FMessageLogInitializationOptions InitOptions;<br>    InitOptions.bShowPages = true;<br>    InitOptions.bShowFilters = true;<br>    FText LogListingName = FTEXT(\"Chapter 11's Log Listing\");<br>    MessageLogModule.RegisterLogListing(logName, LogListingName, InitOptions);<br>}<\/pre>\n\n\n\n<ol><li>Then, head back to somewhere in your code to actually create the log and use it. For example, we can add the following&nbsp;GameModeBase&nbsp;class&#8217;s&nbsp;BeginPlay&nbsp;method:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">void AChapter_11GameModeBase::BeginPlay()<br>{<br>    \/\/ 11-01 - Core\/Logging API - Defining a custom log<br>    \/\/ category<br>    \/\/ Traditional Logging<br>    UE_LOG(LogTemp, Warning, TEXT(\"Message %d\"), 1);<br><br>    \/\/ Our custom log type<br>    UE_LOG(LogCh11, Display, TEXT(\"A display message, log is working\" ) ); \/\/ shows in gray <br>    UE_LOG(LogCh11, Warning, TEXT(\"A warning message\"));<br>    UE_LOG(LogCh11, Error, TEXT(\"An error message \"));<br><br><strong>    \/\/ 11-02 - Core\/Logging API - FMessageLog to write <br>    \/\/ messages to the Message Log<\/strong><br><strong>    CreateLog(LoggerName);<\/strong><br><strong>    \/\/ Retrieve the Log by using the LoggerName. <\/strong><br><strong>    FMessageLog logger(LoggerName);<\/strong><br><strong>    logger.Warning(FTEXT(\"A warning message from gamemode\"));<\/strong><br>}<\/pre>\n\n\n\n<p>The&nbsp;KEY&nbsp;to&nbsp;LOCTEXT&nbsp;(first argument) must be unique or you will get a previously hashed string back. If you&#8217;d like, you can include a&nbsp;#define&nbsp;that repeats the argument to&nbsp;LOCTEXT&nbsp;twice, as we did earlier:<\/p>\n\n\n\n<p>#define FTEXT(x) LOCTEXT(x, x)<\/p>\n\n\n\n<ol><li>Log your messages using the following code:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">logger.Info( FTEXT( \"Info to log\" ) ); \nlogger.Warning( FTEXT( \"Warning text to log\" ) ); \nlogger.Error( FTEXT( \"Error text to log\" ) ); <\/pre>\n\n\n\n<p>This code utilizes the\u00a0FTEXT()\u00a0macro we defined earlier. Ensure it is in your codebase.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How it works&#8230;<\/h1>\n\n\n\n<p>This recipe displays a message to the Message Log. As we discussed previously, you can see logged information at the&nbsp;Message Log&nbsp;(Window&nbsp;|&nbsp;Developer Tools&nbsp;|&nbsp;Message Log) and&nbsp;Output Log&nbsp;(Window&nbsp;|&nbsp;Developer Tools&nbsp;|&nbsp;Output Log) .Constructing your message log again after initialization retrieves a copy of the original message log. For example, at any place in the code, you can write the following code:<\/p>\n\n\n\n<p>FMessageLog( LoggerName ).Info(FTEXT( &#8220;An info message&#8221;)); <\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Core\/Math API \u2013 rotation using FRotator<\/h1>\n\n\n\n<p>Rotation in UE4 has such a complete implementation that it can be hard to choose how to rotate your objects. There are three main methods:&nbsp;FRotator,&nbsp;FQuat, and&nbsp;FRotationMatrix. This recipe outlines the construction and use of the first of the three different methods for the rotation of objects\u2014the&nbsp;FRotator. Using this, and the following two recipes, you can select a method to use to rotate your objects.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Getting ready<\/h1>\n\n\n\n<p>Open a UE4 project that has an object you can get a C++ interface with. For example, you can construct a C++ class Coin that derives from&nbsp;Actor&nbsp;to test out rotations. Override the&nbsp;Coin::Tick()&nbsp;method to apply your rotations from the C++ code. Alternatively, you can call these rotation functions in the&nbsp;Tick&nbsp;event from Blueprints.<\/p>\n\n\n\n<p>In this example, we will rotate an object at a rate of one degree per second by making use of an Actor component. The actual rotation will be the accumulated time since the object was created. To get this value, we&#8217;ll just call\u00a0GetWorld()->TimeSeconds.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Core\/Math API \u2013 rotation using FQuat<\/h1>\n\n\n\n<p>Quaternions sound intimidating, but they are extremely easy to use. You may want to review the theoretical math behind them by viewing the following videos:<\/p>\n\n\n\n<ul><li><em>Fantastic Quaternions<\/em>&nbsp;by Numberphile:&nbsp;<a href=\"https:\/\/www.youtube.com\/watch?v=3BR8tK-LuB0\">https:\/\/www.youtube.com\/watch?v=3BR8tK-LuB0<\/a><\/li><li><em>Understanding Quaternions<\/em>&nbsp;by Jim Van Verth:&nbsp;<a href=\"http:\/\/gdcvault.com\/play\/1017653\/Math-for-Game-Programmers-Understanding\">http:\/\/gdcvault.com\/play\/1017653\/Math-for-Game-Programmers-Understanding<\/a><\/li><\/ul>\n\n\n\n<p>However, we won&#8217;t cover the math background here! In fact, you don&#8217;t need to understand much about the math background of quaternions to use them effectively.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Getting ready<\/h1>\n\n\n\n<p>Have a project\u00a0ready and an\u00a0Actor\u00a0with an override\u00a0::Tick()\u00a0function that we can enter the C++ code into.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How to do it&#8230;<\/h1>\n\n\n\n<ol><li>To construct a quaternion, the best constructor to use is as follows:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">FQuat( FVector Axis, float AngleRad ); <\/pre>\n\n\n\n<p>Quaternions have quaternion addition, quaternion subtraction, multiplication by a scalar, and division by a scalar defined for them, among other functions. They are extremely useful to rotate things at arbitrary angles, and point objects at one another.<\/p>\n\n\n\n<ol><li>For example, if you wanted to use an FQuat inside of the&nbsp;RotateActorComponent.cpp&nbsp;file, it would look similar to this:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">void URotateActorComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)<br>{<br>    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);<br><br>    \/\/ 11-04 - Rotation using FQuat<br><strong>    FQuat quat = FQuat(FVector(0, 1, 0), GetWorld()-&gt;TimeSeconds * PI \/ 4.f);<\/strong><br><strong>    GetOwner()-&gt;SetActorRotation(quat);<\/strong><br><br>}<\/pre>\n\n\n\n<p>Upon compiling your code and returning to the game, you should notice the cube moving at a constant rate:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/learning.oreilly.com\/library\/view\/unreal-engine-4x\/9781789809503\/assets\/ddb86012-77dc-4859-ad2f-ea3689f90875.png\" alt=\"\"\/><figcaption><br><\/figcaption><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\">How it works&#8230;<\/h1>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/6edc4c6a-2cc5-4162-9d74-cd70b3b729b3.jpg\" alt=\"\"\/><\/figure>\n\n\n\n<p>Quaternions are a bit strange, but using them is quite simple. If&nbsp;<em>v<\/em>&nbsp;is the axis around which to rotate, and&nbsp;&nbsp;is the magnitude of the angle of rotation, then we get the following equations for the components of a quaternion:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/e9dc711a-8f43-48f8-bc68-a56de59ad11f.jpg\" alt=\"\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/ac235d9d-5ef7-46a7-8ce4-0a18ed80d558.jpg\" alt=\"\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/69cf02ef-9e27-44a6-9a4b-efdc00908cd8.jpg\" alt=\"\"\/><\/figure>\n\n\n\n<p>So, for example, rotation about&nbsp;&nbsp;by an angle of&nbsp;&nbsp;will have the following quaternion components:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/d3c4d321-4172-4dbe-9974-d6e0b6c8fe89.jpg\" alt=\"\"\/><\/figure>\n\n\n\n<p>Three of the four components of the quaternion (<em>x<\/em>,\u00a0<em>y<\/em>, and\u00a0<em>z<\/em>) define the axis around which to rotate (scaled by the sine of half the angle of rotation), while the fourth component (<em>w<\/em>) has only the cosine of half the angle to rotate with.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">There&#8217;s more&#8230;<\/h1>\n\n\n\n<p>Quaternions, being&nbsp;vectors&nbsp;themselves, can be rotated. Simply extract the (<em>x<\/em>,&nbsp;<em>y<\/em>,&nbsp;<em>z<\/em>) components of the quaternion, normalize, and then rotate that vector. Construct a new quaternion from that new unit vector with the desired angle of rotation.<\/p>\n\n\n\n<p>Multiplying quaternions together represents a series of rotations that happen subsequently. For example, a rotation of 45\u00ba about the&nbsp;<em>X<\/em>-axis, followed by a rotation of 45\u00ba about the&nbsp;<em>Y<\/em>-axis will be composed by the following:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">FQuat( FVector( 1, 0, 0 ), PI\/4.f ) * \nFQuat( FVector( 0, 1, 0 ), PI\/4.f ); <\/pre>\n\n\n\n<p>This would give you a result that would look similar to this:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/learning.oreilly.com\/library\/view\/unreal-engine-4x\/9781789809503\/assets\/f4bbdb04-e68b-48f2-abea-f943c4029dfd.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The&nbsp;application programming interface&nbsp;(API) i [&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\/3119"}],"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=3119"}],"version-history":[{"count":1,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/3119\/revisions"}],"predecessor-version":[{"id":3129,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/3119\/revisions\/3129"}],"wp:attachment":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3119"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3119"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3119"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}