[UE] ブループリントと C++ Beginplay の実行順序

Beginplay はレベルがロードされるときに実行され、実行時にのみ呼び出されます。では、C++のBeginplay関数とブループリントの実行順序はどうなるのでしょうか?

長すぎるのでバージョンを見ないでください

最初に結論からお話します。実際には、C++ が Beginplay 関数本体で親クラスの Beginplay メソッドを呼び出すタイミングに依存します。ブループリント BeginPlay の前に、親クラス BeginPlay を呼び出す前のロジックのみが実行されます。

ブループリントの BeginPlay は AActor::BeginPlay() メソッドで呼び出されるため

栗をあげる

例を見てみましょう

// Called when the game starts or when spawned
void ABeginplayOrderTest::BeginPlay()
{
    
    
	UE_LOG(LogTemp, Warning, TEXT("CPP Before BeginPlay"));
	Super::BeginPlay();
	UE_LOG(LogTemp, Warning, TEXT("CPP After BeginPlay"));
}

結果:
ここに画像の説明を挿入

ソースコード分析

Actor から継承されたオブジェクトは、Super::BeginPlay を呼び出した後、AActor::BeginPlay() に転送されます。

そして、この関数では、実際にはブループリントであるBlueprintImplementableEventメソッドが転送されます。ReceiveBeginPlay();Event BeginPlay

ReceiveBeginPlay();メソッド宣言:

//AActor.h
	/** Event when play begins for this actor. */
	UFUNCTION(BlueprintImplementableEvent, meta=(DisplayName = "BeginPlay"))
	void ReceiveBeginPlay();

フル機能本体:

// AActor.cpp
void AActor::BeginPlay()
{
    
    
	TRACE_OBJECT_EVENT(this, BeginPlay);

	ensureMsgf(ActorHasBegunPlay == EActorBeginPlayState::BeginningPlay, TEXT("BeginPlay was called on actor %s which was in state %d"), *GetPathName(), (int32)ActorHasBegunPlay);
	SetLifeSpan( InitialLifeSpan );
	RegisterAllActorTickFunctions(true, false); // Components are done below.

	TInlineComponentArray<UActorComponent*> Components;
	GetComponents(Components);

	for (UActorComponent* Component : Components)
	{
    
    
		// bHasBegunPlay will be true for the component if the component was renamed and moved to a new outer during initialization
		if (Component->IsRegistered() && !Component->HasBegunPlay())
		{
    
    
			Component->RegisterAllComponentTickFunctions(true);
			Component->BeginPlay();
			ensureMsgf(Component->HasBegunPlay(), TEXT("Failed to route BeginPlay (%s)"), *Component->GetFullName());
		}
		else
		{
    
    
			// When an Actor begins play we expect only the not bAutoRegister false components to not be registered
			//check(!Component->bAutoRegister);
		}
	}

	if (GetAutoDestroyWhenFinished())
	{
    
    
		if (UWorld* MyWorld = GetWorld())
		{
    
    
			if (UAutoDestroySubsystem* AutoDestroySys = MyWorld->GetSubsystem<UAutoDestroySubsystem>())
			{
    
    
				AutoDestroySys->RegisterActor(this);
			}			
		}
	}

	ReceiveBeginPlay();

	ActorHasBegunPlay = EActorBeginPlayState::HasBegunPlay;
}

おすすめ

転載: blog.csdn.net/weixin_44559752/article/details/127177576