I’ve made an uobject and there isn’t a begin play function. I have a function I want to execute when the game has started. Is there a begin play alternative I could implement without game modes or creating an actor to fire the function? Perhaps using the GetWorld() function? Thanks!
The are right. UObject doesn’t know is World exist. When you create your UObject dynamically with NewObject function, you should pass an Outer(basically “Owner”) - some actor in the world.
To make it work out-of-box:
-
Create your own BeginPlay() function
-
Override PostInitProperties() function(called after the C++ constructor) and call your BeginPlay() in it. But you should be carefull, this function is called in editor too, so you should first check, if World exist.
void UMyObject::PostInitProperties()
{
Super::PostInitProperties();//Called in game, when World exist . BeginPlay will not be called in editor if(GetWorld()) { BeginPlay(); }
}
-
Override GetWorld() function in your UObject
UWorld* UMyObject::GetWorld() const
{
// Return pointer to World from object owner, if we don’t work in editor
if (GIsEditor && !GIsPlayInEditorWorld)
{
return nullptr;
}
else if (GetOuter())
{
return GetOuter()->GetWorld();
}
return nullptr;
}
Thats all, now you have BeginPlay() for your UObject.
Have a nice day)
Hi! In fact UObject is the base class for all assets, including those that are not intended to be adding on level, that’s why UObject class doesnt contain any logic for that (BeginPlay, EndPlay and so on). As for you UObject - where and who creates it (Actor, Player Controller, etc)?
I know, but I mean like an event that is fired when the world or game has started, not when the object is in the world which is impossible, which is also why in the title of my question I said equivalent of begin play(), a function or event that would be handled similarly like begin play. I would probably do the implementation on construct, the binding etc.
- Global Delegates
- FWorldDelegates::OnPostWorldCreation
- FWorldDelegates::OnPostWorldInitialization
- LevelsChangedEvent
- Global actors
- Game Instance Begin Play
- Game Mode Begin Play
- Or your custom global manager actor if you have
Try override this methods for UObject:
virtual void PostInitProperties();
virtual void PostLoad();
Checkers:
FApp::CanEverRender()
FApp::IsGame() // #if WITH_EDITOR
Maybe this get some direction for research.
EDIT: Also check FCoreDelegates
OnBeginFrame
OnSamplingInput
OnInit
OnPostEngineInit
OnFEngineLoopInitComplete
Yes. FWorldDelegates more right direction.)
Could you show me a quick example on binding the delegate on post world creation. I’m new to delegates in c++ and it’s a little bit confusing. I don’t need an explanation I just need an example on setting it up. Thanks!
- Defenition for FWorldDelegates::OnPostWorldCreation
DECLARE_MULTICAST_DELEGATE_OneParam(FWorldEvent, UWorld* /World/);
FWorldDelegates::OnPostWorldCreation.AddUobject(yourObj, &UYourClass::OnPostWorldCreation);
UFUNCTION()
void OnLevelsChangedEvent(UWorld* world);
- Defenition for FWorldDelegates::OnPostWorldInitialization
DECLARE_MULTICAST_DELEGATE_TwoParams(FWorldInitializationEvent, UWorld* /World/, const UWorld::InitializationValues /IVS/);
FWorldDelegates::OnPostWorldInitialization.AddUobject(yourObj, &UYourClass::OnPostWorldCreation);
UFUNCTION()
void OnLevelsChangedEvent(UWorld* world, const UWorld::InitializationValues);
- Defenition for LevelsChangedEvent
DECLARE_EVENT(UWorld, FOnLevelsChangedEvent);
GetWorld()->LevelsChangedEvent.AddUobject(yourObj, &UYourClass::OnLevelsChangedEvent);
UFUNCTION()
void OnLevelsChangedEvent();
Here is docs: Delegates | Unreal Engine Documentation
Defenition for
FWorldDelegates::OnPostWorldCreationDECLARE_MULTICAST_DELEGATE_OneParam(FWorldEvent,
UWorld* /World/);FWorldDelegates::OnPostWorldCreation.AddUobject(yourObj,
&UYourClass::OnPostWorldCreation);
thanks, in my case GIsPlayInEditorWorld is always false (4.26). I’m using: if (FApp::IsGame()).
Since it can be somewhat difficult to understand what zSSkitzz has written, here again in simpler terms. Create a function.
UFUNCTION()
void beginPlay(UWorld* world);
Then in the constructor or somewhere else bind the function to the event.
FWorldDelegates::OnPostWorldCreation.AddUObject(this, &UMyClass::beginPlay);