Is there an object-independent way to get a reference to the game-instance? As I understand it, there can only ever be one active game-instance, so why wouldn’t there be a kind of global reference to it somewhere?
From within actors, you can easily find every “meta-object” (world, game-instance/state/mode etc.) with one or two member-function calls. That’s not the problem. The problem is UObject-derived classes, because they don’t seem to have any connection/reference to any of those meta-objects at all. And I would really like to avoid giving each and every UObject a pointer to the game-instance, because this would feel extremely redundant.
By the way, I already had a workaround for this problem: In my derived GameInstance-class I kept a static pointer to itself (its created instance) that could be used from everywhere. Setting it up and avoiding conflicts with the “Default__…”-objects that the engine creates internally, took a few more workarounds, but ultimately it worked.
But then I decided to implement multiplayer into my project and there is no way I can keep using static pointers that work with multiple simulated clients in PIE (with a hundred more workarounds, maybe…) that each have their own instance of the game-instance-class.
I believe the proper solution is to give such classes a path to the world by overriding GetWorld(). The following definition should work for most purposes:
This obviously assumes that the object is always constructed with an outer that itself has a path to the world. If that’s not the case you might need to get a little more complicated.
You contradict yourself. You want a function that returns a singleton but then you acknowledge that in some cases there may be more than one valid instance. GameInstances are inevitably tied to UWorlds, there is no getting around that.
It’s been 3 years since I worked on this and I’m not sure what you’re talking about. This problem was solely related to the way that UE4 simulates multiplayer matches in PIE. I don’t remember the details, but I think the issue here was that the simulated clients don’t have their own singletons for all classes but sometimes share the same ones (and the same RAM) like it would never happen in a (non-splitscreen…) multiplayer game. This made testing in the editor impossible. The other instances were the default objects created by the engine, if that’s what you’re talking about. They are not exactly “valid” and I handled them. I don’t see any contradiction here…
Sorry about that, I didn’t notice the date. In multiplayer PIE each client receives a different GameInstance, which is why if you want to support multiplayer PIE you can not have a global function. You would need some reference to a UWorld or other singleton class first. That is what I meant.
My example works if the outer is an actor, a UMG widget class, or even the game instance itself (I’ve done this for a few global objects, constructing them in the instance’s Init() function with the instance as the outer). A slight variant would most likely also work if you can set the world as the object’s outer. If you can’t do any of these, it would certainly complicate things; I think the principal of overriding GetWorld() somehow can still work though…