UPROPERY()
클래스는 객체 또는 설계도라고도 하며 그 설계도로 만든것이 인스턴스이다
객체들의 특징을 멤버라고 하고 그 멤버 ( 메소드 )
바인딩을 하기위해 Project Setting에 Input값 Axis Mappings 값을 바꿔준다
CPlayer.h
public:
// 이동속도는 속성
UPROPERTY(EditAnywhere, Category="Settings")
float speed = 500;
float h;
float v;
void Horizontal(float value);
void Vertical(float value);
CPlayer.cpp
// Called to bind functionality to input
void ACPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
// 사용자 입력과 처리함수 묶어주자. ( 바인딩 )
PlayerInputComponent->BindAxis(TEXT("Horizontal"),
this, &ACPlayer::Horizontal);
PlayerInputComponent->BindAxis(TEXT("Vertical"),
this, &ACPlayer::Vertical);
}
void ACPlayer::Horizontal(float value)
{
h = value;
}
void ACPlayer::Vertical(float value)
{
v = value;
}
CPlayer.cpp
void ACPlayer::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// 사용자의 입력에 따라 이동하고 싶다
// 1. 사용자의 입력을 받아야 한다
// 등속운동, 등가속운동
// P = P0 + vt
// 2. 방향이 필요하다
FVector dir(0, h, v);
// 3. 해당 방향으로 이동하고 싶다
FVector P0 = GetActorLocation();
FVector vt = dir * speed * DeltaTime;
FVector P = P0 + vt;
SetActorLocation(P);
}
CBullet.h
public:
UPROPERTY(VisibleAnywhere)
class UBoxComponent* BoxComp;
UPROPERTY(VisibleAnywhere)
class UStaticMeshComponent* BodyMesh;
// 이동속도는 속성
UPROPERTY(EditAnywhere, Category = "Settings")
float speed = 1000;
CBullet.cpp
ACBullet::ACBullet()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
BoxComp = CreateDefaultSubobject<UBoxComponent>(TEXT("BoxComp"));
RootComponent = BoxComp;
// box size
BoxComp->SetBoxExtent(FVector(50));
BoxComp->SetCollisionProfileName(TEXT("OverlapAll"));
BoxComp->SetRelativeScale3D(FVector((1, 0.25f, 0.5f)));
BodyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BodyMesh"));
BodyMesh->SetupAttachment(BoxComp);
// 에셋 등록
ConstructorHelpers::FObjectFinder<UStaticMesh> TempMesh
(TEXT("/Script/Engine.StaticMesh'/Engine/BasicShapes/Cube.Cube'"));
// 에셋이 로드가 됐다면...
if (TempMesh.Succeeded())
{
BodyMesh->SetStaticMesh(TempMesh.Object);
}
// Matrial �ε��ϱ�
ConstructorHelpers::FObjectFinder<UMaterial> TempMat
(TEXT("/Script/Engine.Material'/Engine/BasicShapes/BasicShapeMaterial.BasicShapeMaterial'"));
if (TempMat.Succeeded())
{
// -> ����ƽ�� �Ҵ�
BodyMesh->SetMaterial(0, TempMat.Object);
}
BodyMesh->SetCollisionProfileName(TEXT("NoCollision"));
}
CBullet.cpp
void ACBullet::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// p = p0 + vt
FVector P = GetActorLocation()
+ FVector::UpVector * speed * DeltaTime;
SetActorLocation(P);
}
CPlayer.h
public:
... 생략
// 사용자가 발사버튼을 누르면 총알을 발사하고 싶다
// 필요속성 : 총알공장, 발사위치,
UPROPERTY(EditDefaultsOnly, Category = "Settings")
TSubclassOf<class ACBullet> bulletFactory;
void Fire();
CPlayer.cpp
void ACPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAxis(TEXT("Horizontal"),
this, &ACPlayer::Horizontal);
PlayerInputComponent->BindAxis(TEXT("Vertical"),
this, &ACPlayer::Vertical);
PlayerInputComponent->BindAction(TEXT("Fire"),
IE_Pressed, this, &ACPlayer::Fire);
}
void ACPlayer::Fire()
{
GetWorld()->SpawnActor<ACBullet>(
bulletFactory, GetActorLocation(), FRotator::ZeroRotator);
}
Enemy또한 몸체를 만들기 위해 Bullet 처럼 몸체를 일단 만든다
그 후 에너미는 플레이를 추격하지만 30% 확률로 쫓아오게 할 것이다
추격
Target( Player )와 Enemy의 위치를 빼서 그 사이의 거리를 구한다
CEnemy.h
public:
... 생략
// 필요속성 : 타겟
UPROPERTY(EditAnywhere)
class AActor* target;
FVector dir;
CEnemy.cpp
void ACEnemy::BeginPlay()
{
Super::BeginPlay();
// 태어날때 한번 방향을 정하고 그대로 움직인다
// 30% 확률
int32 ran_num = FMath::RandRange(1, 3);
if (ran_num == 1)
{
// Target - enemy = Target의 방향
dir = target->GetActorLocation() - GetActorLocation();
dir.Normalize(); // Nomalize
}
else
{
dir = FVector::DownVector;
}
}
void ACEnemy::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// 해당 방향으로 이동하고 싶다
// 등속운동, 등가속운동
// P = P0 + vt
FVector P0 = GetActorLocation();
FVector vt = dir * speed * DeltaTime;
FVector P = P0 + vt;
SetActorLocation(P);
}
CEnemy.cpp
ACEnemy::ACEnemy()
{
...생략 ( 몸체 )
BoxComp->OnComponentBeginOverlap.AddDynamic
}
F12
를 눌러 들어간다FComponentBeginOverlapSignature
에 커서를 가져다 놓고 F12
를 눌러보면DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SixParams(
FComponentBeginOverlapSignature,
UPrimitiveComponent, OnComponentBeginOverlap,
UPrimitiveComponent*, OverlappedComponent,
AActor*, OtherActor,
UPrimitiveComponent*, OtherComp,
int32, OtherBodyIndex,
bool, bFromSweep,
const FHitResult &, SweepResult);
UPrimitiveComponent, OnComponentBeginOverlap,
UPrimitiveComponent*, OverlappedComponent,
AActor*, OtherActor,
UPrimitiveComponent*, OtherComp,
int32, OtherBodyIndex,
bool, bFromSweep,
const FHitResult &, SweepResult);
CEnemy.h
public:
UFUNCTION()
void OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent,
AActor* OtherActor, UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex, bool bFromSweep,
const FHitResult& SweepResult);
CEnemy.cpp
ACEnemy::ACEnemy()
{
...생략 ( 몸체 )
BoxComp->OnComponentBeginOverlap.AddDynamic(this, &ACEnemy::OnComponentBeginOverlap);
}
void ACEnemy::OnComponentBeginOverlap(
UPrimitiveComponent* OverlappedComponent,
AActor* OtherActor,
UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex,
bool bFromSweep,
const FHitResult& SweepResult)
{
OtherActor->Destroy();
Destroy();
}