Loading a texture from C++

I can’t seem to figure out how this is done, I have some code in play, but it cannot find the asset.

static ConstructorHelpers::FObjectFinder<UTexture2D> MyObj(TEXT("/Game/Spells/spell_heal"));

Now, you’re probably wondering, “does he have that asset in his editor?” and yes, yes I do.

And in explorer

Just to clarify, the end-goal of this this texture is to be loaded into an SImage Slate widget. I’ve wasted a 16 hour day on this, I can’t believe it’s this difficult to load little 50x50 png into the UI (and yes I’ve looked at the RTS/Shooter sources).

If I place the offending code in my HUD’s constuctor, then I get a little popup telling me…

CDO Constructor: Failed to find /game/spells/spell_heal

I’m stumped.

Is this for the editor, or for the runtime?

If it’s for the runtime, you’d create a Slate Brush asset that references the texture and use that.
If it’s for the editor, you’d simply add a brush entry to your style set which references that image from disk.

Either way a style set will need to involved as this handles loading, atlassing, and managing the lifespan of textures used by Slate brushes.

I just did a little ninja update there. I was hoping I’d have it fixed before someone replied =/ . Anyway it’s done. I don’t understand, I’m loading the texture exactly how it’s done in the RTS examples. I’ll have to lookup this style-set.

Can you give an example of creating the Slate Brush asset? I literally spent about 8 straight hours with intellisense, nuts.

To answer your question, it’s for the runtime, I wasn’t aware Slate was functioning in the Editor, I was under the impression that was a security vuln. I guess that just goes for the Viewport.

The RTS samples won’t be loading images from disk for use by Slate, I can assure you of that.

What they will be doing though is loading brushes (which is a reference to a texture as well as some information about how it should render in Slate).

You create them in the editor by clicking “New” in the content browser, and then selecting “Miscellaneous → Slate Brush”. This will create an asset that can be loaded by your game via the FSlateGameResources style for your game (see FStrategyStyle::Create for an example of setting one of these up; the search path used must include the path where your Slate brush asset is located).

That sounds simple enough, ty.

Got it working, only took about 20 hours. I’m beat, will start this up again tomorrow.

Seriously though, the long cycles are just part of the learning/research phase, it will take upwards of a couple minutes to do the same thing in the future.

I should add, I did things a little bit differently. Instead of creating a FSlateStyleSet, I used a FSlateGameResources pointer / heap object.

   TSharedRef<FSlateGameResources> pMyResources
    = FSlateGameResources::New(FName("MyStyle"),
        "/Game/Spells", "/Game/Spells");
    FSlateGameResources& MyResources = SlateResources.Get();

It seemed more appropriate since I wasn’t actually working with any StyleSets, but what I would consider to be “resources”. It’s a subclass of SSlateStyleSet. What is the difference?

Here are the humble beginnings of my spell-bar. It’s all black because I’m in debug mode, no lighting or baked lights.

I’ve just checked, and if you check out /Game/UI/Styles/DefaultActionImageBrush, that is an example of using a Slate brush asset in the RTS game.

That will be loaded in the runtime because FStrategyStyle uses /Game/UI/Styles as its search path (it also uses it as a base path, so you can omit the /Game/UI/Styles part when search for brushes from the style set). The brush itself is used in SStrategyButtonWidget::GetButtonImage.

Obviously this information is valid for runtime use; the editor works slightly differently as it loads images from disk rather than using assets.

Just noticed your comment about the editor. The entire editor UI is created and rendered in Slate, so it’s definitely available in the editor :slight_smile:

Resources in this context just means anything used by Slate, the main thing that goes in there (for a game) is brushes, widget styles, and fonts (fonts you currently have to set in code as we don’t have an editor representation of Slate fonts; we’re working on that).

Have you called FSlateStyleRegistry::RegisterSlateStyle(*pMyResources); for that FSlateGameResources instance? If not, I’m surprised that works as an unregistered style set won’t have registered any textures with the atlasser, so usually just ends up rendering invalid, white, semi-transparent brushes everywhere.

No, I hadn’t registered anything, I’d only called

TSharedRef<FSlateGameResources> SlateResources = FSlateGameResources::New(FName("MyStyle"), "/Game/Spells", "/Game/Spells");
FSlateGameResources& Style = SlateResources.Get();
const FSlateBrush* slate_spell_heal = Style.GetBrush(FName("slate_spell_heal"));

and later on

SNew(SImage).Image( slate_spell_heal )

Odd that it worked, but I updated the code to reflect your suggestions anyway.

//Access resources through Shared Pointer for safety
TSharedRef<FSlateGameResources> MyUIResources = FSlateGameResources::New(FName("MyUIResources"), "/Game/Spells", "/Game/Spells");
//Uncomment for direct access, less safe
//FSlateGameResources &MyUIResources = MyUIResources.Get();
//Register resources with Atlasser
FSlateStyleRegistry::RegisterSlateStyle( MyUIResources.Get() );

Another question, what do I use to register FSlateGameResources

I’m using

FSlateStyleRegistery::RegisterSlateStyle( *MyUIResourcesPtr );

Is that correct?

You know, at first I really hated the RTS game’s design, but I started writing some classes of my own, and without even looking they ended up being 99% the same lmao.

I would assume the reason run-time loading of resources fails or is unsupported is because of the platforms Unreal supports. some platform do not allow or allow limited access to the file system and instead need to use embedded resources much like how Win32 Uses them for the exe’s icon. I assume brushes ARE embedded correct?

Assuming MyUIResourcesPtr is some form of pointer to an FSlateGameResources, then yes, that’s correct.

It’s probably also a good idea to call FSlateStyleRegistery::UnRegisterSlateStyle when shutting down your game as well.

Not embedded as such, but a brush asset (like any other asset) will be cooked and packed for your game.

That actually raises a good point. I mentioned that if you wanted to use a font, you still have to load those from disk; what I forgot to mention though is that the fonts will need to be somewhere inside the /Content/Slate folder for your project. If they’re not placed here then they won’t be included in the package for your game so will fail to load - this is a stop-gap until we have font assets that Slate can use.

I just want to add that if anyone is having trouble with fonts in /Content/Slate

Try something like /Content/UI or /Content/Widgets

And adjust your code to use the /Game/UI or /Game/Widgets path instead of /game/slate . I haven’t loaded any fonts up yet, only brushes, but in one of the Engine’s .ini files there is a short list of places Slate will load resources from, the two I mentioned and a couple more, /Content/Widget is another one.

Thanks, but /Content/Slate should work for fonts since they’re loaded directly from disk. The sample games use that as a place to store their fonts, and I believe it is currently hard-coded somewhere as a packaging path.

If it doesn’t work, then that’s a bug that we need to fix :slight_smile:

I solved it putting these instructions in the constructor.