2024. 8. 3. 15:49ㆍUnreal Engine
14일차 복습
메모리 관리가 필요한 부분은 U로 시작한다. UPROPERTY(), UStaticMeshComponent*
* 은 메모리 주소를 저장하는 변수이다.
:: 은 소속을 뜻한다. 왼쪽 안에 있는 오른쪽의~
F 붙으면 구조체나 표준 C++ 클래스를 만들어내는 오브젝트 (ex) FObjectFinder)
-> 는 기능에 접근하는 표시 (ex) SpaceShipMesh->SetStaticMesh()
BP_CPlayer 구성
헤더 파일 코드 추가
UPROPERTY(VisibleAnywhere)
class USceneComponent* FirePosition;
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "CPlayer.generated.h"
UCLASS()
class SHOOTING_API ACPlayer : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
ACPlayer();
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:
UPROPERTY(VisibleAnywhere)
class UStaticMeshComponent* BodyMesh;
UPROPERTY(VisibleAnywhere)
class UStaticMeshComponent* SpaceShipMesh;
UPROPERTY(VisibleAnywhere)
class USceneComponent* FirePosition;
};
C++ 코드 추가
//총구 컴포넌트 등록
FirePosition = CreateDefaultSubobject<USceneComponent>(TEXT("FirePosition"));
FirePosition->SetupAttachment(BodyMesh);
FirePosition->SetRelativeLocation(FVector(0, 0, 80));
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#include "CPlayer.h"
// Sets default values
ACPlayer::ACPlayer()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
//BodyMesh 그릇에 StaticMeshComponent를 만들어서 담으려고 한다.
BodyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BodyMesh"));
//BodyMesh를 Root로 등록
RootComponent = BodyMesh;
SpaceShipMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SpaceShipMesh"));
SpaceShipMesh->SetupAttachment(BodyMesh);
//사용할 Static Mesh 데이터를 읽어서 컴포넌트에 할당하기
ConstructorHelpers::FObjectFinder<UStaticMesh> TempMesh(TEXT("/Script/Engine.StaticMesh'/Game/SpaceShip/Spaceship_ARA.Spaceship_ARA'"));
//로딩 성공하면 SpaceShipMesh에 사용할 Static Mesh로 TempMesh를 넣는다.
if (TempMesh.Succeeded())
{
SpaceShipMesh->SetStaticMesh(TempMesh.Object);
//부모 기준 상대적 위치값 세팅. 회전 순서는 Y, Z, X 순서임
SpaceShipMesh->SetRelativeRotation(FRotator(0, 90, 90));
//크기 세팅
SpaceShipMesh->SetRelativeScale3D(FVector(6));
}
//총구 컴포넌트 등록
FirePosition = CreateDefaultSubobject<USceneComponent>(TEXT("FirePosition"));
FirePosition->SetupAttachment(BodyMesh);
FirePosition->SetRelativeLocation(FVector(0, 0, 80));
}
// Called when the game starts or when spawned
void ACPlayer::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACPlayer::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void ACPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
Ctrl + B로 빌드
Fire Position이 잘 붙었다.
C++로 이동 구현
오른쪽으로 향하게 만들기
헤더 파일 추가
public:
//좌우, 상하 방향, 이동 속도 설정
float h = 0;
float v = 0;
float speed = 500;
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "CPlayer.generated.h"
UCLASS()
class SHOOTING_API ACPlayer : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
ACPlayer();
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:
UPROPERTY(VisibleAnywhere)
class UStaticMeshComponent* BodyMesh;
UPROPERTY(VisibleAnywhere)
class UStaticMeshComponent* SpaceShipMesh;
UPROPERTY(VisibleAnywhere)
class USceneComponent* FirePosition;
public:
//좌우, 상하 방향, 이동 속도 설정
float h = 0;
float v = 0;
float speed = 500;
};
C++ 코드 추가
void ACPlayer::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//이동
FVector dir = FVector::RightVector;
FVector P0 = GetActorLocation(); //현재 위치 설정
FVector vt = dir * speed * DeltaTime;
FVector P = P0 + vt;
SetActorLocation(P);
}
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#include "CPlayer.h"
// Sets default values
ACPlayer::ACPlayer()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
//BodyMesh 그릇에 StaticMeshComponent를 만들어서 담으려고 한다.
BodyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BodyMesh"));
//BodyMesh를 Root로 등록
RootComponent = BodyMesh;
SpaceShipMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SpaceShipMesh"));
SpaceShipMesh->SetupAttachment(BodyMesh);
//사용할 Static Mesh 데이터를 읽어서 컴포넌트에 할당하기
ConstructorHelpers::FObjectFinder<UStaticMesh> TempMesh(TEXT("/Script/Engine.StaticMesh'/Game/SpaceShip/Spaceship_ARA.Spaceship_ARA'"));
//로딩 성공하면 SpaceShipMesh에 사용할 Static Mesh로 TempMesh를 넣는다.
if (TempMesh.Succeeded())
{
SpaceShipMesh->SetStaticMesh(TempMesh.Object);
//부모 기준 상대적 위치값 세팅. 회전 순서는 Y, Z, X 순서임
SpaceShipMesh->SetRelativeRotation(FRotator(0, 90, 90));
//크기 세팅
SpaceShipMesh->SetRelativeScale3D(FVector(6));
}
//총구 컴포넌트 등록
FirePosition = CreateDefaultSubobject<USceneComponent>(TEXT("FirePosition"));
FirePosition->SetupAttachment(BodyMesh);
FirePosition->SetRelativeLocation(FVector(0, 0, 80));
}
// Called when the game starts or when spawned
void ACPlayer::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACPlayer::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//이동
FVector dir = FVector::RightVector;
FVector P0 = GetActorLocation(); //현재 위치 설정
FVector vt = dir * speed * DeltaTime;
FVector P = P0 + vt;
SetActorLocation(P);
}
// Called to bind functionality to input
void ACPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
Viewport에 라이트, 카메라 추가
카메라 세팅
[Auto Activate for Player] - [Player 0] 설정
BP_CPlayer (0, 0, 0) 세팅
오른쪽으로 잘 움직인다.
사용자의 입력에 따른 이동
헤더 파일 코드 추가
public:
//좌우, 상하 방향, 이동 속도 설정
float h = 0;
float v = 0;
float speed = 500;
void Horizontal(float value);
void Vertical(float value);
헤더 전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "CPlayer.generated.h"
UCLASS()
class SHOOTING_API ACPlayer : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
ACPlayer();
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:
UPROPERTY(VisibleAnywhere)
class UStaticMeshComponent* BodyMesh;
UPROPERTY(VisibleAnywhere)
class UStaticMeshComponent* SpaceShipMesh;
UPROPERTY(VisibleAnywhere)
class USceneComponent* FirePosition;
public:
//좌우, 상하 방향, 이동 속도 설정
float h = 0;
float v = 0;
float speed = 500;
void Horizontal(float value);
void Vertical(float value);
};
C++ 코드 추가
void ACPlayer::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//이동
FVector dir(0, h ,v);
FVector P0 = GetActorLocation(); //현재 위치 설정
FVector vt = dir * speed * DeltaTime;
FVector P = P0 + vt;
SetActorLocation(P);
}
// 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;
}
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#include "CPlayer.h"
// Sets default values
ACPlayer::ACPlayer()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
//BodyMesh 그릇에 StaticMeshComponent를 만들어서 담으려고 한다.
BodyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BodyMesh"));
//BodyMesh를 Root로 등록
RootComponent = BodyMesh;
SpaceShipMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SpaceShipMesh"));
SpaceShipMesh->SetupAttachment(BodyMesh);
//사용할 Static Mesh 데이터를 읽어서 컴포넌트에 할당하기
ConstructorHelpers::FObjectFinder<UStaticMesh> TempMesh(TEXT("/Script/Engine.StaticMesh'/Game/SpaceShip/Spaceship_ARA.Spaceship_ARA'"));
//로딩 성공하면 SpaceShipMesh에 사용할 Static Mesh로 TempMesh를 넣는다.
if (TempMesh.Succeeded())
{
SpaceShipMesh->SetStaticMesh(TempMesh.Object);
//부모 기준 상대적 위치값 세팅. 회전 순서는 Y, Z, X 순서임
SpaceShipMesh->SetRelativeRotation(FRotator(0, 90, 90));
//크기 세팅
SpaceShipMesh->SetRelativeScale3D(FVector(6));
}
//총구 컴포넌트 등록
FirePosition = CreateDefaultSubobject<USceneComponent>(TEXT("FirePosition"));
FirePosition->SetupAttachment(BodyMesh);
FirePosition->SetRelativeLocation(FVector(0, 0, 80));
}
// Called when the game starts or when spawned
void ACPlayer::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACPlayer::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//이동
FVector dir(0, h ,v);
FVector P0 = GetActorLocation(); //현재 위치 설정
FVector vt = dir * speed * DeltaTime;
FVector P = P0 + vt;
SetActorLocation(P);
}
// 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;
}
Ctrl+B 빌드
BP_CPlayer에서 Possess 설정
잘 움직인다.
총알 새 C++ 클래스 만들기
우클릭 해서 생성
Actor 설정
솔루션 탐색기 보면 CBullet의 C++와 헤더 파일이 생성된 것을 볼 수 있다.
CPlayer에서 썼던 코드 복붙
헤더 파일
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CBullet.generated.h"
UCLASS()
class SHOOTING_API ACBullet : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ACBullet();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
public:
UPROPERTY(VisibleAnywhere)
class UStaticMeshComponent* BodyMesh;
};
C++ 파일
// Fill out your copyright notice in the Description page of Project Settings.
#include "CBullet.h"
// Sets default values
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;
//BodyMesh 그릇에 StaticMeshComponent를 만들어서 담으려고 한다.
BodyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BodyMesh"));
//BodyMesh를 Root로 등록
RootComponent = BodyMesh;
}
// Called when the game starts or when spawned
void ACBullet::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACBullet::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
이전에 블루프린트로 만들었던 BP_Bullet의 Cube 스케일 값을 사용하기 위해 값을 복사해서 가져온다.
//스케일 값 설정
BodyMesh->SetRelativeScale3D(FVector(1.0f, 0.25f, 0.75f));
만든 CBullet을 블루프린트로 만들기
스케일 값과 BodyMesh 하위 오브젝트가 잘 만들어진 것을 볼 수 있다.
StaticMesh 모델링 넣기
C++ 파일에 코드 추가
//사용할 Static Mesh 데이터를 읽어서 컴포넌트에 할당하기
ConstructorHelpers::FObjectFinder<UStaticMesh> TempMesh(TEXT("/Script/Engine.StaticMesh'/Engine/BasicShapes/Cube.Cube'"));
//로딩 성공하면 BodyMesh에 사용할 Static Mesh로 TempMesh를 넣는다.
if (TempMesh.Succeeded())
{
BodyMesh->SetStaticMesh(TempMesh.Object);
}
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#include "CBullet.h"
// Sets default values
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;
//BodyMesh 그릇에 StaticMeshComponent를 만들어서 담으려고 한다.
BodyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BodyMesh"));
//BodyMesh를 Root로 등록
RootComponent = BodyMesh;
//스케일 값 설정
BodyMesh->SetRelativeScale3D(FVector(1.0f, 0.25f, 0.75f));
//사용할 Static Mesh 데이터를 읽어서 컴포넌트에 할당하기
ConstructorHelpers::FObjectFinder<UStaticMesh> TempMesh(TEXT("/Script/Engine.StaticMesh'/Engine/BasicShapes/Cube.Cube'"));
//로딩 성공하면 BodyMesh에 사용할 Static Mesh로 TempMesh를 넣는다.
if (TempMesh.Succeeded())
{
BodyMesh->SetStaticMesh(TempMesh.Object);
}
}
// Called when the game starts or when spawned
void ACBullet::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACBullet::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
에디터를 껐다 켜면, 큐브가 잘 들어온 것을 볼 수 있다.
메테리얼 적용하기
C++ 코드 추가
// 메테리얼 로드하기
ConstructorHelpers::FObjectFinder<UMaterial> TempMat(TEXT("/Script/Engine.Material'/Engine/BasicShapes/BasicShapeMaterial.BasicShapeMaterial'"));
//로딩 성공하면 BodyMesh에 사용할 Static Mesh로 TempMesh를 넣는다.
if (TempMat.Succeeded())
{
BodyMesh->SetMaterial(0, TempMat.Object);
}
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#include "CBullet.h"
// Sets default values
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;
//BodyMesh 그릇에 StaticMeshComponent를 만들어서 담으려고 한다.
BodyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BodyMesh"));
//BodyMesh를 Root로 등록
RootComponent = BodyMesh;
//스케일 값 설정
BodyMesh->SetRelativeScale3D(FVector(1.0f, 0.25f, 0.75f));
//사용할 Static Mesh 데이터를 읽어서 컴포넌트에 할당하기
ConstructorHelpers::FObjectFinder<UStaticMesh> TempMesh(TEXT("/Script/Engine.StaticMesh'/Engine/BasicShapes/Cube.Cube'"));
//로딩 성공하면 BodyMesh에 사용할 Static Mesh로 TempMesh를 넣는다.
if (TempMesh.Succeeded())
{
BodyMesh->SetStaticMesh(TempMesh.Object);
}
// 메테리얼 로드하기
ConstructorHelpers::FObjectFinder<UMaterial> TempMat(TEXT("/Script/Engine.Material'/Engine/BasicShapes/BasicShapeMaterial.BasicShapeMaterial'"));
//로딩 성공하면 BodyMesh에 사용할 Static Mesh로 TempMesh를 넣는다.
if (TempMat.Succeeded())
{
BodyMesh->SetMaterial(0, TempMat.Object);
}
}
// Called when the game starts or when spawned
void ACBullet::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACBullet::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
Ctrl+B 빌드
메테리얼이 바로 적용이 안된다면,
Class Settings에서 Parent Calss를 Actor로 한 번 바꿔준 후 다시 CBullet으로 돌아오면 적용이 된다.
적용이 잘 되었다.
총알 이동 처리
헤더 파일 코드 추가
public:
float speed = 500;
C++ 코드 추가
void ACBullet::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//이동
FVector dir(0, 0, 1);
FVector P0 = GetActorLocation(); //현재 위치 설정
FVector vt = dir * speed * DeltaTime;
FVector P = P0 + vt;
SetActorLocation(P);
}
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#include "CBullet.h"
// Sets default values
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;
//BodyMesh 그릇에 StaticMeshComponent를 만들어서 담으려고 한다.
BodyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BodyMesh"));
//BodyMesh를 Root로 등록
RootComponent = BodyMesh;
//스케일 값 설정
BodyMesh->SetRelativeScale3D(FVector(1.0f, 0.25f, 0.75f));
//사용할 Static Mesh 데이터를 읽어서 컴포넌트에 할당하기
ConstructorHelpers::FObjectFinder<UStaticMesh> TempMesh(TEXT("/Script/Engine.StaticMesh'/Engine/BasicShapes/Cube.Cube'"));
//로딩 성공하면 BodyMesh에 사용할 Static Mesh로 TempMesh를 넣는다.
if (TempMesh.Succeeded())
{
BodyMesh->SetStaticMesh(TempMesh.Object);
}
// 메테리얼 로드하기
ConstructorHelpers::FObjectFinder<UMaterial> TempMat(TEXT("/Script/Engine.Material'/Engine/BasicShapes/BasicShapeMaterial.BasicShapeMaterial'"));
//로딩 성공하면 BodyMesh에 사용할 Static Mesh로 TempMesh를 넣는다.
if (TempMat.Succeeded())
{
BodyMesh->SetMaterial(0, TempMat.Object);
}
}
// Called when the game starts or when spawned
void ACBullet::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACBullet::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//이동
FVector dir(0, 0, 1);
FVector P0 = GetActorLocation(); //현재 위치 설정
FVector vt = dir * speed * DeltaTime;
FVector P = P0 + vt;
SetActorLocation(P);
}
Ctrl+B 빌드
에디터에서 BP_CBullet 끌어다 놓고 위치 수정하고 실행하면 위로 올라가는 것을 볼 수 있다.
총알 속도 조절 가능하도록 코드 수정
public:
UPROPERTY(EditAnywhere)
float speed = 500;
블루프린트에서도 사용할 수 있게 수정
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float speed = 500;
카테고리 추가도 가능하다.
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="MySettings")
float speed = 500
발사 버튼을 누를 때 총알이 발사 되도록 설정
CPlayer.h 코드 추가
//발사 버튼 입력 처리 함수
void Fire();
//총알 공장
UPROPERTY(EditAnywhere, Category = "Bullet")
TSubclassOf<class ACBullet> bulletFactory; //ACBullet의 하위 클래스
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "CPlayer.generated.h"
UCLASS()
class SHOOTING_API ACPlayer : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
ACPlayer();
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:
UPROPERTY(VisibleAnywhere)
class UStaticMeshComponent* BodyMesh;
UPROPERTY(VisibleAnywhere)
class UStaticMeshComponent* SpaceShipMesh;
UPROPERTY(VisibleAnywhere)
class USceneComponent* FirePosition;
public:
//좌우, 상하 방향, 이동 속도 설정
float h = 0;
float v = 0;
float speed = 500;
void Horizontal(float value);
void Vertical(float value);
//발사 버튼 입력 처리 함수
void Fire();
//총알 공장
UPROPERTY(EditAnywhere, Category = "Bullet")
TSubclassOf<class ACBullet> bulletFactory; //ACBullet의 하위 클래스
};
빌드 후 에디터에서 보면 ACBullet의 하위 클래스만 뜨는 것을 볼 수 있고, BP_CBullet을 선택한다.
CPlayer.cpp 코드 추가
#include <CBullet.h>
//총알 발사 버튼 입력과 처리 함수 엮기
PlayerInputComponent->BindAction(TEXT("Fire"), IE_Pressed, this, &ACPlayer::Fire);
void ACPlayer::Fire()
{
//총알 발사
GetWorld()->SpawnActor<ACBullet>(bulletFactory, FirePosition->GetComponentLocation(), FRotator());
}
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#include "CPlayer.h"
#include <CBullet.h>
// Sets default values
ACPlayer::ACPlayer()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
//BodyMesh 그릇에 StaticMeshComponent를 만들어서 담으려고 한다.
BodyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BodyMesh"));
//BodyMesh를 Root로 등록
RootComponent = BodyMesh;
SpaceShipMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SpaceShipMesh"));
SpaceShipMesh->SetupAttachment(BodyMesh);
//사용할 Static Mesh 데이터를 읽어서 컴포넌트에 할당하기
ConstructorHelpers::FObjectFinder<UStaticMesh> TempMesh(TEXT("/Script/Engine.StaticMesh'/Game/SpaceShip/Spaceship_ARA.Spaceship_ARA'"));
//로딩 성공하면 SpaceShipMesh에 사용할 Static Mesh로 TempMesh를 넣는다.
if (TempMesh.Succeeded())
{
SpaceShipMesh->SetStaticMesh(TempMesh.Object);
//부모 기준 상대적 위치값 세팅. 회전 순서는 Y, Z, X 순서임
SpaceShipMesh->SetRelativeRotation(FRotator(0, 90, 90));
//크기 세팅
SpaceShipMesh->SetRelativeScale3D(FVector(6));
}
//총구 컴포넌트 등록
FirePosition = CreateDefaultSubobject<USceneComponent>(TEXT("FirePosition"));
FirePosition->SetupAttachment(BodyMesh);
FirePosition->SetRelativeLocation(FVector(0, 0, 80));
}
// Called when the game starts or when spawned
void ACPlayer::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACPlayer::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//이동
FVector dir(0, h ,v);
FVector P0 = GetActorLocation(); //현재 위치 설정
FVector vt = dir * speed * DeltaTime;
FVector P = P0 + vt;
SetActorLocation(P);
}
// 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);
//총알 발사 버튼 입력과 처리 함수 엮기
PlayerInputComponent->BindAction(TEXT("Fire"), IE_Pressed, this, &ACPlayer::Fire);
}
void ACPlayer::Horizontal(float value) //좌우 입력 처리 함수
{
h = value;
}
void ACPlayer::Vertical(float value) //상하 입력 처리 함수
{
v = value;
}
void ACPlayer::Fire()
{
//총알 발사
GetWorld()->SpawnActor<ACBullet>(bulletFactory, FirePosition->GetComponentLocation(), FRotator());
}
발사가 잘 된다.