Uobject begin play() equivalent

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!

2 Likes

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:

  1. Create your own BeginPlay() function

  2. 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();
     }
    

    }

  3. 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)

2 Likes

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)?

1 Like

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.

  1. Global Delegates
  • FWorldDelegates::OnPostWorldCreation
  • FWorldDelegates::OnPostWorldInitialization
  • LevelsChangedEvent
  1. 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.)

1 Like

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::OnPostWorldCreation

DECLARE_MULTICAST_DELEGATE_OneParam(FWorldEvent,
UWorld* /World/);

FWorldDelegates::OnPostWorldCreation.AddUobject(yourObj,
&UYourClass::OnPostWorldCreation);

1 Like

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);

2 Likes