Download

Slate Style path crash the editor

Here is the error i get in log when the editor crash :


Address = 0xe4a1b476 (filename not found) [in E:\Programs\Unreal Engine\4.0\Engine\Binaries\Win64\UE4Editor-Core.dll]
Address = 0xe48bf675 (filename not found) [in E:\Programs\Unreal Engine\4.0\Engine\Binaries\Win64\UE4Editor-Core.dll]
FDE_Style::Get() 0xdbe8f481 + 45 bytes [File=e:\elzean documents\documents\unreal projects\fps_inventory\source\fps_inventory\private\ui\style\de_style.cpp:73] [in E:\Elzean Documents\Documents\Unreal Projects\FPS_Inventory\Binaries\Win64\UE4Editor-FPS_Inventory.dll]
SDE_InventorySlotWidget::GetButtonImage() 0xdbe96d98 + 5 bytes [File=e:\elzean documents\documents\unreal projects\fps_inventory\source\fps_inventory\private\ui\widgets\de_inventoryslotwidget.cpp:144] [in E:\Elzean Documents\Documents\Unreal Projects\FPS_Inventory\Binaries\Win64\UE4Editor-FPS_Inventory.dll]
TBaseSPMethodDelegateInstance_RetVal_NoParams_Const<SDE_InventorySlotWidget,FSlateBrush const * __ptr64,0>::Execute() 0xdbe96772 + 12 bytes [File=e:\programs\unrealengine-4.0\engine\source\runtime\core\public	emplates\delegateinstancesimpl.inl:223] [in E:\Elzean Documents\Documents\Unreal Projects\FPS_Inventory\Binaries\Win64\UE4Editor-FPS_Inventory.dll]
Address = 0xe40c7633 (filename not found) [in E:\Programs\Unreal Engine\4.0\Engine\Binaries\Win64\UE4Editor-Slate.dll]
Address = 0xe41ba007 (filename not found) [in E:\Programs\Unreal Engine\4.0\Engine\Binaries\Win64\UE4Editor-Slate.dll]

I followed the StrategyGame example for most of my c++ classes, and i also took everything inside the UI folder.

The problem at line 144 of de_inventoryslotwidget.cpp is the “GetBrush” :


const FSlateBrush*  SDE_InventorySlotWidget::GetButtonImage() const
{
	if (ButtonImage.IsValid())
	{
		return ButtonImage.Get();
	} 
	else 
	{
		return FDE_Style::Get().GetBrush("InventorySlotBrush");
	}
}

And my DE_Style follow what is done in the StrategyGame :


// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.

#include "FPS_Inventory.h"
#include "DE_Style.h"
#include "SlateGameResources.h"

TSharedPtr< FSlateStyleSet > FDE_Style::DE_StyleInstance = NULL;

void FDE_Style::Initialize()
{
	if (!DE_StyleInstance.IsValid())
	{
		DE_StyleInstance = Create();
		FSlateStyleRegistry::RegisterSlateStyle(*DE_StyleInstance);
	}
}

void FDE_Style::Shutdown()
{
	FSlateStyleRegistry::UnRegisterSlateStyle(*DE_StyleInstance);
	ensure(DE_StyleInstance.IsUnique());
	DE_StyleInstance.Reset();
}

FName FDE_Style::GetStyleSetName()
{
	static FName StyleSetName(TEXT("DE_Style"));
	return StyleSetName;
}


#define IMAGE_BRUSH( RelativePath, ... ) FSlateImageBrush( FPaths::GameContentDir() / "Slate"/ RelativePath + TEXT(".png"), __VA_ARGS__ )
#define BOX_BRUSH( RelativePath, ... ) FSlateBoxBrush( FPaths::GameContentDir() / "Slate"/ RelativePath + TEXT(".png"), __VA_ARGS__ )
#define BORDER_BRUSH( RelativePath, ... ) FSlateBorderBrush( FPaths::GameContentDir() / "Slate"/ RelativePath + TEXT(".png"), __VA_ARGS__ )
#define TTF_FONT( RelativePath, ... ) FSlateFontInfo( FPaths::GameContentDir() / "Slate"/ RelativePath + TEXT(".ttf"), __VA_ARGS__ )
#define OTF_FONT( RelativePath, ... ) FSlateFontInfo( FPaths::GameContentDir() / "Slate"/ RelativePath + TEXT(".otf"), __VA_ARGS__ )

TSharedRef< FSlateStyleSet > FDE_Style::Create()
{
	TSharedRef<FSlateStyleSet> StyleRef = FSlateGameResources::New(FDE_Style::GetStyleSetName(), "/Game/UI/Styles", "/Game/UI/Styles");
	FSlateStyleSet& Style = StyleRef.Get();

	const FLinearColor GoldColor(FColor(255,213,160));

	// Fonts still need to be specified in code for now
	Style.Set("FPS_Inventory.MenuFont", TTF_FONT("Fonts/Roboto-Black", 32));

	Style.Set("FPS_Inventory.ResourcesTextStyle", FTextBlockStyle()
		.SetFont(TTF_FONT("Fonts/Roboto-Regular", 40))
		.SetColorAndOpacity(GoldColor)
		.SetShadowColorAndOpacity(FLinearColor::Black)
		.SetShadowOffset(FIntPoint(-1,1))
		);

	Style.Set("FPS_Inventory.ButtonFont", TTF_FONT("Fonts/Roboto-Black", 18));

	return StyleRef;
}

#undef IMAGE_BRUSH
#undef BOX_BRUSH
#undef BORDER_BRUSH
#undef TTF_FONT
#undef OTF_FONT

void FDE_Style::ReloadTextures()
{
	FSlateApplication::Get().GetRenderer()->ReloadTextureResources();
}

const ISlateStyle& FDE_Style::Get()
{
	return *DE_StyleInstance;
}

If i remove the widget using the brush everything else work.

Here is a pic of the brush in the editor :

Can someone see or think of something i’m doing wrong here ?

Thanks !

Seems like any call to the Style crash, not necessarly the brush then.

I saw a file in Shooter and strategyGame “StrategyGameModule.cpp” / “ShooterGameModule.cpp”. I tried to create one :


// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.

#include "FPS_Inventory.h"

#include "DE_Style.h"
//#include "StrategyHUDSoundsWidgetStyle.h"
//#include "StrategyHUDWidgetStyle.h"
//#include "StrategyMenuWidgetStyle.h"

#include "FPS_Inventory.generated.inl"

class FDE_GameModule : public FDefaultGameModuleImpl
{
	virtual void StartupModule() OVERRIDE
	{
		//Hot reload hack
		FSlateStyleRegistry::UnRegisterSlateStyle(FDE_Style::GetStyleSetName());
		FDE_Style::Initialize();
	}

	virtual void ShutdownModule() OVERRIDE
	{
		FDE_Style::Shutdown();
	}
};

IMPLEMENT_PRIMARY_GAME_MODULE(FDE_GameModule, FPS_Inventory, "FPS_Inventory");

DEFINE_LOG_CATEGORY(LogGame)

But the compiler give me some errors :


1>------ Build started: Project: FPS_Inventory, Configuration: Development_Editor x64 ------
1>  DE_GameModule.cpp
1>E:\Elzean Documents\Documents\Unreal Projects\FPS_Inventory\Source\FPS_Inventory\Private\DE_GameModule.cpp(29): error C2146: syntax error : missing ';' before identifier 'LogGame'
1>E:\Elzean Documents\Documents\Unreal Projects\FPS_Inventory\Source\FPS_Inventory\Private\DE_GameModule.cpp(29): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>  -------- End Detailed Actions Stats -----------------------------------------------------------
1>ERROR : UBT error : Failed to produce item: E:\Elzean Documents\Documents\Unreal Projects\FPS_Inventory\Binaries\Win64\UE4Editor-FPS_Inventory.pdb
1>  Cumulative action seconds (8 processors): 0.00 building projects, 0.10 compiling, 0.00 creating app bundles, 0.00 generating debug info, 0.00 linking, 0.00 other
1>  UBT execution time: 8.66 seconds
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.MakeFile.Targets(38,5): error MSB3073: The command "E:\Programs\UnrealEngine-4.0\Engine\Build\BatchFiles\Build.bat FPS_InventoryEditor Win64 Development "E:\Elzean Documents\Documents\Unreal Projects\FPS_Inventory\FPS_Inventory.uproject"" exited with code -1.
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========

How do i create those files ? Do you think it can be related to my problem with the style ?

You will get memory errors when you pass your resources by value instead of by reference. You shouldn’t be making any copies of the resources (by value), always access the resources by reference. To be clear, there should only be a single object in memory for your Slate resources, when you pass by value it makes extra copies which, while it could probably be done with some extra work (requiring in depth knowledge of Slate memory footprint), it isn’t the de-facto way supported by the UE4 framework.

Thanks for your reply, I’m not sure where i am calling it by value ? Isn’t the style class the point to avoid this situation ?

in my widgets i call this :


FDE_Style::Get().GetBrush("InventorySlotBrush");

Which call “get” inside my style class :


const ISlateStyle& FDE_Style::Get()
{
	return *DE_StyleInstance;
}

Then every resources is actually called by this style.

But yes the error only happen during a “GetBrush” or a “GetTextFont”, anything that seems to require a file crash my editor, right now i dont even get a stack error anymore, the log just say “Fatal error”…

This style class always has the same kind of setup, they use it in their game samples but also in several place inside the editor, i can’t find what i’m doing wrong here :confused:

Edit :
From what i understand every Style is initialize as some sort of Singleton (im not a c++ guru so i am not sure here), they are instantiated when the program start and every widget using one or another is calling the Style needed throw the static function “Get” (of the corresponding style). This seems to be the recurrent pattern for styles and widgets all over UE4. I can’t get it right and i’m stuck, i would really like to make it work with the same pattern as they do.

You’re very close, it seems that you just need to initialise your style instance when your module is loaded (your Get() call doesn’t do this).

The code you have to initialise your module is failing to compile due to the DEFINE_LOG_CATEGORY(LogGame) line. If you look in StrategyGame.h you’ll see that it has the following:
DECLARE_LOG_CATEGORY_EXTERN(LogGame, Log, All);

You can either add that to your own games header (FPS_Inventory.h), or just remove the DEFINE_LOG_CATEGORY(LogGame) line.

As i said here : Slate Style crash the editor - UE4 AnswerHub

Correcting the module class fixed mostly everything, i finally got some sort of inventory grid to show up :slight_smile:

Now that i have the full skeleton of Slate + Style working in what seems the “right” way, i should be able to move forward !

Thanks a lot for your help !