Been working on a small multiplayer game that ain’t too big and I have recently run in to a problem I can’t solve during package build testing. After Lobby when I enter my battle map, I can play perfectly for 1 minute but after that if I switch my UI the game crashes when creating Widgets. I switch between Battle and Result UI, and you can enter back to battle if needed. I had a similar problem with my Battle Camera but I fixed that by making a different camera inside Character class instead of having a separate camera class.
Any help would be greatly appreciated since I’m stuck atm.
The problem occurs when I call createWidget() function. I also did try a normal CreateWidget but that also crashes for some reason.
Error Log
[2017.09.30-19.25.44:570][385]LogMC: Warning: AMCBattleHud(25): GKCrash - CreateBattleWidgets - Create Widget on next Line
[2017.09.30-19.25.44:907][385]LogWindows: Error: === Critical error: ===
[2017.09.30-19.25.44:907][385]LogWindows: Error:
[2017.09.30-19.25.44:907][385]LogWindows: Error: Fatal error!
[2017.09.30-19.25.44:907][385]LogWindows: Error:
[2017.09.30-19.25.44:907][385]LogWindows: Error: Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0xffffffff
[2017.09.30-19.25.44:907][385]LogWindows: Error:
[2017.09.30-19.25.44:907][385]LogWindows: Error: MystrasChampion.exe!0x00000000E25A6EE6
[2017.09.30-19.25.44:908][385]LogWindows: Error: MystrasChampion.exe!0x00000000E25D7B52
[2017.09.30-19.25.44:908][385]LogWindows: Error: MystrasChampion.exe!0x00000000E2B8F4A2
[2017.09.30-19.25.44:908][385]LogWindows: Error: MystrasChampion.exe!0x00000000E2B52AF2
[2017.09.30-19.25.44:908][385]LogWindows: Error: MystrasChampion.exe!0x00000000E2F0C6E6
Code
/**
* Check if we can create a widget or not
*/
FORCEINLINE bool areRequirementsOkay(const UWorld* inWorld, const UClass* inWidgetClass) const
{
MCLog("GKCrash - areRequirementsOkay - Enter");
// Check if World Exist
if (inWorld == nullptr)
{
MCLogError("Fail to have World");
return false;
}
// Check if we have Data Asset
if (WidgetAssetsHandler == nullptr)
{
MCLogError("Fail to have Data Asset");
return false;
}
// Check if we have a class
if (inWidgetClass == nullptr)
{
MCLogError("Fail to have User Class");
return false;
}
// Check if UI class is of type MCBaseUserWidget
if (inWidgetClass)
{
if (!inWidgetClass->IsChildOf(UMCBaseUserWidget::StaticClass()))
{
MCLogErrorFormat("Class '%s' Failed to be a class of UMCBaseUserWidget", *inWidgetClass->GetName());
return false;
}
}
MCLog("GKCrash - areRequirementsOkay - Exit Okay");
return true;
}
protected:
/**
* Creates a Widget and returns a value for storing
*/
template<class T>
T* createWidget(UClass* UserWidgetClass, int32 ZOrder = 0)
{
MCLog("GKCrash - createWidget - Enter");
T* foundClass = nullptr;
UWorld* const World = GetWorld();
bool const isCheckOkay = areRequirementsOkay(World, UserWidgetClass);
// Widget to Create
if(isCheckOkay)
{
MCLog("GKCrash - createWidget - CreateWidget");
foundClass = CreateWidget<T>(World, UserWidgetClass);
MCLog("GKCrash - createWidget - AddToViewport");
foundClass->AddToViewport(ZOrder);
}
else
{
MCLogWarning("---------------- Fail to create a widget");
}
MCLogFormat("GKCrash - createWidget - Exit hasClass:%s", foundClass != nullptr ? TEXT("true") : TEXT("false") );
return foundClass;
}