3.4 - 発射物をワールドと相互作用させる

FPS プロジェクトで発射物をワールドと相互作用させる方法を学びます。

Windows
MacOS
Linux

発射物 (プロジェクタイル) のコリジョンの相互作用を検知できるようになったので、コリジョンの反応方法を決めることができます。このステップでは、OnHit 関数を collision event に反応する FPSProjectile に追加します。

発射物をコリジョンに反応させる

  1. Solution Explorer (ソリューション エクスプローラー) で、FPSProjectile クラス ヘッダ ファイルを探して、 FPSProjectile.h を開きます。

  2. 次のコードを FPSProjectile クラスの宣言に追加します。

    // Function that is called when the projectile hits something. (発射物が何かにぶつかると呼び出される関数)
    UFUNCTION()
    void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, FVector NormalImpulse, const FHitResult& Hit);
  3. FPSProjectile.h は以下のようになります。

    // Fill out your copyright notice in the Description page of Project Settings. (Project Settings の Description ページに著作権情報を入力してください) 
    
    #pragma once
    
    #include "GameFramework/Actor.h"
    #include "FPSProjectile.generated.h"
    
    UCLASS()
    class FPSPROJECT_API AFPSProjectile : public AActor
    {
        GENERATED_BODY()
    
    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 DeltaSeconds ) override;
        // Sphere collision component (Sphere collision コンポーネント)
        UPROPERTY(VisibleDefaultsOnly, Category = Projectile)
        USphereComponent* CollisionComponent;
    
        //Projectile movement component. (Projectile Movement コンポーネント)
        UPROPERTY(VisibleAnywhere, Category = Movement)
        UProjectileMovementComponent* ProjectileMovementComponent;
    
    // Function that initializes the projectile's velocity in the shoot direction. (発射方向に発射物のべロシティを初期化する関数)
        void FireInDirection(const FVector& ShootDirection);
    
    // Function that is called when the projectile hits something. (発射物が何かにぶつかると呼び出される関数)
        void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, FVector NormalImpulse, const FHitResult& Hit);
    };
  4. Solution Explorer で、FPSProjectile class CPP ファイルを探して、FPSProjectile.cpp を開いて以下のコードを追加します。

    // Function that is called when the projectile hits something. (発射物が何かにぶつかると呼び出される関数)
    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);
        }
    }
  5. FPSProjectile コンストラクタで、CollisionComp 作成の後に以下の行を追加します。

    CollisionComponent->OnComponentHit.AddDynamic(this, &AFPSProjectile::OnHit);
  6. FPSProjectile.cpp は以下のようになります。

    // Fill out your copyright notice in the Description page of Project Settings. (Project Settings の Description ページに著作権情報を入力してください) 
    
    #include "FPSProject.h"
    #include "FPSProjectile.h"
    
    // Sets default values (デフォルト値を設定) 
    AFPSProjectile::AFPSProjectile()
    {
        // Set this actor to call Tick() every frame. (フレーム毎に Tick() を呼び出すようにこのアクタを設定) You can turn this off to improve performance if you don't need it. (必要がなければパフォーマンスを向上させるためにオフにすることができます) 
        PrimaryActorTick.bCanEverTick = true;
    
        // Use a sphere as a simple collision representation (簡易なコリジョン表現に球体を使用)
        CollisionComponent = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
        CollisionComponent->BodyInstance.SetCollisionProfileName(TEXT("Projectile"));
        CollisionComponent->OnComponentHit.AddDynamic(this, &AFPSProjectile::OnHit);
    
        // Set the sphere's collision radius. (球体のコリジョン半径を設定します)
        CollisionComponent->InitSphereRadius(15.0f);
        // Set the root component to be the collision component. (ルート コンポーネントを collision コンポーネントに設定します)
        RootComponent = CollisionComponent;
    
        // Use this component to drive this projectile's movement. (このコンポーネントを使って発射物の動きを操作します)
        ProjectileMovementComponent = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileMovementComponent"));
        ProjectileMovementComponent->SetUpdatedComponent(CollisionComponent);
        ProjectileMovementComponent->InitialSpeed = 3000.0f;
        ProjectileMovementComponent->MaxSpeed = 3000.0f;
        ProjectileMovementComponent->bRotationFollowsVelocity = true;
        ProjectileMovementComponent->bShouldBounce = true;
        ProjectileMovementComponent->Bounciness = 0.3f;
    
        // Die after 3 seconds. (3 秒後に消滅)
        InitialLifeSpan = 3.0f;
    }
    
    // Called when the game starts or when spawned (ゲーム開始時またはスポーン時に呼び出される)
    void AFPSProjectile::BeginPlay()
    {
        Super::BeginPlay();
    
        }
    
    // Called every frame (フレームごとに呼び出される)
    
    void AFPSProjectile::Tick( float DeltaTime )
    {
        Super::Tick( DeltaTime );
    
    }
    
    // Function that initializes the projectile's velocity in the shoot direction. (発射方向に発射物のべロシティを初期化する関数)
    void AFPSProjectile::FireInDirection(const FVector& ShootDirection)
    {
        ProjectileMovementComponent->Velocity = ShootDirection * ProjectileMovementComponent->InitialSpeed;
    }
    
    // Function that is called when the projectile hits something. (発射物が何かにぶつかると呼び出される関数)
    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);
        }
    }
  7. FPSProjectile.hFPSProjectile.cpp を Visual Studio に保存します。

  8. [Solution Explorer (ソリューション エクスプローラ)][FPSProject] を探します。

  9. [FPSProject] 上で右クリックして [Build] を選択してプロジェクトをコンパイルします。

    BuildFPSProject.png

発射物のコリジョンをテストする

  1. ビルドが終了したら アンリアル エディタ に戻り、FPSProject を開きます。

  2. Floor StaticMesh を選択します。

  3. この floor メッシュをコピー&ペーストします。

  4. 比率の鍵を必ず解除して、floor メッシュのコピー ("Floor2" と呼びます) を {0.2, 0.2, 3.0} にスケーリングします。

  5. floor メッシュのコピーを {320, 0, 170} に配置します。

    ズームインするには画像をクリックします。

  6. [Physics] セクションまで下にスクロールして、[Simulate Physics] ボックスにチェックを入れます。

    ズームインするには画像をクリックします。

  7. マップを Save (保存) して、BP_FPSProjectile をダブルクリックして、編集のために projectile ブループリントを開きます。

  8. Class Defaults モード を開いて、 [Components] タブで [ProjectileMeshComponent] をクリックします。

  9. [Collision][Collision Presets] プロパティを探して、[ProjectileMeshComponent] に設定します。

    SetCollisionPresets.png

  10. ブループリントを コンパイル し、保存 してから、ブループリント エディタ を閉じます。

  11. レベル エディタのツールバー で、[Play In] ボタンをクリックします。

  12. 左クリックして発射物の発射およびキューブをレベル内で移動させます。

    ProjectileComplete.png

    これで発射物が完成しました!

  13. [PIE (Play In Editor)] モードを終了するには、レベル エディタで Escape キーを押すか、[Stop] ボタンをクリックします。

Select Skin
Light
Dark

Welcome to the new Unreal Engine 4 Documentation site!

We're working on lots of new features including a feedback system so you can tell us how we are doing. It's not quite ready for use in the wild yet, so head over to the Documentation Feedback forum to tell us about this page or call out any issues you are encountering in the meantime.

We'll be sure to let you know when the new system is up and running.

Post Feedback