UE4

UE4/C++ 弾丸を発射する 6 : 弾丸と発射

弾丸の作成です。
以下の手順で作成します。

アクターを作成する

全文 bullet00.h

/**
 * @file bullet00.h
 * @brief  弾丸
 * @author     inuvatico
 * @date        2020/11/08
 * @version     1.0
 * @copyright   2018 inuvatico
 * Released under the MIT license.
 *   see https://opensource.org/licenses/MIT
 * @par (new/Add/Change : 2020/10/17)
 *
*/
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Bullet00.generated.h"

class UHitComponent;

UCLASS()
class ABullet00 : public AActor
{
    GENERATED_BODY()
public:
    static AActor*Create(const UWorld *World, FVector pos, FRotator rot);
public:
    ABullet00();
protected:
    virtual void BeginPlay() override;
public:
    virtual void Tick(float DeltaTime) override;
private:
    float Time;
    UHitComponent* HitComponent;
};

全文 bullet00.cpp

/**
 * @file bullet00.cpp
 * @brief  弾丸
 * @author     inuvatico
 * @date        2020/11/08
 * @version     1.0
 * @copyright   2018 inuvatico
 * Released under the MIT license.
 *   see https://opensource.org/licenses/MIT
 * @par (new/Add/Change : 2020/10/17)
 *
*/
#include "Components/SphereComponent.h"
#include <uty/AttakDamageBase.h>
#include "bullet00.h"

//-----------------------------------------------------
//!弾丸の作成
//-----------------------------------------------------
AActor*ABullet00::Create(const UWorld *World, FVector pos, FRotator rot ) {
    AActor* Actor = nullptr;
    const FString path = "/Game/app/chr/bullet/Bullet00_00C.Bullet00_00C_C";
    TSubclassOf<class AActor> sc = TSoftClassPtr<AActor>(FSoftObjectPath(*path)).LoadSynchronous();
    if (sc != nullptr) {
        Actor = World->GetWorld()->SpawnActor<AActor>(sc);
        Actor->SetActorLocation(pos, false, nullptr, ETeleportType::ResetPhysics);
        Actor->SetActorRotation(rot);
    }
    return Actor;
}

//-----------------------------------------------------
// コンストラクタ
//-----------------------------------------------------
ABullet00::ABullet00()
{
    PrimaryActorTick.bCanEverTick = true;
}

//-----------------------------------------------------
// BeginPlay
//-----------------------------------------------------
void ABullet00::BeginPlay()
{
    Super::BeginPlay();
    Time = 5.0f;
    HitComponent = FindComponentByClass<UHitComponent>();
}

//-----------------------------------------------------
// Tick
//-----------------------------------------------------
void ABullet00::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    bool bDestroy = false;

    //移動処理
    {
        FRotator rot = GetActorRotation();
        float angl = FMath::DegreesToRadians(rot.Yaw);
        FVector vec(0, 0, 0);
        vec.X = cos(angl);
        vec.Y = sin(angl);

        vec *= DeltaTime * 100.0f * 4;
        vec += GetActorLocation();
        SetActorLocation(vec, true, nullptr, ETeleportType::TeleportPhysics);
    }

    Time -= DeltaTime;
    if (Time <= 0) {
        bDestroy = true;
    }

    if (HitComponent) {
        if (HitComponent->HitAtb) {
            bDestroy = true;
        }
    }

    if (bDestroy) {
        Destroy();
    }
}

アクターをBPにする

C++クラスからBullet00選び
ブループリントクラスを作成します。
vatico
 ↓
vatico

メッシュとコンポーネントを割り当てる

BPを開いてコンポーネントの追加から適当なMeshUHitComponentを追加する
vatico
&
vatico

Tagの設定

衝突検出をするコンポーネント('Mesh')にTag"NotifiyCollision"を設定する
vatico

物理設定とコリジョン設定

必要に応じて物理設定とコリジョン設定を行う
vatico

ACppPlayerControllerから弾丸を発射する

ACppPlayerController.cppにbullet/bullet00.hをインクルードし、
ABullet00::Create()を呼び出します。

//-------------------------------------------------
//! 攻撃(SHOOT)
//-------------------------------------------------
void ACppPlayerController::ActAttack1(CallType type) 
{
    if (CallType::INIT == type) {
        MyActor->AnmStateComponent->SetAnmIndex(UAnmIndex::ANMID_ATTACK1);
    }if (CallType::ACT == type) {

        //射撃1
        if (MyActor->AnmStateComponent->AnmEventBit& (1 << static_cast<int>(UAnmEvent::ST_SHOOT1))) {
            auto pos = MyActor->GetMesh()->GetSocketLocation("Muzzle_01");
            auto rot = MyActor->GetActorRotation();
            ABullet00::Create(MyActor->GetWorld(), pos,rot);
            MyActor->AnmStateComponent->ClearEventNo((int)UAnmEvent::ST_SHOOT1);
        }

        //射撃2
        if (MyActor->AnmStateComponent->AnmEventBit& (1 << static_cast<int>(UAnmEvent::ST_SHOOT2))) {
            MyActor->AnmStateComponent->ClearEventNo((int)UAnmEvent::ST_SHOOT2);
            auto pos = MyActor->GetMesh()->GetSocketLocation("Muzzle_02");
            auto rot = MyActor->GetActorRotation();
            ABullet00::Create(MyActor->GetWorld(), pos, rot);
        }

        if (MyActor->AnmStateComponent->AnmEventBit& (1 << static_cast<int>(UAnmEvent::ST_END))) {
            SetAction(ActType::IdleRun);
            return;
        }
    }
}

位置はGetSocketLocation()で向きはMyActor->GetActorRotation();で取得しABullet00::Create()に渡しています。
これで射撃ができるようになりました。










digitalize
  始めました。