Two issues.
- You want to have WaitingRoom be a pointer to a UStaffUnit object.
UStaffUnit* WaitingRoom
It’s trying to store the whole UStaffUnit in the class otherwise, which UE4 doesn’t like. It likes to handle the pool of memory that all UObjects are spawned into, and only give your classes a pointer to where it is.
Which leads into the second problem.
- Because UE4 wants to handle memory management of UObjects, you will also need to add a UPROPERTY() macro above it. This adds a bit of code so UE4’s garbage collector can see if a UObject is still in use by someone. Without the UPROPERTY() macro, the garbage collector will not count UStaffManagers as needing the UStaffUnit that WaitingRoom points to. In other words? UE4 will just delete it out from under you.
So you should have, instead:
UCLASS()
class CODE_API UStaffManager : public UObject
{
GENERATED_BODY()
private:
UPROPERTY() //I'd put one here, too, just to be safe.
TArray<UStaffUnit*> RegularUnits;
UPROPERTY() //Prevents GC from deleting the UStaffUnit pointed at by WaitingRoom until it's nullified here (and everywhere else).
UStaffUnit* WaitingRoom;
public:
UStaffManager();
~UStaffManager();
TArray<UStaffUnit*>& GetRegularUnits() { return RegularUnits; }
UStaffUnit& GetWaitingRoom() { return WaitingRoom; }
};
If you need to spawn a UStaffUnit, then do it in a game thread function (such as the constructor, beginplay, or whatever) and store the returned pointer in a pointer slot that has a UPROPERTY() macro over it.
//In some method, like the constructor, beginplay, tick, one that you create and call, or whatever.
//It needs to be on the main (game) thread, though, but you would know if it isn't (because you'd need to intentionally spawn the FRunnable or whatever).
WaitingRoom = NewObject<UStaffUnit>(this, UStaffUnit::StaticClass());
Alternatively, if you actually did want an object to be stored in UStaffManager, and it doesn’t need the benefits of being a UObject, you could use a UStruct or a standard C++ object. Those can be directly held in a UCLASS header file. If you made it a USTRUCT, it would need to be called FStaffUnit, though. I’m pretty sure spawning it as a UObject and storing a pointer with a UPROPERTY() is what you want to do, though.
Your code compiles because it’s valid C++, even though UE4 rejects it for UObject-derived classes.