UE4为组件Component注册事件时没有效果的问题解决


按照UE4的教程:

.h文件:

// 在 Project Settings 的 Description 页面填入版权声明。
#pragma once
#include "GameFramework/Actor.h"
#include "FPSProjectile.generated.h"
UCLASS()
class FPSPROJECT_API AFPSProjectile : public AActor
{
    GENERATED_BODY()
public: 
    // 设置该 actor 属性的默认值
    AFPSProjectile();
    // 游戏开始时或生成时调用
    virtual void BeginPlay() override;
    // 每帧调用
    virtual void Tick( float DeltaSeconds ) override;
    // 球体碰撞组件。
    UPROPERTY(VisibleDefaultsOnly, Category = Projectile)
    USphereComponent* CollisionComponent;
    // 发射物运动组件。
    UPROPERTY(VisibleAnywhere, Category = Movement)
    UProjectileMovementComponent* ProjectileMovementComponent;
    // 在发射方向上设置发射物初速度的函数。
    void FireInDirection(const FVector& ShootDirection);
    // 发射物命中物体时调用的函数。
    void OnHit(UPrimitiveComponent* HitComponent, class AActor* OtherActor, class UPrimitiveComponent* OtherComponent, FVector NormalImpulse, const FHitResult& Hit);
};

cpp文件:

// 在 Project Settings 的 Description 页面填入版权声明。
#include "FPSProject.h"
#include "FPSProjectile.h"
// 设置默认值
AFPSProjectile::AFPSProjectile()
{
    // 将此 actor 设为每帧调用 Tick()。不需要时可将此关闭,以提高性能。
    PrimaryActorTick.bCanEverTick = true;
    // 使用球体代表简单碰撞。
    CollisionComponent = CreateDefaultSubobject(TEXT("SphereComponent"));
    CollisionComponent->BodyInstance.SetCollisionProfileName(TEXT("Projectile"));
    CollisionComponent->OnComponentHit.AddDynamic(this, &AFPSProjectile::OnHit);
    // 设置球体的碰撞半径。
    CollisionComponent->InitSphereRadius(15.0f);
    // 将碰撞组件设为根组件。
    RootComponent = CollisionComponent;
    // 使用此组件驱动此发射物的运动。
    ProjectileMovementComponent = CreateDefaultSubobject(TEXT("ProjectileMovementComponent"));
    ProjectileMovementComponent->SetUpdatedComponent(CollisionComponent);
    ProjectileMovementComponent->InitialSpeed = 3000.0f;
    ProjectileMovementComponent->MaxSpeed = 3000.0f;
    ProjectileMovementComponent->bRotationFollowsVelocity = true;
    ProjectileMovementComponent->bShouldBounce = true;
    ProjectileMovementComponent->Bounciness = 0.3f;
    // 3 秒后消亡。
    InitialLifeSpan = 3.0f;
}
// 游戏开始时或生成时调用
void AFPSProjectile::BeginPlay()
{
    Super::BeginPlay();
}
// 每帧调用
void AFPSProjectile::Tick( float DeltaTime )
{
    Super::Tick( DeltaTime );
}

// 在发射方向上设置发射物初速度的函数。
void AFPSProjectile::FireInDirection(const FVector& ShootDirection)
{
    ProjectileMovementComponent->Velocity = ShootDirection * ProjectileMovementComponent->InitialSpeed;
}
// 发射物命中物体时调用的函数。
void AFPSProjectile::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, FVector NormalImpulse, const FHitResult& Hit)
{
    if (OtherActor != this && OtherComponent->IsSimulatingPhysics())
    {
        OtherComponent->AddImpulseAtLocation(ProjectileMovementComponent->Velocity * 100.0f, Hit.ImpactPoint);
    }
}


运行后发现OnHit并没有触发。

改成下面即可解决问题:

.h文件:

// Fill out your copyright notice in the Description page of Project Settings.
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/SphereComponent.h"
#include "GameFramework/ProjectileMovementComponent.h"
#include "DelegateCombinations.h"
#include "FPSProjectile.generated.h"

UCLASS()
class FPSPROJECT_API AFPSProjectile : public AActor
{
	GENERATED_BODY()
	
public:
	UPROPERTY(VisibleDefaultsOnly, Category = Projectile)
		USphereComponent* CollisionComponent;

	UPROPERTY(VisibleAnywhere, Category = Movement)
		UProjectileMovementComponent* ProjectileMovementComponent;
	
public:	
	// Sets default values for this actor's properties
	AFPSProjectile();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// 在发射方向上设置发射物初速度的函数。
	void FireInDirection(const FVector& ShootDirection);
	
	UFUNCTION() 	void OnHit(UPrimitiveComponent* HitComponent, class AActor* OtherActor, class UPrimitiveComponent* OtherComponent, FVector NormalImpulse, const FHitResult& Hit);
};

在事件的前面加上
UFUNCTION()
修饰符即可。