충돌 검사를 수행하고 나면, 충돌한 물체의 위치와 방향, 속도 등을 계산할 수 있다. 이를 바탕으로 충돌한 물체에 대한 반응을 구현할 수 있다. 이를 위해서는 충돌 응답(Collision Response) 코드를 작성해야 한다. 충돌 응답 코드는 충돌한 물체가 서로 어떻게 반응해야 하는지를 결정하는 것이다. 예를 들어, 물체가 서로 충돌하면 반대 방향으로 튕겨져 나가거나, 속도가 감소하는 등의 반응을 구현할 수 있다.

 

 

목차

     

     


     

     

    Collision - Override

     

    01_Spawn
      C01_Properties.h .cpp
    C02_Mesh
    C02_Mesh_Sphere
    C02_Mesh_Cone
    C03_Spawner.h .cpp
    02_Profiler
      C01_Log.h .cpp
    C02_DrawDebug.h .cpp
    03_Collision
      C01_ActorOverlap.h .cpp
    C02_ComponentOverlap.h .cpp
    C03_OverlapAndHit.h .cpp 
    C04_Trigger.h .cpp
    C04_Light.h .cpp 
    C05_MultiTrigger.h .cpp 생성
    C05_FallingBox.h .cpp 생성
    C05_SpotLight.h .cpp 생성
    C06_EventTrigger.h .cpp 생성
    C06_Explosion.h .cpp 생성

    C07_Override.h .cpp 생성
    04_Trace
      C01_Trigger.h .cpp 생성
    C01_SphereTrace.h .cpp 생성
    Utilities
      CHelpers.h
     
    CAnimInstance.h .cpp
    CGameMode.h .cpp
    CPlayer.h .cpp

     

     


     

    C07_Override 

     

    C07_Override.h

    더보기
    #pragma once
    
    #include "CoreMinimal.h"
    #include "GameFramework/Actor.h"
    #include "C07_Override.generated.h"
    
    UCLASS()
    class U2212_03_API AC07_Override : public AActor
    {
    	GENERATED_BODY()
    
    private:
    	UPROPERTY(VisibleDefaultsOnly)
    		class USceneComponent* Root;
    
    	UPROPERTY(VisibleDefaultsOnly)
    		class UBoxComponent* Box;
    
    	UPROPERTY(VisibleDefaultsOnly)
    		class UTextRenderComponent* Text;
    
    public:	
    	AC07_Override();
    
    protected:
    	virtual void BeginPlay() override;
    
    private:
    	UFUNCTION()
    		void OnBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);
    
    	UFUNCTION()
    		void OnEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
    
    protected:
    	UFUNCTION(BlueprintNativeEvent) //가상화
    		void ChangeColorWhite();
    	void ChangeColorWhite_Implementation(); //재정의하겠다. 언리얼C++에서 재정의를 할 때는 _Implementation을 붙인다.
    
    	UFUNCTION(BlueprintImplementableEvent) //추상화. 상속받은 이후 재정의가 가능하다.
    		void ChangeColorRed();
    
    };

     

     

     

    C07_Override.cpp

    더보기
    #include "03_Collision/C07_Override.h"
    #include "Global.h"
    #include "CPlayer.h"
    #include "Components/BoxComponent.h"
    #include "Components/TextRenderComponent.h"
    
    AC07_Override::AC07_Override()
    {
    	CHelpers::CreateComponent<USceneComponent>(this, &Root, "Root");
    	CHelpers::CreateComponent<UBoxComponent>(this, &Box, "Box", Root);
    
    	CreateTextRender();
    
    	Box->SetRelativeScale3D(FVector(3));
    	Box->bHiddenInGame = false;
    }
    
    void AC07_Override::BeginPlay()
    {
    	Super::BeginPlay();
    
    	Box->OnComponentBeginOverlap.AddDynamic(this, &AC07_Override::OnBeginOverlap);
    	Box->OnComponentEndOverlap.AddDynamic(this, &AC07_Override::OnEndOverlap);
    }
    
    void AC07_Override::OnBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
    {
    	ChangeColorRed();
    }
    
    void AC07_Override::OnEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
    {
    	ChangeColorWhite();
    }
    
    void AC07_Override::ChangeColorWhite_Implementation()
    {
    	ACPlayer* player = Cast<ACPlayer>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
    	CheckNull(player);
    
    	player->ChangeColor(FLinearColor::White);
    }

     

     

    BP_C07_Override

    블루프린트에서 색을 수정하는 경우이다.

    • C07_Override.h .cpp에서 만든 Change Color Red, Change Color White를 불러온다.
    • Change Color로 각각 빨간색, 마젠타색을 지정해서 넣어준다.
      •  Change Color Red, Change Color White 코드 안에서 색을 정의했지만 Change Color로 재정의 할 수 있다.

     


     

    CPlayer - Material 추가

     

    CPlayer.h

    더보기
    #pragma once
    #include "CoreMinimal.h"
    #include "GameFramework/Character.h"
    #include "CPlayer.generated.h"
    
    UCLASS()
    class U2212_03_API ACPlayer : public ACharacter
    {
    	GENERATED_BODY()
    
    private:
    	UPROPERTY(VisibleAnywhere)
    		class USpringArmComponent* SpringArm;
    
    	UPROPERTY(VisibleAnywhere)
    		class UCameraComponent* Camera;
    
    public:
    	ACPlayer();
    
    protected:
    	virtual void BeginPlay() override;
    
    public:	
    	virtual void Tick(float DeltaTime) override;
    	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
    
    private:
    	void OnMoveForward(float InAxisValue);
    	void OnMoveRight(float InAxisValue);
    	void OnHorizontalLook(float InAxisValue);
    	void OnVerticalLook(float InAxisValue);
    
    private:
    	void OnRun();
    	void OffRun();
    
    public:
    	UFUNCTION(BlueprintCallable, Category = "Color")//직렬화
    		void ChangeColor(FLinearColor InColor);//BP에서 접근 가능한 함수가 된다.
    
    private:
    	TArray<class UMaterialInstanceDynamic*> Materials;
    };

     

     

    CPlayer.cpp

    더보기
    #include "CPlayer.h"
    #include "Global.h"
    #include "CAnimInstance.h"
    #include "GameFramework/SpringArmComponent.h"
    #include "GameFramework/CharacterMovementComponent.h"
    #include "Camera/CameraComponent.h"
    #include "Components/CapsuleComponent.h"
    #include "Components/InputComponent.h"
    #include "Materials/MaterialInstanceDynamic.h"
    
    ACPlayer::ACPlayer()
    {
    	PrimaryActorTick.bCanEverTick = true;
    
    	CHelpers::CreateComponent<USpringArmComponent>(this, &SpringArm, "SpringArm", GetCapsuleComponent());
    	CHelpers::CreateComponent<UCameraComponent>(this, &Camera, "Camera", SpringArm);
    
    
    	USkeletalMesh* mesh;
    	CHelpers::GetAsset<USkeletalMesh>(&mesh, "SkeletalMesh'/Game/Character/Mesh/SK_Mannequin.SK_Mannequin'");
    	GetMesh()->SetSkeletalMesh(mesh);
    	GetMesh()->SetRelativeLocation(FVector(0, 0, -90));
    	GetMesh()->SetRelativeRotation(FRotator(0, -90, 0));
    
    	
    	TSubclassOf<UCAnimInstance> animInstance;
    	CHelpers::GetClass<UCAnimInstance>(&animInstance, "AnimBlueprint'/Game/ABP_Character.ABP_Character_C'");
    	GetMesh()->SetAnimClass(animInstance);
    
    
    	bUseControllerRotationYaw = false;
    	GetCharacterMovement()->bOrientRotationToMovement = true;
    	GetCharacterMovement()->MaxWalkSpeed = 400;
    
    
    	SpringArm->SetRelativeLocation(FVector(0, 0, 60));
    	SpringArm->TargetArmLength = 200;
    	SpringArm->bUsePawnControlRotation = true;
    	SpringArm->bEnableCameraLag = true;
    
    }
    
    void ACPlayer::BeginPlay()
    {
    	Super::BeginPlay(); //Super가 BP의 BeginPlay를 콜한다.
    
    	TArray<UMaterialInterface*> materials = GetMesh()->GetMaterials(); //UMaterialInterface는 Material의 최상위
    	for (int32 i = 0; i < materials.Num(); i++)
    	{
    		//InstanceDynamic으로 할당 후 넣어준다.
    		UMaterialInstanceDynamic* temp = UMaterialInstanceDynamic::Create(materials[i], this);
    		GetMesh()->SetMaterial(i, temp);
    
    		Materials.Add(temp);
    	}
    
    	ChangeColor(FLinearColor::Black);
    }
    
    void ACPlayer::Tick(float DeltaTime)
    {
    	Super::Tick(DeltaTime);
    
    }
    
    void ACPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
    {
    	Super::SetupPlayerInputComponent(PlayerInputComponent);
    
    	PlayerInputComponent->BindAxis("MoveForward", this, &ACPlayer::OnMoveForward);
    	PlayerInputComponent->BindAxis("MoveRight", this, &ACPlayer::OnMoveRight);
    	PlayerInputComponent->BindAxis("HorizontalLook", this, &ACPlayer::OnHorizontalLook);
    	PlayerInputComponent->BindAxis("VerticalLook", this, &ACPlayer::OnVerticalLook);
    
    	PlayerInputComponent->BindAction("Run", EInputEvent::IE_Pressed, this, &ACPlayer::OnRun);
    	PlayerInputComponent->BindAction("Run", EInputEvent::IE_Released, this, &ACPlayer::OffRun);
    }
    
    void ACPlayer::OnMoveForward(float InAxisValue)
    {
    	FRotator rotator = FRotator(0, GetControlRotation().Yaw, 0);
    	FVector direction = FQuat(rotator).GetForwardVector();
    
    	AddMovementInput(direction, InAxisValue);
    }
    
    void ACPlayer::OnMoveRight(float InAxisValue)
    {
    	FRotator rotator = FRotator(0, GetControlRotation().Yaw, 0);
    	FVector direction = FQuat(rotator).GetRightVector();
    
    	AddMovementInput(direction, InAxisValue);
    }
    
    void ACPlayer::OnHorizontalLook(float InAxisValue)
    {
    	AddControllerYawInput(InAxisValue);
    }
    
    void ACPlayer::OnVerticalLook(float InAxisValue)
    {
    	AddControllerPitchInput(InAxisValue);
    }
    
    void ACPlayer::OnRun()
    {
    	GetCharacterMovement()->MaxWalkSpeed = 600;
    }
    
    void ACPlayer::OffRun()
    {
    	GetCharacterMovement()->MaxWalkSpeed = 400;
    }
    
    void ACPlayer::ChangeColor(FLinearColor InColor)
    {
    	for (UMaterialInstanceDynamic* material : Materials)
    		material->SetVectorParameterValue("BodyColor", InColor);
    }

     

     

    BP_CPlayer

     


     

    실행화면

     

     

     


     

     

     

     

    언리얼엔진의 Blueprint와 Unreal C++ 호출순서 - 중요!

     

     

    ※ 언리얼엔진은 Blueprint를 먼저 읽은 후에 Unreal C++를 읽는다!  그래서 부모를 나중에 세팅해야 한다. 

     

     

    아래의 예시코드는 Player 매쉬의 색을 바꾸는 CPlayer.cpp 코드 중 일부를 사용하였다.

     

     

    원본 코드

    더보기
    void ACPlayer::BeginPlay()
    {
    	TArray<UMaterialInterface*> materials = GetMesh()->GetMaterials(); //UMaterialInterface는 Material의 최상위
    	for (int32 i = 0; i < materials.Num(); i++)
    	{
    		UMaterialInstanceDynamic* temp = UMaterialInstanceDynamic::Create(materials[i], this);
    		GetMesh()->SetMaterial(i, temp);
    
    		Materials.Add(temp);
    	}
    
    	Super::BeginPlay(); //Super가 BP의 BeginPlay를 콜한다.
    }
    • C++ 코드를 적용한 후에 Super::BeginPlay()로 BlueprintBeginPlay를 실행시킨다.
    • 위의 경우에는 Unreal C++  BP 순으로 실행한다.

    실행 시 Player가 검은색으로 등장한다.

     

     

     

    오류 코드 - Super::BeginPlay()가 위로 올라온 경우

    더보기
    void ACPlayer::BeginPlay()
    {
    	Super::BeginPlay(); //Super가 BP의 BeginPlay를 콜한다.
    
    	TArray<UMaterialInterface*> materials = GetMesh()->GetMaterials(); //UMaterialInterface는 Material의 최상위
    	for (int32 i = 0; i < materials.Num(); i++)
    	{
    		UMaterialInstanceDynamic* temp = UMaterialInstanceDynamic::Create(materials[i], this);
    		GetMesh()->SetMaterial(i, temp);
    
    		Materials.Add(temp);
    	}
    }
    • Super::BeginPlay()를 아래의 코드보다 먼저 실행시켰다.
    • 위의 경우에는 BP → Unreal C++ 순서로 실행된다.
    • 이 경우 mesh에 material을 할당하는 아래의 코드가 적용되지 않은 상태에서 Blueprint가 실행된다. 
      • Blueprint에서 ChangeColor를 실행할 때 정보를 찾지 못해 색이 바뀌지 않는다.

    색이 적용되지 않는다.

     

     

     

     

    수정 코드 - ChangeColor 코드를 뒤에 추가한 경우

    더보기
    void ACPlayer::BeginPlay()
    {
    	Super::BeginPlay(); //Super가 BP의 BeginPlay를 콜한다.
    
    	TArray<UMaterialInterface*> materials = GetMesh()->GetMaterials(); //UMaterialInterface는 Material의 최상위
    	for (int32 i = 0; i < materials.Num(); i++)
    	{
    		UMaterialInstanceDynamic* temp = UMaterialInstanceDynamic::Create(materials[i], this);
    		GetMesh()->SetMaterial(i, temp);
    
    		Materials.Add(temp);
    	}
    
    	ChangeColor(FLinearColor::Black);
    }
    • 위의 경우에는 BP → Unreal C++  → ChangeColor
    • 맨 뒤에 ChangeColor를 넣어 순서 문제가 생기는 것을 방지할 수 있는 코드이다.
    • ChangeColor로 색을 지정해준다.

     


     

    Narrative vs. Implementation

     

    Native Event = 가상화. Unreal C++에서 정의할테니 원하면 가져다가 써라.

     

    Implementation = 추상화. 함수 호출 해줄테니 필요하면 재정의해서 써라. 

     


     

     

     

     

     

    Trace

     


     

    큐브 배치하기

     

    큐브 배치

    • Simulate Physics 체크하기
    • MassInKg = 매스의 무게
      • 큐브 마다 매스의 무게를 조금씩 다르게 설정하였다.

     


     

     

    C01_Trigger

     

    C01_Trigger.h

    더보기
    #pragma once
    #include "CoreMinimal.h"
    #include "GameFramework/Actor.h"
    #include "C01_Trigger.generated.h"
    
    UCLASS()
    class U2212_03_API AC01_Trigger : public AActor
    {
    	GENERATED_BODY()
    
    private:
    	UPROPERTY(VisibleDefaultsOnly)
    		class USceneComponent* Root;
    
    	UPROPERTY(VisibleDefaultsOnly)
    		class UBoxComponent* Box;
    
    	UPROPERTY(VisibleDefaultsOnly)
    		class UTextRenderComponent* Text;
    	
    public:	
    	AC01_Trigger();
    
    protected:
    	virtual void BeginPlay() override;
    };

     

     

     

    C01_Trigger.cpp

    더보기
    #include "04_Trace/C01_Trigger.h"
    #include "Global.h"
    #include "C01_SphereTrace.h"
    #include "Components/BoxComponent.h"
    #include "Components/TextRenderComponent.h"
    
    AC01_Trigger::AC01_Trigger()
    {
    	CHelpers::CreateComponent<USceneComponent>(this, &Root, "Root");
    	CHelpers::CreateComponent<UBoxComponent>(this, &Box, "Box", Root);
    
    	CreateTextRender();
    
    	Box->SetRelativeScale3D(FVector(3));
    	Box->bHiddenInGame = false;
    }
    
    void AC01_Trigger::BeginPlay()
    {
    	Super::BeginPlay();
    
    	AC01_SphereTrace* trace = CHelpers::FindActor<AC01_SphereTrace>(GetWorld());
    	CheckNull(trace);
    
    	OnActorBeginOverlap.AddDynamic(trace, &AC01_SphereTrace::BeginOverlap);
    }

     

     


     

    C01_SphereTrace

     

    C01_SphereTrace.h

    더보기
    #pragma once
    
    #include "CoreMinimal.h"
    #include "GameFramework/Actor.h"
    #include "Kismet/KismetSystemLibrary.h"
    #include "C01_SphereTrace.generated.h"
    
    UCLASS()
    class U2212_03_API AC01_SphereTrace : public AActor
    {
    	GENERATED_BODY()
    
    private:
    	UPROPERTY(EditAnywhere, Category = "Settings")
    		TEnumAsByte<EDrawDebugTrace::Type> DrawDebug;  //TEnumAsByte는 직렬화 
    
    	UPROPERTY(EditAnywhere, Category = "Settings")
    		float DrawTime = 5;;
    
    	UPROPERTY(EditAnywhere, Category = "Settings")
    		float MaxMass = 300;
    
    	UPROPERTY(EditAnywhere, Category = "Settings")
    		float ImpulseAmount = 500;
    
    
    private:
    	UPROPERTY(VisibleAnywhere)
    		class UParticleSystemComponent* Particle;
    
    public:	
    	AC01_SphereTrace();
    
    protected:
    	virtual void BeginPlay() override;
    
    public:
    	UFUNCTION()
    		void BeginOverlap(AActor* OverlappedActor, AActor* OtherActor);
    };

     

     

    C01_SphereTrace.cpp

    더보기
    #include "04_Trace/C01_SphereTrace.h"
    #include "Global.h"
    #include "Particles/ParticleSystemComponent.h"
    
    AC01_SphereTrace::AC01_SphereTrace()
    {
    	CHelpers::CreateComponent<UParticleSystemComponent>(this, &Particle, "Particle");
    
    
    	UParticleSystem* particle;
    	CHelpers::GetAsset<UParticleSystem>(&particle, "ParticleSystem'/Game/AdvancedMagicFX12/particles/P_ky_hit_thunder.P_ky_hit_thunder'");
    
    	Particle->SetTemplate(particle);
    	Particle->bAutoActivate = false;
    	Particle->SetRelativeScale3D(FVector(3));
    }
    
    void AC01_SphereTrace::BeginPlay()
    {
    	Super::BeginPlay();
    }
    
    void AC01_SphereTrace::BeginOverlap(AActor* OverlappedActor, AActor* OtherActor)
    {
    	FVector location = GetActorLocation();
    
    	//오브젝트 콜리션 종류들
    	TArray<TEnumAsByte<EObjectTypeQuery>> types; //TEnumAsByte는 Enum의 사이즈를 알려주는 템플릿이다.
    	types.Add(EObjectTypeQuery::ObjectTypeQuery4); //4는 PhysicsBody
    
    	TArray<AActor*> ignores;
    	TArray<FHitResult> hitResults; //배열로 들어간다.
    
    	//여기 마지막 변수 체크
    	bool b = UKismetSystemLibrary::SphereTraceMultiForObjects(GetWorld(), location, location, 300, types, false, ignores, DrawDebug, hitResults, true, FLinearColor::Red, FLinearColor::Green, DrawTime);
    	CheckFalse(b); // b가 true라면 하나라도 충돌된게 있는 것이다.
    
    	Particle->ResetParticles(); //Particle 플레이가 끝나면 마지막 장면에 멈춰있기 때문에 포인터가 앞으로 오도록 리셋해준다.
    	Particle->SetActive(true); //Particle 플레이 해준다.
    
    	for(const FHitResult& hitResult : hitResults) //const로 변경방지, &로 복사방지
    	{
    		UStaticMeshComponent* mesh = Cast<UStaticMeshComponent>(hitResult.GetActor()->GetRootComponent());
    
    		if (!!mesh && mesh->IsSimulatingPhysics())
    			// RadialImpulse는 구형으면 Impulse, 무거운게 덜 날라가도록 strength항목에 MaxMass - mesh->GetMass() * ImpulseAmount //RIF_Linear 거리에 따라 선형으로 힘이 줄어들음.
    			mesh->AddRadialImpulse(location, 1000, (MaxMass - mesh->GetMass()) * ImpulseAmount, ERadialImpulseFalloff::RIF_Linear); 
    	}
    }

    TEnumAsByte는 Enum의 사이즈를 알려주는 템플릿이다.

     

    Enum을 과거에 사용하던 방식으로 계속 사용하는 경우도 있다. Legacy Type에는 사이즈가 없기 때문에 이 방식으로 사용하려면 TEnumAsByte를 사용하여 사이즈를 알려줘야 한다.

     

     

    UObject* WorldContextObject = 월드를 넣어준다.

     

     


     

    실행화면

     

     


     

     

     

    Trace

     


     

    원기둥 배치하기

     

     


     

     

    C02_Cylinder

     

    C02_Cylinder.h

    더보기
    #pragma once
    #include "CoreMinimal.h"
    #include "GameFramework/Actor.h"
    #include "C02_Cylinder.generated.h"
    
    UCLASS()
    class U2212_03_API AC02_Cylinder : public AActor
    {
    	GENERATED_BODY()
    
    private:
    	UPROPERTY(VisibleDefaultsOnly)
    		class USceneComponent* Root;
    
    	UPROPERTY(VisibleDefaultsOnly)
    		class UStaticMeshComponent* Mesh;
    
    	UPROPERTY(VisibleDefaultsOnly)
    		class UTextRenderComponent* Text;
    
    public:	
    	AC02_Cylinder();
    
    protected:
    	virtual void BeginPlay() override;
    };

     

     

    C02_Cylinder.cpp

    더보기
    #include "04_Trace/C02_Cylinder.h"
    #include "Global.h"
    #include "Components/StaticMeshComponent.h"
    #include "Components/TextRenderComponent.h"
    
    AC02_Cylinder::AC02_Cylinder()
    {
    	CHelpers::CreateComponent<USceneComponent>(this, &Root, "Root");
    	CHelpers::CreateComponent<UStaticMeshComponent>(this, &Mesh, "Mesh", Root);
    
    	CreateTextRender();
    
    	Text->SetRelativeLocation(FVector(0, 0, 150));
    
    
    	UStaticMesh* mesh;
    	CHelpers::GetAsset<UStaticMesh>(&mesh, "StaticMesh'/Game/Meshes/Cylinder.Cylinder'");
    	Mesh->SetStaticMesh(mesh);
    	Mesh->SetRelativeScale3D(FVector(1, 1, 2.5f));
    }
    
    void AC02_Cylinder::BeginPlay()
    {
    	Super::BeginPlay();
    }

     


     

     

     

    C02_LineTrace

     

    02_LineTrace.h

    더보기
    #pragma once
    
    #include "CoreMinimal.h"
    #include "GameFramework/Actor.h"
    #include "C02_LineTrace.generated.h"
    
    DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FLineTraceResult, class AActor*, InActor, FLinearColor, InColor);
    
    UCLASS()
    class U2212_03_API AC02_LineTrace : public AActor
    {
    	GENERATED_BODY()
    	
    public:	
    	AC02_LineTrace();
    
    protected:
    	virtual void BeginPlay() override;
    
    public:	
    	virtual void Tick(float DeltaTime) override;
    
    private:
    	UFUNCTION()
    		void StartLaunch(class AActor* InActor, FLinearColor InColor);//Dynamic은 매개변수 이름이 똑같아야 한다.
    
    public:
    	FLineTraceResult OnLineTraceResult;
    
    private:
    	TArray<class AC02_Cylinder*> Cylinders;
    };

     

     

    02_LineTrace.cpp

    더보기
    #include "04_Trace/C02_LineTrace.h"
    #include "Global.h"
    #include "C02_Cylinder.h"
    #include "GameFramework/Character.h" //실제적으로 실행시켜주는 역할
    
    AC02_LineTrace::AC02_LineTrace()
    {
    	PrimaryActorTick.bCanEverTick = true;
    }
    
    void AC02_LineTrace::BeginPlay()
    {
    	Super::BeginPlay();
    
    	CHelpers::FindActors<AC02_Cylinder>(GetWorld(), Cylinders);
    
    	//Delegate 사용
    	OnLineTraceResult.AddDynamic(this, &AC02_LineTrace::StartLaunch);
    }
    
    void AC02_LineTrace::Tick(float DeltaTime)
    {
    	Super::Tick(DeltaTime);
    
    	FVector start = Cylinders[0]->GetActorLocation();
    	FVector end = Cylinders[1]->GetActorLocation();
    
    	//DrawDebugLIne
    	{
    		start.Z -= 20;
    		end.Z -= 20;
    
    		DrawDebugLine(GetWorld(), start, end, FColor::Blue);
    	}
    }
    
    void AC02_LineTrace::StartLaunch(AActor* InActor, FLinearColor InColor)
    {
    }

     


     

     

    실행화면