今天來製作第二個魔法攻擊:追蹤彈,使用UE5的 Projectile Movement Component 來製作
Blueprint 或 C++ 都可以加 Porjectile Component,但我這裡用 C++ 來做投射物的 Base。
ProjectileBase.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/ProjectileMovementComponent.h"
#include "ProjectileBase.generated.h"
UCLASS()
class ITHOME30DAYS_API AProjectileBase : public AActor
{
	GENERATED_BODY()
public:
	AProjectileBase();
	virtual void BeginPlay() override;
	
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Movement")
	UProjectileMovementComponent* ProjectileComp;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Projectile Settings")
	float InitialSpeed = 300.f;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Projectile Settings")
	float MaxSpeed = 800.f;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Projectile Settings")
	float ProjectileGravityScale = 0.f;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Projectile Settings")
	bool bIsHoming = false;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Projectile Settings")
	bool bRotationFollowVelocity = bIsHoming;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Projectile Settings")
	float HomingAccelerationMagnitude = 2000.f;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Projectile Settings")
	USceneComponent* HomingTarget = nullptr;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Projectile Settings")
	float Damage = 5.f;
};
ProjectileBase.cpp
#include "ProjectileBase.h"
AProjectileBase::AProjectileBase()
{
	PrimaryActorTick.bCanEverTick = true;
	// 預先創建 Projectile Component
	ProjectileComp = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileComp"));
}
void AProjectileBase::BeginPlay()
{
	Super::BeginPlay();
	ProjectileComp->InitialSpeed = InitialSpeed;
	ProjectileComp->MaxSpeed = MaxSpeed;
	ProjectileComp->ProjectileGravityScale = ProjectileGravityScale;
	ProjectileComp->bIsHomingProjectile = bIsHoming;
	ProjectileComp->bRotationFollowsVelocity = bRotationFollowVelocity;
	ProjectileComp->HomingAccelerationMagnitude = HomingAccelerationMagnitude;
}
在敵人身上 加一個 Scene Component (HomingTarget)作為導彈目標,因為 Projectile Component 的 Homing Target 只接收 "Component" 而非 FVector Location
跟之前創建武器一樣,創建 Blueprint 時選擇 ProjectileBase 作為 Parent。

MagicWeapon.hUPROPERTY(EditAnywhere, Category = "Weapon")
TArray<TSubclassOf<AActor>> Magics = {};
// 還有加一個攻擊函式
UFUNCTION()
virtual void BookMagicProj();
MagicWeapon.cpp
void AMagicWeapon::BookMagicProj()
{
    if (!Magics[1]) return;
    // 從魔法書發射
    const FVector Loc = OwnerChar->GetMesh()->GetSocketLocation(AttachSocketName);
    
    AActor* ProjActor = GetWorld()->SpawnActor<AActor>(Magics[1], Loc, (OwnerChar->TargetActor != nullptr) ? FRotator(90,0,0) : OwnerChar->GetActorRotation());
        
    if (AProjectileBase* Projectile = Cast<AProjectileBase>(ProjActor))
    {
        Projectile->Damage = Damage*1.5;
        
        if (OwnerChar->TargetActor != nullptr)
        {
            Projectile->bIsHoming = true;
            USceneComponent* HomingPoint = Cast<USceneComponent>(OwnerChar->TargetActor->GetDefaultSubobjectByName(TEXT("HomingTarget")));
            Projectile->ProjectileComp->HomingTargetComponent = HomingPoint ? HomingPoint : OwnerChar->TargetActor->GetRootComponent();
        }
        else
        {
            Projectile->bIsHoming = false;
        }
    }
}
然後就
