언어:
페이지 정보
수준별:
엔진 버전:
언리얼 엔진

3.4 - 월드와 상호작용하는 프로젝타일

언리얼 엔진

프로젝타일의 콜리전 상호작용을 감지할 수 있으니, 이제 그 콜리전에 어떻게 반응할지를 결정하면 됩니다. 이번 단계에서는, 콜리전 이벤트에 반응하는 FPSProjectileOnHit 함수를 추가하겠습니다.

프로젝타일이 콜리전에 반응하도록 만들기

  1. Solution Explorer 에서 FPSProjectile 클래스 헤더 파일을 찾고 FPSProjectile.h 를 엽니다.

  2. FPSProjectile 클래스 정의에 다음 코드를 추가합니다:

    // 프로젝타일이 무언가에 맞으면 호출되는 함수입니다.
    UFUNCTION()
    void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, FVector NormalImpulse, const FHitResult& Hit);
  3. FPSProjectile.h 는 이제 다음과 같을 것입니다:

    // 프로젝트 세팅의 설명 페이지에 저작권 문구를 채우세요.
    
    #pragma once
    
    #include "GameFramework/Actor.h"
    #include "FPSProjectile.generated.h"
    
    UCLASS()
    class FPSPROJECT_API AFPSProjectile : public AActor
    {
        GENERATED_BODY()
    
    public: 
        // 이 액터 프로퍼티의 기본값을 설정합니다.
        AFPSProjectile();
    
    protected:
        // 게임 시작 또는 스폰 시 호출됩니다.
        virtual void BeginPlay() override;
    
    public:
        // 매 프레임 호출됩니다.
        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, AActor* OtherActor, UPrimitiveComponent* OtherComponent, FVector NormalImpulse, const FHitResult& Hit);
    };
  4. Solution Explorer 에서 FPSProjectile 클래스 CPP 파일을 찾고 FPSProjectile.cpp 를 열고 다음 코드를 추가합니다:

    // 프로젝타일에 무언가 맞으면 호출되는 함수입니다.
    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 는 이제 다음과 같은 모습일 것입니다:

    // 프로젝트 세팅의 설명 페이지에 저작권 문구를 채우세요.
    
    #include "FPSProject.h"
    #include "FPSProjectile.h"
    
    // Sets default values
    AFPSProjectile::AFPSProjectile()
    {
        // 이 액터가 매 프레임 Tick() 을 호출하도록 설정합니다. 필요치 않은 경우 끄면 퍼포먼스가 향상됩니다.
        PrimaryActorTick.bCanEverTick = true;
    
        // 구체를 단순 콜리전 표현으로 사용합니다.
        CollisionComponent = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
        CollisionComponent->BodyInstance.SetCollisionProfileName(TEXT("Projectile"));
        CollisionComponent->OnComponentHit.AddDynamic(this, &AFPSProjectile::OnHit);
    
        // 구체의 콜리전 반경을 설정합니다.
        CollisionComponent->InitSphereRadius(15.0f);
        // 루트 컴포넌트를 콜리전 컴포넌트가 되도록 설정합니다.
        RootComponent = CollisionComponent;
    
        // 이 컴포넌트를 사용하여 이 프로젝타일의 무브먼트를 구동시킵니다.
        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;
    
        // 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);
        }
    }
  7. Visual Studio 에서 FPSProjectile.hFPSProjectile.cpp 를 저장합니다.

  8. Solution Explorer 에서 FPSProject 를 찾습니다.

  9. FPSProject 에 우클릭한 다음 Build 를 선택하여 프로젝트를 빌드합니다.

    BuildFPSProject.png

프로젝타일 콜리전 테스트

  1. 빌드 완료 후, 언리얼 에디터 로 돌아가 FPSProject 를 엽니다.

  2. Floor StaticMesh 를 선택합니다.

  3. 바닥 메시를 복사 & 붙여넣기 합니다.

  4. 비율 고정이 풀렸는지 확인하고, (이름이 Floor2 인) 바닥 메시 사본의 스케일을 {0.2, 0.2, 3.0} 으로 설정합니다.

  5. 바닥 메시 사본 위치는 {320, 0, 170} 으로 조정합니다.

    이미지를 클릭하면 줌인합니다.

  6. Physics 섹션으로 스크롤해 내려간 뒤 Simulate Physics (피직스 시뮬레이션) 옵션을 체크합니다.

    이미지를 클릭하면 줌인 합니다.

  7. 맵을 저장하고 BP_FPSProjectile 에 더블클릭하여 프로젝타일 블루프린트를 편집용으로 엽니다.

  8. 클래스 디폴트 모드 를 열고 컴포넌트 탭에서 ProjectileMesh 를 클릭합니다.

  9. Collision 아래에서 Collision Presets 프로퍼티를 찾은 다음 Projectile 로 설정합니다..

    SetCollisionPresets.png

  10. 블루프린트를 컴파일, 저장 한 뒤 블루프린트 에디터 를 닫습니다.

  11. 레벨 에디터 툴바플레이 버튼을 클릭합니다.

  12. 좌클릭 하여 프로젝타일을 발사하고 레벨에 큐브를 이동시킬 수 있습니다.

    ProjectileComplete.png

    축하합니다, 프로젝타일이 완성되었습니다!

  13. 레벨 에디터에서 중지 버튼을 눌러 에디터에서 플레이 (PIE) 모드를 빠져나갑니다.