• Home
  • About
    • 게임 개발자 유정룡 photo

      게임 개발자 유정룡

      포트폴리오

    • Learn More
    • Email
    • Github
    • Bitbucket
  • Projects
    • All Projects
    • All Tags

ProjectDark - 06 - InteractionActor

31 Aug 2021

Reading time ~2 minutes

Interaction Actor

이 전에 무기를 만들었지만, 장착할 수 있는 방법이나 액터가 없었다.

그래서 플레이어가 직접 상호작용 할 수 있는 액터 클래스를 만든뒤, 장착할 수 있게 만들자.

InteractionActorBase.h
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "InteractionActorBase.generated.h"

UCLASS()
class PROJECTDARK_API AInteractionActorBase : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AInteractionActorBase();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

private:

public:
	virtual void PlayInteraction();

	virtual void PlayInteraction(const class AMainPlayer* MainPlayer);
};
InteractionActorBase.cpp
#include "InteractionActorBase.h"

#include "Components/BoxComponent.h"

#include "MainPlayerCodes/MainPlayer.h"

AInteractionActorBase::AInteractionActorBase()
{
	PrimaryActorTick.bCanEverTick = true;
}

void AInteractionActorBase::BeginPlay()
{
	Super::BeginPlay();
	
}

void AInteractionActorBase::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

void AInteractionActorBase::PlayInteraction()
{

}

void AInteractionActorBase::PlayInteraction(const AMainPlayer* MainPlayer)
{
	UE_LOG(LogTemp, Log, TEXT("Iteraction!!!"));
}

(마지막에 있는 로그는 무시하자… 체크 하기 위해 넣었다.)

PlayerInteraction을 사용해서 플레이어와 상호작용 할 수 있게 플레이어에게 다른 명령어를 넣어주자.

MainPlayer.h
#pragma region Interaction

private:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Interaction", meta = (AllowPrivateAccess = "True"))
	class USphereComponent* InteractionSphere;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Interaction", meta = (AllowPrivateAccess = "True"))
	TArray<class AInteractionActorBase*> InteractionActors;

public:
	UFUNCTION()
	void BeginInteractionSphereOverlap(class UPrimitiveComponent* HitComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

	UFUNCTION()
	void EndInteractionSphereOverlap(class UPrimitiveComponent* HitComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

	void InteractionMonobehavior();

#pragma endregion

따로 콜라이더를 만들어 그 안으로 들어올 때, 밖으로 나갈때, 이 둘을 체크해서 현재 인터렉션 액터들을 모은 뒤, 그 액터중에 가장 가까운 InteractionActor에게 명령어를 실행시키게 만든다.

MainPlyer.cpp
void AMainPlayer::BeginPlay()
{
	Super::BeginPlay();

	InteractionSphere->OnComponentBeginOverlap.AddDynamic(this, &AMainPlayer::BeginInteractionSphereOverlap);
	InteractionSphere->OnComponentEndOverlap.AddDynamic(this, &AMainPlayer::EndInteractionSphereOverlap);
}

void AMainPlayer::BeginInteractionSphereOverlap(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	UE_LOG(LogTemp, Log, TEXT("Actor In"));
	if (OtherActor)
	{
		AInteractionActorBase* InteractionActor = Cast<AInteractionActorBase>(OtherActor);
		if (InteractionActor)
		{
			InteractionActors.Add(InteractionActor);
		}
	}
}

void AMainPlayer::EndInteractionSphereOverlap(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	UE_LOG(LogTemp, Log, TEXT("Actor Out"));
	if (OtherActor)
	{
		AInteractionActorBase* InteractionActor = Cast<AInteractionActorBase>(OtherActor);
		if (InteractionActor)
		{
			InteractionActors.Remove(InteractionActor);
		}
	}
}

void AMainPlayer::InteractionMonobehavior()
{
	if (InteractionActors.Num() > 0)
	{
		AInteractionActorBase* NearActor = NULL;
		float Distance = 999999;
		for (int i = 0; i < InteractionActors.Num(); i++)
		{
			if (InteractionActors[i]->IsHidden() == true)
			{
				continue;
			}
			float CurrentDiatance = FVector::Distance(GetActorLocation(), InteractionActors[i]->GetActorLocation());
			if (CurrentDiatance < Distance)
			{
				NearActor = InteractionActors[i];
			}
		}

		if (NearActor)
		{
			NearActor->PlayInteraction(this);
		}
	}
}

델리게이트를 사용해서 SphereComponent에 들어온 오브젝트르 검사할 수 있게 만든다.



Unreal Share Tweet +1