Unreal Engine 4 프로그래밍 c++/기능
unreal c++ interface사용하기
코닥쿠
2022. 1. 13. 01:07
반응형
c++기능의 interface사용하는 방법은 다음과 같다.
지금 포트폴리오에 대해 예를 들어 설명하면 다음과 같습니다.
플레이어 머즐과 카메라의 접점의 임팩트포인트라 하면 이접점에 위치값을 불러와야 할것이다.
하지만 이대로 값을 호출할경우에는 다음과같이 트레이스가 생성된다.
이런식으로 포인트가 생성되면 문제가 많이 생성된다. 그래서 Interface방법으로 값을 전달받아 탄착점이 맞게 사용해보는거에 대해 보겠습니다.
Weapon_Interface.h
#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "Weapon_Interface.generated.h"
// This class does not need to be modified.
UINTERFACE(MinimalAPI)
class UWeapon_Interface : public UInterface
{
GENERATED_BODY()
};
/**
*
*/
//함수는 생성은 아래 I같붙은 Interface 클래스에서 생성해줘야한다.//
class PROJECT_API IWeapon_Interface
{
GENERATED_BODY()
// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
//반환할 값의 함수를 호출해준다.//
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = Functions)
FVector GetTargetLocation();
};
/*cpp는 따로 작성을 안해준다.(Interface는 Interface의 cpp클래스에서 정의가 아닌 상속받은 클래스에서의 정의가 내려지기 때문에 생성을 안한다.)*/
PlayerCharacter.h
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
//Interface상속을 위해 인클루드해줌//
#include "Weapon_Interface.h"
#include "ThirdPersonCharacter.generated.h"
UCLASS()
class PROJECT_API AThirdPersonCharacter : public ACharacter, public IWeapon_Interface
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AThirdPersonCharacter();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
public:
//발사시 임팩트로케이션 interface//
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "TargetLocation")
FVector GetTargetLocation();
virtual FVector GetTargetLocation_Implementation() override;
/////////////////////////////
PlayerCharacter.cpp
//인터페이스::위치넘기기//
FVector AThirdPersonCharacter::GetTargetLocation_Implementation()
{
FHitResult OutHit;
FVector Start = Camera->GetComponentLocation();
FRotator Con_Rot = UGameplayStatics::GetPlayerController(GetWorld(), 0)->GetControlRotation();
FVector End = Start + UKismetMathLibrary::GetForwardVector(Con_Rot) * 100000.f;
bool isHit = UKismetSystemLibrary::LineTraceSingle(GetWorld(), Start, End, ETraceTypeQuery::TraceTypeQuery1, false, IgnoreActors, EDrawDebugTrace::ForOneFrame, OutHit, true);
if (isHit)
{
//임팩트포인트만 가져오면 각도에 따라서 블록킹히트가 안될수도 있기때문에 카메라의 ForwardVector 더해준다.
FVector ImpactPoint = OutHit.ImpactPoint + Camera->GetForwardVector();
return ImpactPoint;
}
else
{
//만약 임팩트가 작용하지 않고 위에만 리턴하면 값이 FVector(0, 0, 0)이 전달되기때문에 위치를 End로 설정해준다.//
return End;
}
}
Weapon.cpp
void AM4_Weapon::Fire()
{
//0이상 리로드중이 아닐경우 실행// /* 플레이어변수는 MasetPickupActor에 Cast됨*/
if (weaponInfo.CurrentAmmo > 0 && !Player->GetReload())
{
FHitResult OutHit;
FVector Start = weaponMesh->GetSocketLocation("muzzle");
//Interface함수를 호출하여 상속받은 객체의 값을 받아 함수의 정의된 값을 반환받음//
FVector End = IWeapon_Interface::Execute_GetTargetLocation(Player);
TArray<AActor*> IgnoreActors;
//줌 몽타주 플레이//
if (Player->bZoomIn)
{
Player->PlayAnimMontage(Player->Zoom_FireWeaponMontage, 0.5f, "Rifle_Fire_Start");
//Player_HUD->PlayAnimationByName();
}
else
{
Player->PlayAnimMontage(Player->FireWeaponMontage, 0.5f, "Rifle_Fire_Start");
}
///////////////////
bool isHit = UKismetSystemLibrary::LineTraceSingle(GetWorld(), Start, End, ETraceTypeQuery::TraceTypeQuery1, true, IgnoreActors,EDrawDebugTrace::ForDuration, OutHit, true);
if (isHit)
{
}
}
else if(weaponInfo.MaxAmmo > 0)
{
//재장전 호출//
Player->Reload();
///////////////
}
////////////////////////////////
}
Interface값을 받기 위해서는 I+(interface class)::Execute_(Function Name)(상속받은 객체의 변수) 이런식으로 선언해야한다. /*(IWeapon_Interface::Execute_GetTargetLocation(Player)*/
반응형