iT邦幫忙

2025 iThome 鐵人賽

DAY 26
0

今天要製作魔法攻擊的功能,大概的概念是在敵人腳下產生向上爆發的魔力衝擊,造成傷害並將敵人擊飛。

1. Code

  • 上篇的 DoMagicStuff
void AMagicWeapon::DoMagicStuff()
{
    if (MeshMissile == nullptr) return;

    FHitResult HitResult_v;
    bool hit_v;

    float LaunchForce = 700.f;
  • 這裡用 Day 7 的視角鎖定,鎖定到的 Actor 來看要不要往玩家面前做判定,還是直接對 Actor 做攻擊。
    if (OwnerChar->TargetActor == nullptr)
    {
  • 這裡用兩個 LineTrace 一個往前射,如果碰到牆壁就往回退一點,再往下射另一個 Trace,目的是要找玩家面前的地面,可以做為生成特效的起點,像是大岩壁那種的。
        float AttackRange=500;
        float AttackDepth=500;
        float MagicWidth=50;
        
        FHitResult HitResult_h;
        FCollisionQueryParams Params;
        Params.AddIgnoredActor(MeshMissile.GetDefaultObject());
        
        FVector Start = OwnerChar->GetActorLocation();
        FVector End = OwnerChar->GetActorLocation() + OwnerChar->GetActorForwardVector()*AttackRange;
        
        bool hit_h = GetWorld()->LineTraceSingleByChannel(
            HitResult_h,
            Start,
            End,
            ECC_Visibility,
            Params
        );
        
        DrawDebugLine(
            GetWorld(),
            Start,
            hit_h ? HitResult_h.ImpactPoint : End,
            hit_h ? FColor::Green : FColor::Red,
            false,
            5,
            0,
            2
            );

        //FHitResult HitResult_v;
        FVector vStart = HitResult_h.ImpactPoint + HitResult_h.ImpactNormal*MagicWidth;
        hit_v = GetWorld()->LineTraceSingleByChannel(
            HitResult_v,
            hit_h ? vStart : End,
            hit_h ? vStart + vStart.UpVector*(-AttackDepth) : End + End.UpVector*(-AttackDepth),
            ECC_Visibility,
            Params
        );

        DrawDebugLine(
            GetWorld(),
            hit_h ? vStart : End,
            hit_v ? HitResult_v.ImpactPoint : End + End.UpVector*(-AttackDepth),
            hit_v ? FColor::Green : FColor::Red,
            false,
            5,
            0,
            2
            );
  • 如果有視角鎖定的目標的話,就直接在他腳下生成判定。
    }else
    {
        AActor* TargetA = OwnerChar->TargetActor;
        hit_v = true;
        HitResult_v.ImpactPoint = TargetA->GetActorLocation();
    }

    if (hit_v)
    {
        FActorSpawnParameters SpawnParams;
        SpawnParams.Owner = this;
        SpawnParams.Instigator = OwnerChar;
        
        GetWorld()->SpawnActor<AActor>(MeshMissile, HitResult_v.ImpactPoint, FRotator::ZeroRotator, SpawnParams);

        TArray<FHitResult> AHitResult;
        float Radius = 100.f;
        DrawDebugSphere(GetWorld(), HitResult_v.ImpactPoint, Radius, 12, FColor::Red, false, 2, 2);

        FCollisionQueryParams sParams;
        sParams.AddIgnoredActor(OwnerChar);
        sParams.AddIgnoredActor(this);

        bool AHit = GetWorld()->SweepMultiByObjectType(
            AHitResult,
            HitResult_v.ImpactPoint,
            HitResult_v.ImpactPoint,
            FQuat::Identity,                     // no rotation for sphere
            ECC_Pawn,                      // collision channel
            FCollisionShape::MakeSphere(Radius), // << sphere shape
            sParams
        );
  • 在攻擊時產生一個向上的力 (Impulse),將敵人往上擊飛。
        if (AHit)
            for (auto sHitResult : AHitResult)
            {
                DrawDebugSphere(GetWorld(), sHitResult.ImpactPoint, 20, 8, FColor::Green, false, 2, 2);
                if (AActor* HitActor = sHitResult.GetActor())
                {
                    if (UHealthComponent* HealthComp = HitActor->FindComponentByTag<UHealthComponent>("Damage"))
                    {
                        HealthComp->ApplyDamage(10.f, HitActor, sHitResult, WeaponType);
                        if (ACharacter* Char = Cast<ACharacter>(HitActor))
                            Char->LaunchCharacter(FVector(0,0,LaunchForce), true, true);
                        else
                            if (sHitResult.GetComponent()->IsSimulatingPhysics())
                                sHitResult.GetComponent()->AddImpulse(FVector(0,0,LaunchForce), NAME_None, true);
                    }
                }
            }
    }
}

2. 結果

  • 判斷面前的地面
    https://ithelp.ithome.com.tw/upload/images/20251010/20171036kSzHaJtwOV.png
  • 面對牆壁的情況
    https://ithelp.ithome.com.tw/upload/images/20251010/20171036XAeUsFKcsK.png
  • 在最後落點生成判定
    https://ithelp.ithome.com.tw/upload/images/20251010/20171036RApR1LU8NL.png
    https://ithelp.ithome.com.tw/upload/images/20251010/20171036pJB6pebIKB.png

完成!!!!!!!!!!!!!


上一篇
# Day 25|超超超加強武器模組化
系列文
30 天用 Unreal Engine 5 C++ 開發遊戲26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言