UE4 C++ 델리게이트_2


Tags :


30 이벤트 델리게이트와 델리게이트의 블루프린트 오버라이드를 활용한 트리거들을 구현해보자

폭발이펙트 트리거

접근하면 폭발 Particle을 실행하는 Trigger 구현하기

활용 델리게이트 유형 : 이벤트 델리게이트

  • DECLARE_EVENT_OneParam
  • 멀티캐스트 델리게이트와 유사하고, 다수의 이벤트 바인딩이 가능하지만, 델리게이트 생성 시 클래스내에서 선언이 되어야 하고, 선언한 클래스에서만 Broadcast, IsBound, Clear함수 호출이 가능하다

EventTrigger

C++ Actor클래스로 C06_EventTrigger클래스 생성하기
캐릭터와 Component Begin Overlap 판정될 때, C06_Explosion클래스의 랜덤 폭발 Particle을 실행 할 함수 OnExplosion을 Call하도록 델리게이트 FExplosionEvent 구현하기

  • 헤더
    #pragma once
    #include "CoreMinimal.h"
    #include "GameFramework/Actor.h"
    #include "C06_EventTrigger.generated.h"
        
      UCLASS()
      class U03_BASIC_API AC06_EventTrigger : public AActor
      {
          GENERATED_BODY()
            
      private:
          DECLARE_EVENT_OneParam(AC06_EventTrigger, FExplosionEvent, int32);
            
      public:	
          AC06_EventTrigger();
            
      protected:
          virtual void BeginPlay() override;
            
      private:
          UPROPERTY(VisibleAnywhere)
              class USceneComponent*      Root;
          UPROPERTY(VisibleAnywhere)
              class UBoxComponent*        Box;
          UPROPERTY(VisibleAnywhere)
              class UTextRenderComponent* Text;
        
      private:
          UFUNCTION()
              void OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor,
              UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
        
      public:
          FExplosionEvent OnExplosionEvent;
            
      };
    
  • 소스
    생성자의 컴포넌트 생성과정은 동일하니 생략
    BeginPlay에서 AddDynamic
      void AC06_EventTrigger::BeginPlay()
      {
          Super::BeginPlay();
            
          Box->OnComponentBeginOverlap.AddDynamic(this, &AC06_EventTrigger::OnComponentBeginOverlap);
      }
    

    OnComponentBeginOverlap에서 OnExplosionEvent에 바인드된 함수 실행
    실행 시 0~2사이 랜덤 integer값을 인자로 넘겨 해당 인덱스의 Particle을 실행하게 해준다

      void AC06_EventTrigger::OnComponentBeginOverlap
      (UPrimitiveComponent * OverlappedComp, AActor * OtherActor, UPrimitiveComponent * OtherComp,
      int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
      {
          if (OnExplosionEvent.IsBound())
          {
              int32 index = UKismetMathLibrary::RandomIntegerInRange(0, 2);
              OnExplosionEvent.Broadcast(index);
          }
      }
    

    Explosion

    C++ Actor클래스로 C06_Explosion클래스 생성하기
    입력받은 인덱스에 해당하는 3개의 폭발이펙트 Particle들을 담을 Particles배열을 변수로 선언해준다

  • 헤더
    #pragma once
    #include "CoreMinimal.h"
    #include "GameFramework/Actor.h"
    #include "C06_Explosion.generated.h"
        
      UCLASS()
      class U03_BASIC_API AC06_Explosion : public AActor
      {
          GENERATED_BODY()
        
      public:	
          AC06_Explosion();
            
      protected:
          virtual void BeginPlay() override;
            
      private:
          UPROPERTY(EditAnywhere, Category = "Particles")
              class UParticleSystem* Particles[3];
        
      private:
          UPROPERTY(VisibleAnywhere)
              class USceneComponent*      Root;
          UPROPERTY(VisibleAnywhere)
              class UTextRenderComponent* Text;
            
      private:
          UFUNCTION()
              void OnExplosion(int32 InIndex);
      };
    
  • 소스
    라이브러리 추가 & 생성자
    #include "03_Collision/C06_Explosion.h"
    #include "Global.h"
    #include "C06_EventTrigger.h"
    #include "Components/TextRenderComponent.h"
    #include "Particles/ParticleSystem.h"
    
      AC06_Explosion::AC06_Explosion()
      {
          // 컴포넌트 생성
          CHelpers::CreateComponent<USceneComponent>(this, &Root, "Root");
          CreateTextRender();
            
          // 파티클
          CHelpers::GetAsset<UParticleSystem>(&Particles[0], "ParticleSystem'/Game/AdvancedMagicFX12/particles/P_ky_hit.P_ky_hit'");
          CHelpers::GetAsset<UParticleSystem>(&Particles[1], "ParticleSystem'/Game/AdvancedMagicFX12/particles/P_ky_hit_dark.P_ky_hit_dark'");
          CHelpers::GetAsset<UParticleSystem>(&Particles[2], "ParticleSystem'/Game/AdvancedMagicFX12/particles/P_ky_hit_fire.P_ky_hit_fire'");
      }
    

    BeginPlay에서 AddUFunction()

      void AC06_Explosion::BeginPlay()
      {
          Super::BeginPlay();
          AC06_EventTrigger* trigger = CHelpers::FindActor<AC06_EventTrigger>(GetWorld());
            
          CheckNull(trigger);
            
          trigger->OnExplosionEvent.AddUFunction(this, "OnExplosion");
      }
    

    OnExplosion()

      void AC06_Explosion::OnExplosion(int32 InIndex)
      {
          // Global.h에 미리 추가한 헤더 Kismet/GameplayStatics
          UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), Particles[InIndex],GetActorLocation());
      }
    

    30_1


머터리얼색변경 트리거

접근하면 Player의 머터리얼인스턴스 BodyColor를 변경해주는 Trigger 구현하기

활용 델리게이트 유형 : C++에서 바인드 후 파생 블프에서 구현하기

  • C++로 생성한 클래스를 블루프린트로 파생시켜 여러사람이 함께 작업할 수 있게 틀을 잡는 방법