I still remember when I began to learn blueprint from the official document, actor communication can be realized by interface, cast-to or event dispatchers. According to the example, it will happen when player goes into a collision trigger, make the on actor begin overlap event in the blueprint to communicate with the player.
However, in the cpp version, the event dispatchers is explained as the delegate. At that time, I didnt realize the example as there are too many parameters in the bind event. Now I found an use case with delegate which is also the unreal FPS project template. The delegate is used for the projectile. When the projectile hits other actors, it calls the custom event OnHit() . Lets take a look at the projectile source code.
classAProjectile:public AActor { UPROPERTY() USphereComponent* CollisionComp; //U indicate this is a collision component rather than a mesh UFUNCTION() voidOnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit); }
AProjectile::AProjectile() { CollisionComp->OnComponentHit.AddDynamic(this, &AFPSCPPProjectile::OnHit); //seems like an event calls the custom function in the blueprint }
//not all the parameters are used, but the "other actor" and "other component" are the things that the projectile is hitting. If it has the physics feature, add an impulse depend on the projectile. the code is similiar to the blueprint event. voidAProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit) { if ((OtherActor != nullptr) && (OtherActor != this) && (OtherComp != nullptr) && OtherComp->IsSimulatingPhysics()) { OtherComp->AddImpulseAtLocation(GetVelocity() * 100.0f, GetActorLocation()); Destroy(); } }
Get into the engine source code.
The reason why USphereComponent reference can point to the OnComponentHit is that OnComponentHit is a signature of UPrimitiveComponent , its also considered as a delegate name.
1 2 3 4 5 6 7 8 9 10 11
//PrimitiveComponent.h
UCLASS() classENGINE_API UPrimitiveComponent : public USceneComponent, public INavRelevantInterface { UPROPERTY(BlueprintAssignable, Category="Collision") FComponentHitSignature OnComponentHit; //considered as an event which can be created in blueprint in the same name }
//long marco declaretion include parameters DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FiveParams( FComponentHitSignature, UPrimitiveComponent, OnComponentHit, UPrimitiveComponent*, HitComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, FVector, NormalImpulse, const FHitResult&, Hit );
How to bind a function to the delegate
1 2 3
//Delegate.h #define AddDynamic( UserObject, FuncName ) //OnComponentHit.AddDynamic(this, &AFPSCPPProjectile::OnHit) on the top
How to confirm the parameter in the custom function.
1 2 3 4
//SparseDelegate.h //as we can see, in the projectile example, there are five parameters #define DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FiveParams( SparseDelegateClass, OwningClass, DelegateName, Param1Type, Param1Name, Param2Type, Param2Name, Param3Type, Param3Name, Param4Type, Param4Name, Param5Type, Param5Name )
By the way, in the FPS blueprint template, event Hit is used to add impluse. The target of Hit is actor itself.
While in the cpp version, OnComponentHit is used which target is sphere collision. And it is actually including 5 parameters as we saw in the source code.
Above all is the summary of the projectile example.
Go back to the actor communication example.
I create the first actor including a box collision and a delegate.
The second actor bind the delegate.
When player overlap with the first box collision, delegate is active, and the second actor log a message.
//second actor classAReactActor { classATriggerActor* TriggerActorReference; voidGetIntoTrigger(){ UE_LOG(LogTemp, Log, TEXT("get into the trigger")); } }