To make my UI as modular as possible, I’ve made it so input simply calls a pure virtual function in the currently active widget. I’ve done this by having SMainUserInterface (the SCanvas that stores and displays other widgets) store the currently active widget in a pointer of type SCompoundWidget, since all the widgets that can receive input derive from SCompoundWidget and this allows me to store any of them within one pointer. Then, I created a pure virtual class called InterfaceAction, which I make the widget classes inherit from when they need to be able to process input.
class InterfaceAction
{
public:
virtual ~InterfaceAction();
virtual void ActionButton() = 0;
virtual void CancelButton() = 0;
virtual void DetailsButton() = 0;
virtual void DeleteButton() = 0;
virtual void MoveCursorX(float AxisValue) = 0;
virtual void MoveCursorY(float AxisValue) = 0;
};
My problem is that, when the player controller wants to call any of these functions, I need to cast the SCompoundWidget pointer to InterfaceAction, which the Cast function doesn’t allow me to do. This:
if (PlayerUI.IsValid())
{
InterfaceAction* InterfaceCheck = Cast<InterfaceAction>(PlayerUI->ActiveWidget.Get());
if (InterfaceCheck)
{
InterfaceCheck->ActionButton();
}
}
Returns this error:
CompilerResultsLog:Error: Error C:\Program Files\Epic Games\4.13\Engine\Source\Runtime\CoreUObject\Public\Templates\Casts.h(178) : error C2664: ‘InterfaceAction *TCastImpl::DoCast(UObject *)’: cannot convert argument 1 from ‘SCompoundWidget *’ to ‘UObject *’
CompilerResultsLog: Info with
CompilerResultsLog: Info [
CompilerResultsLog: Info From=SCompoundWidget,
CompilerResultsLog: Info To=InterfaceAction
CompilerResultsLog: Info ]
CompilerResultsLog:Error: Error C:\Program Files\Epic Games\4.13\Engine\Source\Runtime\CoreUObject\Public\Templates\Casts.h(178) : note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
CompilerResultsLog:Error: Error C:\Users\Alexandra\Documents\Documents\Libera Me\Project Files\Libera_Me\Source\Libera_Me\Private\Controllers\PlayerUnitController.cpp(94) : note: see reference to function template instantiation ‘To *Cast(From *)’ being compiled
CompilerResultsLog: Info with
CompilerResultsLog: Info [
CompilerResultsLog: Info To=InterfaceAction,
CompilerResultsLog: Info ObjectType=SCompoundWidget,
CompilerResultsLog: Info From=SCompoundWidget
CompilerResultsLog: Info ]
I imagine this is because InterfaceAction doesn’t inherit from UObject in any way. However, C-style cast and function-style cast are both rather dangerous to use, and dynamic_cast is unavailable due to RTTI being disabled. What’s the best way for me to do this, then? I can’t use UE4’s Interface class because as far as I’m aware, they’re only made to be inherited by UObject-based classes, which SCompoundWidget is not.