<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Robert Lewicki]]></title><description><![CDATA[Daily Unreal Column is a project about sending one and only one bite-sized news per day at 12pm CET, from Monday to Friday, to expose you to a features of Unreal Engine that are not very well known.]]></description><link>https://unreal.robertlewicki.games</link><image><url>https://substackcdn.com/image/fetch/$s_!7VT4!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png</url><title>Robert Lewicki</title><link>https://unreal.robertlewicki.games</link></image><generator>Substack</generator><lastBuildDate>Thu, 16 Apr 2026 20:36:23 GMT</lastBuildDate><atom:link href="https://unreal.robertlewicki.games/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Robert Lewicki]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[newsletter@robertlewicki.games]]></webMaster><itunes:owner><itunes:email><![CDATA[newsletter@robertlewicki.games]]></itunes:email><itunes:name><![CDATA[Robert Lewicki]]></itunes:name></itunes:owner><itunes:author><![CDATA[Robert Lewicki]]></itunes:author><googleplay:owner><![CDATA[newsletter@robertlewicki.games]]></googleplay:owner><googleplay:email><![CDATA[newsletter@robertlewicki.games]]></googleplay:email><googleplay:author><![CDATA[Robert Lewicki]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Daily Unreal Column #89 - FScopedSlowTask]]></title><description><![CDATA[Following up on the previous post, this is another way to provide accurate feedback to your user whenever something is happening and its taking some time.]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-89-fscopedslowtask</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-89-fscopedslowtask</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Wed, 18 Dec 2024 11:01:43 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>FScopedSlowTask is a structure that is very easy to use and provides great feedback to the user. It displays a progress bar with an optional message about what is currently happening. Let&#8217;s have a look at an example where we will be processing an array.</p><p>First thing we need to do is create a variable.</p><pre><code>TArray&lt;FSomeData&gt; MyData;
FScopedSlowTask MyTask(MyData.Num(), FText::FromString("Processing data..."));</code></pre><p>Notice that I defined an instance of the struct passing two parameters. First one, MyData.Num() defines how many units of work we are going to be processing. In our example, we will be processing array elements, so the number of units of work is equal to the number of the array elements. The second parameter is just a text that will be displayed on a progress bar.</p><p>Then, we just need to update the our task notifying it how many units of work we are planning to process at a given time. </p><pre><code>for (int32 Index = 0; Index &lt; MyTask.Num(); Index++)
{
&#9;MyTask.EnterProgressFrame(1.0f);
&#9;...
&#9;...
&#9;...
}</code></pre><p>And that&#8217;s it. We don&#8217;t need to worry about notifying the task that we have finished processing because it will wrap things up itself as soon as it runs out of the scope.</p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #88 - FScopedBusyCursor]]></title><description><![CDATA[Have you ever thought about how to provide a user feedback when making a tools that take more than a fraction of a second to run? Unreal got you covered with some nice structures built in.]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-88-fscopedbusycursor</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-88-fscopedbusycursor</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Mon, 16 Dec 2024 11:01:39 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One of the goodies that is available to use is FScopedBusyCursor. This structure is extremely simple to use and understand. What it does is, within the scope a variable of this type is created, it changes the operating system default cursor to a &#8220;busy&#8221; cursor. Busy cursor in Windows 10 is the spinning circle I&#8217;m sure most of you&#8217;ve seen.</p><p>As soon as the variable runs out of the scope (at the end of the function at latest unless you explicitly declared the variable on a heap) the cursor is being changed back to normal. Let&#8217;s have a look at an example code using it.</p><pre><code>void AMyActor::Foo()
{
&#9;...
&#9;...
&#9;...
&#9;{
&#9;&#9;// Creating busy curosr, default cursor is being
&#9;&#9;// replaced with busy cursor here.
&#9;&#9;FScopedBusyCursor BusyCursor;
&#9;&#9;for (int32 Index = 0; Index &lt; VeryBigNumber; Index++)
&#9;&#9;{
&#9;&#9;&#9;...
&#9;&#9;&#9;...
&#9;&#9;&#9;...
&#9;&#9;}
&#9;}
&#9;// Busy cursor doesn't exist here so normal cursor is
&#9;// being set here.
}</code></pre><p></p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #87 - Source code class templates]]></title><description><![CDATA[When you want to create new class in Unreal Engine you can pick a template you want to use. It is, however, very likely, that you want to delete or add something to that template. Here is how.]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-87-source-code</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-87-source-code</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Mon, 09 Dec 2024 11:52:09 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There are some changes that you might want to introduce to the class templates that already ship with the engine. Or, perhaps, you want to introduce your own. Either way, you can find all existing templates inside the <code>Engine\Content\Editor\Templates</code> directory.</p><pre><code>%COPYRIGHT_LINE%

#pragma once

#include "CoreMinimal.h"
%BASE_CLASS_INCLUDE_DIRECTIVE%
#include "%UNPREFIXED_CLASS_NAME%.generated.h"

UCLASS(%UCLASS_SPECIFIER_LIST%)
class %CLASS_MODULE_API_MACRO%%PREFIXED_CLASS_NAME% : public %PREFIXED_BASE_CLASS_NAME%
{
&#9;GENERATED_BODY()
&#9;
public:&#9;
&#9;// Sets default values for this actor's properties
&#9;%PREFIXED_CLASS_NAME%();

protected:
&#9;// Called when the game starts or when spawned
&#9;virtual void BeginPlay() override;

public:&#9;
&#9;// Called every frame
&#9;virtual void Tick(float DeltaTime) override;

&#9;%CLASS_FUNCTION_DECLARATIONS%
&#9;%CLASS_PROPERTIES%
};</code></pre><p>This is for example template file for a header file for the Actor class. I don&#8217;t know about you, but first thing I always do is delete all the comments and then move the <code>Tick</code> function right under the constructor to get rid of the second <code>public</code> namespace. Perhaps you might want to delete the tick function completely and modify the CPP file to disable ticking by default.</p><p>I highly recommend adjusting these templates to your project to improve the quality of life of your developers.</p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #86 - AI Data Provider]]></title><description><![CDATA[Writing modular functionality to support AI agents in your game can be very challenging. There are some great tools you can use to make this easier. Data providers are one of them.]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-86-ai-data-provider</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-86-ai-data-provider</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Wed, 04 Dec 2024 11:02:23 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Imaging creating a behavior tree for one of the agents in your game. One of the behavior tree tasks expect you to pass their attack range. Then you also want to run an EQS with a donut pattern generated  using the attack range as a radius. And you also want to use this somewhere in your game code, directly. Making sure that all these places uses same source of truth is not easy. This is exactly where AI Data Providers shine.</p><p>To be specific, the structure we are talking about here is <code>FAIDataProviderValue </code>and its subclasses. This struct has a property of type <code>UAIDataProvider</code>. This one is the most interesting one from the end user perspective. The engine ships with two subclasses to this one:</p><ul><li><p><code>UAIDataProvider_QueryParams</code></p></li><li><p><code>UAIDataProvider_Random</code></p></li></ul><p>The first one is used in EQS to allow specifying EQS params when requesting query execution. The second one, as the name states, is purely random.</p><p>Let&#8217;s go back to the example I mentioned in the first paragraph and assume that we are using Gameplay Ability System (GAS) in our game. This means, that the attack range is most likely a property in an attribute set for either character or a weapon. What we can do is create a subclass of <code>UAIDataProvider</code> class and make it bind its value to a specific attribute value.</p><pre><code>class AIMODULE_API UAIDataProvider_Attribute : public UAIDataProvider
{
&#9;GENERATED_BODY()
public:
&#9;virtual void BindData(const UObject&amp; Owner, int32 RequestId) override;

&#9;UPROPERTY(EditAnywhere, Category = Provider)
&#9;EAttributeType AttributeType;

&#9;UPROPERTY()
&#9;float FloatValue;

&#9;UPROPERTY()
&#9;int32 IntValue;

&#9;UPROPERTY()
&#9;bool BoolValue;
};</code></pre><p>Above is an exampel code on how to declare a class that will bind attribute value based on the specified <code>AttributeType</code>. Inside the <code>BindData</code> function what we need to do is query the attribute value from the Owner and set its value to the <code>FloatValue</code>, <code>IntValue</code> and <code>BoolValue</code>.</p><p>Then, wherever you create a reference for the <code>FAIDataProvider </code>struct, you will be able to assign your new <code>UAIDataProvider</code> class reference to dynamically bind the attribute value to it.</p><p>Here is an example on how the above would look like in the editor when used for specifing grid half size for EQS simple grid generator:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eXWg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F389e8f65-654d-4442-96ee-691d966f1056_674x244.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eXWg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F389e8f65-654d-4442-96ee-691d966f1056_674x244.png 424w, https://substackcdn.com/image/fetch/$s_!eXWg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F389e8f65-654d-4442-96ee-691d966f1056_674x244.png 848w, https://substackcdn.com/image/fetch/$s_!eXWg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F389e8f65-654d-4442-96ee-691d966f1056_674x244.png 1272w, https://substackcdn.com/image/fetch/$s_!eXWg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F389e8f65-654d-4442-96ee-691d966f1056_674x244.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eXWg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F389e8f65-654d-4442-96ee-691d966f1056_674x244.png" width="674" height="244" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/389e8f65-654d-4442-96ee-691d966f1056_674x244.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:244,&quot;width&quot;:674,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:25692,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!eXWg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F389e8f65-654d-4442-96ee-691d966f1056_674x244.png 424w, https://substackcdn.com/image/fetch/$s_!eXWg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F389e8f65-654d-4442-96ee-691d966f1056_674x244.png 848w, https://substackcdn.com/image/fetch/$s_!eXWg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F389e8f65-654d-4442-96ee-691d966f1056_674x244.png 1272w, https://substackcdn.com/image/fetch/$s_!eXWg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F389e8f65-654d-4442-96ee-691d966f1056_674x244.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Pro tip: it&#8217;s worth adding a property to your data provider to specifying a constant fall through value. This is because when testing EQS in the editor time using EQS testing pawn, these data providers will fail to bind to any meaningful values as there are most likely no instances of actors that we can read the attributes from. </p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #85 - Console Variable Sink]]></title><description><![CDATA[Using console variable to manage different aspects of your game is great, but sometimes you also want to be explicitly notified when a console variable value changes.]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-85-console-variable</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-85-console-variable</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Fri, 29 Nov 2024 11:03:13 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is exactly what <code>FAutoConsoleVariableSink</code> is for.  It allows us to bind a function to an existing console variable and be notified whenever its updated.</p><p><code>FAutoConsoleVariableSink</code> are usually defined in a source file (not headers) and look like this:</p><pre><code>FAutoConsoleVariableSink FooCVarSink(FConsoleCommandDelegate::CreateStatic(&amp;OnFooCVarChanged));</code></pre><p>As you can see, the constructor of this property take a delegate reference. This is where we define a function we want to invoke when a console variable changes.</p><p>There are multiple examples in the engine on how these are being utilized, so if you are curious, have a look at the engine code.</p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #84 - Mesh merging]]></title><description><![CDATA[Sometimes you might want to make a single mesh out of multiple parts. Unreal Engine has a functionality for merging multiple meshes into a single mesh and here is how.]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-84-mesh-merging</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-84-mesh-merging</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Tue, 26 Nov 2024 12:24:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One if such helper structures is <code>FSkeletalMeshMerge</code>. It can be found inside <code>SkeletalMeshMerge.h</code> file inside the engine. It it&#8217;s constructor it takes a skeletal mesh object that will store the result of the merge, an array of skeletal meshes we want to merge, and few other properties. With this structure created we just need to call <code>DoMerge</code> function which will return a boolean value indicating a success or a failure. <a href="https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Source/Runtime/Engine/Public/SkeletalMeshMerge.h#L128">Here</a> is a link to the source to this class on GitHub.</p><p>Merging meshes into a single one is not <em>always </em>beneficial, but there are some cases where it is. In case of skeletal mesh for example, it allows you to run a single animation blueprint on a single skeletal mesh component instead running multiple instances on multiple parts. Even other instances do nothing but copy the pose, that still costs us some computation time.</p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #83 - InlineEditConditionToggle]]></title><description><![CDATA[Another very useful, not very well known, meta tag property!]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-83-inlineeditconditiontoggle</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-83-inlineeditconditiontoggle</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Thu, 21 Nov 2024 12:32:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>So, we already covered meta tags for specifying <code>EditCondition</code>. This time we will expand our toolbox with <code>InlineEditConditionToggle</code>.</p><p>This specific tag allows us to force a flag to be inlined into the same row as another property that uses it for its <code>EditCondition</code>.</p><p>Here is how to define it:</p><pre><code>UPROPERTY(EditAnywhere, meta=(InlineEditConditionToggle))
bool bExampleFlag = false;

UPROPERTY(EditAnywhere, meta=(EditCondition="bExampleFlag"))
float ExampleValue = 0.0f;</code></pre><p>With the above defined, this is what we will see in the editor:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PwUW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e5a48f6-e4a5-4fca-8bf8-64993c364c15_565x112.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PwUW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e5a48f6-e4a5-4fca-8bf8-64993c364c15_565x112.gif 424w, https://substackcdn.com/image/fetch/$s_!PwUW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e5a48f6-e4a5-4fca-8bf8-64993c364c15_565x112.gif 848w, https://substackcdn.com/image/fetch/$s_!PwUW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e5a48f6-e4a5-4fca-8bf8-64993c364c15_565x112.gif 1272w, https://substackcdn.com/image/fetch/$s_!PwUW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e5a48f6-e4a5-4fca-8bf8-64993c364c15_565x112.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PwUW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e5a48f6-e4a5-4fca-8bf8-64993c364c15_565x112.gif" width="565" height="112" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1e5a48f6-e4a5-4fca-8bf8-64993c364c15_565x112.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:112,&quot;width&quot;:565,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:34991,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PwUW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e5a48f6-e4a5-4fca-8bf8-64993c364c15_565x112.gif 424w, https://substackcdn.com/image/fetch/$s_!PwUW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e5a48f6-e4a5-4fca-8bf8-64993c364c15_565x112.gif 848w, https://substackcdn.com/image/fetch/$s_!PwUW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e5a48f6-e4a5-4fca-8bf8-64993c364c15_565x112.gif 1272w, https://substackcdn.com/image/fetch/$s_!PwUW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1e5a48f6-e4a5-4fca-8bf8-64993c364c15_565x112.gif 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p></p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #82 - RunCommandlet]]></title><description><![CDATA[Creating custom commandlets and iterating on them was quite a pain. Epic has improved the a user experience in the latest Unreal Engine release!]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-82-runcommandlet</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-82-runcommandlet</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Wed, 20 Nov 2024 11:11:14 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you don&#8217;t know what commandlet is, its basically a class that contains a logic that can be executed via CLI. To run it, one must pass <code>-run</code> parameter when booting the editor. For example:</p><pre><code>UE5Editor.exe -run=FixRedirectors</code></pre><p>This will run the <code>FixRedirectors</code> commandlet.</p><p>The problem with that is when you are iterating on your commandlet, you must boot the editor from scratch every time you make any change.</p><p>Starting release 5.5, there is now a console command that allows you to run a commandlet directly from the editor: <code>RunCommandlet</code>.</p><p>This means that you can change your code, use live coding to compile the changes and use that console command to run your commandlet directly from the editor.</p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #81 - Plural variants for string format]]></title><description><![CDATA[When creating user facing interface with text, one of the annoying things in terms of creating a logic is making sure that we update the text labels based on the number. Here is how to make it easy.]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-81-plural-variants</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-81-plural-variants</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Tue, 19 Nov 2024 11:03:01 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!tdL4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48139e05-f9d9-4d3a-b2dc-593c2cdfdf83_1243x318.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><code>Format Text</code> node has a hidden logic that allows us to define different plural forms based on a number we use. Here is syntax for it:</p><pre><code>{Parameter}|plural(one=Text,other=OtherText)</code></pre><p>Let&#8217;s break it down. First, we must specify a parameter that will be used to evaluate which form the <code>Format Text</code> node should use. Right after that, we must insert <code>|</code> and specify the function (I guess?) name, in this case, <code>plural</code>. Then, inside paranthesis, specify version for a single item with <code>one=YourText</code> and finally specify version for all the other cases by typing <code>other=YourOtherText</code>.</p><p>Example usage:</p><pre><code>{Num}|plural(one=item,other=items)</code></pre><p>Here is a blueprint graph presenting the above example:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tdL4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48139e05-f9d9-4d3a-b2dc-593c2cdfdf83_1243x318.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tdL4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48139e05-f9d9-4d3a-b2dc-593c2cdfdf83_1243x318.png 424w, https://substackcdn.com/image/fetch/$s_!tdL4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48139e05-f9d9-4d3a-b2dc-593c2cdfdf83_1243x318.png 848w, https://substackcdn.com/image/fetch/$s_!tdL4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48139e05-f9d9-4d3a-b2dc-593c2cdfdf83_1243x318.png 1272w, https://substackcdn.com/image/fetch/$s_!tdL4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48139e05-f9d9-4d3a-b2dc-593c2cdfdf83_1243x318.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tdL4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48139e05-f9d9-4d3a-b2dc-593c2cdfdf83_1243x318.png" width="1243" height="318" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/48139e05-f9d9-4d3a-b2dc-593c2cdfdf83_1243x318.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:318,&quot;width&quot;:1243,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:119728,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tdL4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48139e05-f9d9-4d3a-b2dc-593c2cdfdf83_1243x318.png 424w, https://substackcdn.com/image/fetch/$s_!tdL4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48139e05-f9d9-4d3a-b2dc-593c2cdfdf83_1243x318.png 848w, https://substackcdn.com/image/fetch/$s_!tdL4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48139e05-f9d9-4d3a-b2dc-593c2cdfdf83_1243x318.png 1272w, https://substackcdn.com/image/fetch/$s_!tdL4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F48139e05-f9d9-4d3a-b2dc-593c2cdfdf83_1243x318.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>With the literal int value equal to 1, the above format text would evaluate to &#8220;You have 1 item.&#8221;. If we were to change it to any other value greater than 1, we would get &#8220;You have X items.&#8221;.</p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #80 - Manual level blueprint event execution 'ce']]></title><description><![CDATA[Following up on last daily column, today I want to show you how to manually execute events defined in level blueprints.]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-80-manual-level</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-80-manual-level</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Mon, 18 Nov 2024 09:45:34 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Last time I showed you how to execute an event defined in an actor blueprint by specifying the name of the actor, the event name and parameters. Often though, while testing, we put some helper functions inside level blueprint for convenience. This specific blueprint graph is not an actor so it has a specific way of accessing its events.</p><p>To call an event from a level blueprint use following console command:</p><pre><code>ce EventName ParamValues</code></pre><p>With the above command you will execute an event with a name <code>EventName</code> with parameter values specified right after.</p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #79 - Manual event execution with 'ke']]></title><description><![CDATA[When testing different aspects of your game, I'm almost certain that at some point you wanted to be able to manually execute an event defined in an actor blueprint graph. Here is how to do that.]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-79-manual-event</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-79-manual-event</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Fri, 15 Nov 2024 11:21:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Once you start a PIE session, you need to open a console prompt and type in following command:</p><pre><code>ke ActorName EventName ParamValue</code></pre><p>ActorName is the name as appears in the scene outline.</p><p>EventName is the name of the blueprint event.</p><p>ParamValue is the value of a parameter, if one exist.</p><p>Further more, you can use * instead ActorName to execute specified event on all actors. For example:</p><pre><code>ke * Jump</code></pre><p>will execute Jump event on all actors that have that event defined.</p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #78 - Core Delegates]]></title><description><![CDATA[Writing gameplay or editor code that needs to react to some user action is very inconvenient if there is no delegate notifying us that something has happened. Here is where to find useful delegates.]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-78-core-delegates</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-78-core-delegates</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Thu, 14 Nov 2024 10:59:41 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As mentioned in the intro paragraph, when it comes to reacting to some user or engine action the most convenient thing is to have a delegate that we can subscribe to and act upon.</p><p>There is a <code>CoreDelegate.h</code> header file where we can find <em><strong>a lot</strong></em> of useful delegates. Go ahead and explore yourself while I will bring just few examples here.</p><p>Here is a delegate broadcasted when <code>GConfig</code> is ready to use.</p><pre><code>DECLARE_MULTICAST_DELEGATE(FConfigReadyForUse);
static FConfigReadyForUse ConfigReadyForUse;</code></pre><p>Here is  a delegate that allows us to add our own message to the viewport, similar to the &#8220;Lightning needs to be rebuilt&#8221; message we can often see.</p><pre><code>DECLARE_MULTICAST_DELEGATE_OneParam(FGetOnScreenMessagesDelegate, FSeverityMessageMap&amp;);
static FGetOnScreenMessagesDelegate OnGetOnScreenMessages;</code></pre>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #77 - Custom AI focus priorities]]></title><description><![CDATA[It is very common to have our AI agents focus on either another actor or some specific location (also called focal point). Existing code does support both, but have limited amount of priorities.]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-77-custom-ai</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-77-custom-ai</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Wed, 13 Nov 2024 13:23:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If we take a peek into AIController.h file, we can find a following definition somewhere at the top:</p><pre><code>namespace EAIFocusPriority
{
&#9;typedef uint8 Type;

&#9;const Type Default = 0;
&#9;const Type Move = 1;
&#9;const Type Gameplay = 2;

&#9;const Type LastFocusPriority = Gameplay;
}</code></pre><p>As you can see, by default there are only 3 priorities available to us. Luckily, this isn&#8217;t an enum class but simply a typedef&#8217;ed uint8 constants. This means, that we can extend this in our game code by writing something like this:</p><pre><code>namespace EAIFocusPriority
{
&#9;const Type CustomPriority = 3;
}</code></pre><p>This is supported by the system as it internally expand the array that stores the focus targets for each priority:</p><pre><code>...
if (InPriority &gt;= FocusInformation.Priorities.Num())
{
&#9;FocusInformation.Priorities.SetNum(InPriority + 1);
}
...</code></pre>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #76 - Copy blueprint nodes to text]]></title><description><![CDATA[If you ever wondered how you can store source of your blueprint graphs externally, wonder no more. They can be copied and stored as plain text!]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-76-copy-blueprint</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-76-copy-blueprint</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Tue, 12 Nov 2024 12:38:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You probably copied and pasted blueprint nodes between different graphs or even within the same graph multiple times. But did you know that if you copy selected blueprint nodes, you can simply paste them into a text file? This way you can easily share it for other members of your team for example. Or you can use website like <a href="https://blueprintue.com/">this</a> to publish your blueprints externally without needing to take and send screenshots.</p><p>I&#8217;m not going to paste any example here due to the size of the generated text but give it a try yourself!</p><p>PS. Sorry for the lack of the daily column updates in the past days but I decided to keep myself offline during my holidays. I&#8217;m back now though, and so is the unreal column!</p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #75 - DebugExecBindings]]></title><description><![CDATA[When working on game project, making debug tools is essential. The easiest way to enable them is by using console variables or cheat commands. Here is how to easily bind them to keys for ease of use.]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-75-debugexecbindings</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-75-debugexecbindings</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Fri, 01 Nov 2024 11:01:27 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you are using some tools very often it might be a great convenience to have a dedicated key to activate it. However, we, of course, don&#8217;t want to waste actual player input binding for that, as we are not going to ship our game with debug tools. Luckily, Unreal Engine already has a concept of debug key bindings, for example, for toggling different view modes using function keys (F1, F2, &#8230;).</p><p>These bindings are defined inside a <code>BaseInput.ini</code> file.</p><pre><code>[/Script/Engine.PlayerInput]

; --- General bindings
+DebugExecBindings=(Key=F11,Command="LevelEditor.ToggleImmersive", bIgnoreCtrl=True, bIgnoreAlt=True)
+DebugExecBindings=(Key=F11,Command="MainFrame.ToggleFullscreen",Shift=True)
+DebugExecBindings=(Key=F1,Command="viewmode wireframe", bIgnoreShift=True)
+DebugExecBindings=(Key=F2,Command="viewmode unlit")
+DebugExecBindings=(Key=F3,Command="viewmode lit")
...</code></pre><p>So, to add your own keys, you can either modify this config file directly, or add the <code>[/Script/Engine.PlayerInput]</code> section in one of your game specific configs to enable them.</p><p>The key bindings will be automatically stripped out in a shipping build.</p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #74 - AssetRegistrySearchable]]></title><description><![CDATA[When working with big sets of data it is advisable to be very cautious when gets and what doesn't get loaded into the memory. AssetRegistrySearchable meta tag makes it all so much easier. Here is how.]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-74-assetregistrysearchable</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-74-assetregistrysearchable</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Thu, 31 Oct 2024 11:01:17 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you use Asset Registry to find all existing assets using a specific query, for example, by filtering them by class like that</p><pre><code>FAssetRegistryModule&amp; AssetRegistryModule = FModuleManager::LoadModuleChecked&lt;FAssetRegistryModule&gt;("AssetRegistry");
TArray&lt;FAssetData&gt; AssetData;
const UClass* Class = UStaticMesh::StaticClass();
AssetRegistryModule.Get().GetAssetsByClass(Class-&gt;GetFName(), AssetData);</code></pre><p>you probably don&#8217;t want to load all of them into memory. Unfortunately, in order to read an object property, it would need to be loaded. That is, unless its properties are being marked with AssetRegistrySearchable. A property with this tag is being added to a TagsAndValues map of the FAssetData structure. This allows us to find all objects, then filter them using these tags and values, and only load the ones we really need.</p><p>Example property declared as AssetRegistrySearchable:</p><pre><code>UPROPERTY(Category=Texture, AssetRegistrySearchable)
TEnumAsByte&lt;enum TextureFilter&gt; Filter;</code></pre><p></p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #73 - FPlatformMisc]]></title><description><![CDATA[One benefit of using Unreal Engine is its support for multiple platforms. It is worth knowing that Unreal has a generic wrapper for a lot of OS specific functionality.]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-73-fplatformmisc</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-73-fplatformmisc</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Wed, 30 Oct 2024 11:23:17 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><code>FPlatformMisc</code> is a <code>typedef</code> that is bound to a specific class type during compilation based on a target platform. For example, on Windows, it is <code>typedef</code>&#8217;ed to <code>FWindowsPlatformMisc</code>. These platform miscellaneous classes contain a lot of utility functions specific to a platform, things like accessing registry key, environment variables, requesting application to exit, getting CPU and GPU information and many more.</p><p>Have a look at <code>FGenericPlatformMisc</code> which all of platform specific implementations inherit from to get a better understanding of what is available.</p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #72 - TFixedAllocator]]></title><description><![CDATA[We already covered TInlineAllocator in the past, today we will briefly talk about alternative.]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-72-tfixedallocator</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-72-tfixedallocator</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Tue, 29 Oct 2024 12:35:45 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As you may remember, <code>TInlineAllocator</code> allowed us to allocate a memory space for an array elements in the same space as the owner of the array. In case the declaration is inside a function, it is being allocated on stack.</p><p><code>TFixedAllocator</code> works exactly same in this regard, except it doesn&#8217;t offer a fallback which <code>TInlineAllocator</code> does. This means that if we exceed declared size,  the program will crash. This might be intended as we may design certain functions to work on a specific order of magnitude of data, so knowing when this limit is exceeded can be very beneficial to us.</p><pre><code>TArray&lt;float, TFixedAllocator&lt;32&gt;&gt; Floats;</code></pre><p>The above snippets shows how to declare array using <code>TFixedAllocator</code>.</p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #71 - DisableEnginePluginsByDefault]]></title><description><![CDATA[Did you know that it is possible to disable all the engine plugins by adding one line of text inside your project's '.uproject' file?]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-71-disableenginepluginsbydef</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-71-disableenginepluginsbydef</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Mon, 28 Oct 2024 11:45:11 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The reality is that we rarely use all of the plugins that are enabled by default. But their DLLs are still being loaded and, if you use source version of the engine, a clean build needs to take them into account and compile them.</p><p>Adding this line of text to your &#8216;.uproject&#8217; file will prevent them from loading:</p><pre><code>...
"DisableEnginePluginsByDefault": true,
...</code></pre><p>Of course, we still need some plugins to be enabled in order to be able to use the Editor at all. This is why some great folks created a snippets that contain the absolutely required ones you can just yank into your file and should be good to go.</p><p>Here is a link to a gist: <a href="https://gist.github.com/MilkyEngineer/a1e953f87509877adc4587cf8776c8a2">https://gist.github.com/MilkyEngineer/a1e953f87509877adc4587cf8776c8a2</a></p>]]></content:encoded></item><item><title><![CDATA[Daily Unreal Column #70 - PostEditChangeChainProperty]]></title><description><![CDATA[It is often a case that you want to run some custom code whenever you update a property on your object or actor. For example to do some validation or update another property based on it?]]></description><link>https://unreal.robertlewicki.games/p/daily-unreal-column-70-posteditchangechainproper</link><guid isPermaLink="false">https://unreal.robertlewicki.games/p/daily-unreal-column-70-posteditchangechainproper</guid><dc:creator><![CDATA[Robert Lewicki]]></dc:creator><pubDate>Fri, 25 Oct 2024 10:02:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F373895bd-a713-4de0-8e82-258af074ac72_256x256.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>All you need to do is to overwrite a single function:</p><pre><code>virtual void PostEditChangeChainProperty(struct FPropertyChangedChainEvent &amp; PropertyChangedEvent) override;</code></pre><p>The base function is defined inside <code>UObject</code> class, so any subclass can overwrite it. Inside it, you figure out which property has been updated based on the data from the <code>FPropertyChangedChainEvent</code>, but more details how to fetch this data will be covered in the future column.</p>]]></content:encoded></item></channel></rss>