probably the reason the Compiler/tool-chain is not yelling at you about the “U” is because you are missing UCLASS()
and GENERATED_BODY()
for the reflection system, but if this class was created as a “blank C++ class” then adding it to the reflection system can be slightly annoying.
by having it be a UCLASS()
with GENERATED_BODY()
you can give it UPROPERTY()
(so that you can examine the states in the Editor) and UFUNCTION()
(so that this maybe could be called through blueprints, Events/Functions)
is this EnterState()
a pass through to an engine function, or are you doing something separate to the engine’s built in state machine system.
either through logging(UE_LOG()
or GEngine->AddOnScreenDebugMessage()
) or by stepping through with an IDE debugger does anything about the CurrentState or the members it accesses become null?
a memory access violation is typically:
- attempting to access a null pointer
- attempting to access a memory block that has been thread locked
- attempting to access memory that has not been allocated to the program (the OS should prevent this, and if that failsafe fails it often results in a memory dump)
could you wrap your accesses of States inside a check to see if it was created correctly
if( States = NewObject<PlayerStateFactory>(this))
{
UE_LOG(LogTemp, Warning, TEXT("States was created %s"), *GetName());
CurrentState = States->Idle();
CurrentState->EnterState();
}
else
{
UE_LOG(LogTemp, Error, TEXT("States was not created %s", *GetName());
}
if an entity is creating its own factory then that doesn’t seam like a factory, but rather a controller: a Factory is typically a static (or near static singleton) entity that is solely responsible for creating things as needed, and then hands them out to the requester, or just puts them into place. typically they do not modify the state of the Thing after it is handed out.
a Controller is either static (near static singleton), or per Entity thing that needs to be controlled (this is probably the most dangerous because if every thing needs its own manager this should either be unified into a static or near static singleton, or let the thing control its own state)
for the static implementation this can be done through creating a Subsystem a C++ exclusive feature with some Additional reading (Unreal-style Singletons with Subsystems · ben🌱ui) in which case you do get Singleton, and by making it a subsystem you match its lifespan to the lifespan of the thing it is a subsystem of, for example if this was to be a subsystem of UWorld
(as a UWorldSubsystem
) it would have the same lifespan as the UWorld
and subsystems are “effectively” not needed to be instantiated manually as long as they are declared appropriately which the compiler/tool-chain will enforce.
the biggest downside to subsystems is the inability to assign data member in the editor to/for them as they are instantiated silently by the Engine (even the ones that exist in the level before PIE will be instantiated from defaults), and are one of the exceptions to instantiated things “needing” actual blueprints (or fake blueprints) to be instantiated.