언리얼은 로깅 환경을 위해 UE_LOG 라는 매크로를 제공하고 있다.
사용법은
UE_LOG(카테고리, 로깅 수준, 형식 문자열, 인자..) 이다 .
창 -> 출력 로그를 체크하면 출력로그를 볼수있다.
먼저 ArenaBattle 의 선언부와 구현부를 위와같이 해준다음.
분수대의 선언부와 구현부에
각각 추가한다.
안되다가 껐다키니까 된다.
그리고 언리얼엔진도 유니티와 같이 이벤트 함수가 존재한다.
유니티와 언리얼을 비교해보자
익숙한 유니티와 비교하니 어떤것인지 확실히 알것같다.
이렇게 분수대 선언부에 위와같은 코드를 작성하면
Meta = (AllowPrivateAccess = true)구문을 이용해서 캡슐화할수있다.
그리고 구현부에
넣어둔 다음.
Tick에 코드를 작성한다.
그리고 언리얼 엔진에서는 움직임 이라는 요소를 분리해 액터와 별도로 관리하도록 프레임워크를 구성했는데, 이것이 무브먼트 컴포넌트다.
언리얼 엔진은 여러가지 무브먼트 컴폰넌트를 제공하는데
FloatingPawnMovement : 중력의 영향을 받지 않는 액터의 움직임을 제공한다. 입력에 따라 자유롭게 움직이도록 설계됐다.
RotatingMovement : 지정한 속도로 액터를 회전시킨다.
InterpMovement : 지정한 위치로 액터를 이동시킨다.
ProjectileMovement : 액터에 중력의 영햐을 받아 포물선을 그리는 발사체의 움직임을 제공한다. 주로 총알, 미사일 등에 사용한다.
이번에는 RotatingMovement를 사용해본다 .
선언부에 추가를 해주고,
구현부에서 bCanEverTick를 false 해줍니다.
를 추가해줍니다.
그럼 이렇게 회전하는 분수대를 구현할수있다.
Fountian.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "ArenaBattle/ArenaBattle.h"
#include "GameFramework/RotatingMovementComponent.h"
#include "GameFramework/Actor.h"
#include "Fountian.generated.h"
UCLASS()
class ARENABATTLE_API AFountian : public AActor
{
GENERATED_BODY()
UPROPERTY(VisibleAnywhere)
URotatingMovementComponent* Movement;
public:
// Sets default values for this actor's properties
AFountian();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(VisibleAnywhere)
UStaticMeshComponent* Body;
UPROPERTY(VisibleAnywhere)
UStaticMeshComponent* Water;
UPROPERTY(VisibleAnywhere)
UPointLightComponent* Light;
UPROPERTY(VisibleAnywhere)
UParticleSystemComponent* Splash;
UPROPERTY(EditAnywhere, Category=ID)
int32 ID;
private:
UPROPERTY(EditAnywhere, Category = Stat, Meta = (AllowPrivateAccess = true))
float RotateSpeed;
};
Fountain.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Fountian.h"
// Sets default values
AFountian::AFountian()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = false;
Body = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BODY"));
Water = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Water"));
Light = CreateDefaultSubobject<UPointLightComponent>(TEXT("Light"));
Splash = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("SPLASH"));
Movement = CreateDefaultSubobject<URotatingMovementComponent>(TEXT("MOVEMENT"));
RootComponent = Body;
Water->SetupAttachment(Body);
Light->SetupAttachment(Body);
Splash->SetupAttachment(Body);
Water->SetRelativeLocation(FVector(0.0f, 0.0f, 135.0f));
Light->SetRelativeLocation(FVector(0.0f, 0.0f, 195.0f));
Splash->SetRelativeLocation(FVector(0.0f, 0.0f, 195.0f));
static ConstructorHelpers::FObjectFinder<UStaticMesh>SM_BODY(TEXT("/Game/Chapter1/Content/InfinityBladeGrassLands/Environments/Plains/Env_Plains_Ruins/StaticMesh/SM_Plains_Castle_Fountain_01.SM_Plains_Castle_Fountain_01"));
if (SM_BODY.Succeeded()) {
Body->SetStaticMesh(SM_BODY.Object);
}
static ConstructorHelpers::FObjectFinder<UStaticMesh>SM_WATER(TEXT("/Game/Chapter1/Content/InfinityBladeGrassLands Effects/FX_Meshes/Env/SM_Plains_Fountain_02.SM_Plains_Fountain_02"));
if (SM_WATER.Succeeded()) {
Water->SetStaticMesh(SM_WATER.Object);
}
static ConstructorHelpers::FObjectFinder<UParticleSystem>PS_SPLASH(TEXT("/Game/Chapter1/Content/InfinityBladeGrassLands/Effects/FX_Ambient/Water/P_Water_Fountain_Splash_Base_01.P_Water_Fountain_Splash_Base_01"));
if (PS_SPLASH.Succeeded()) {
Splash->SetTemplate(PS_SPLASH.Object);
}
RotateSpeed = 30.0f;
Movement->RotationRate = FRotator(0.0f, RotateSpeed, 0.0f);
}
// Called when the game starts or when spawned
void AFountian::BeginPlay()
{
Super::BeginPlay();
UE_LOG(ArenaBattle, Warning, TEXT("Actor Name : %s, ID : %d, Location X : %.3f"),*GetName(), ID, GetActorLocation().X);
}
// Called every frame
void AFountian::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
AddActorLocalRotation(FRotator(0.0f, RotateSpeed * DeltaTime, 0.0f));
}