UEのQuartzをC++から触ってみる
頑張ってBlueprintをC++変換する練習をしているので、
備忘録がてらQuartzのビートごとにイベントが呼ばれる簡単なサンプルをC++で書いてみました。
Blueprint版
C++
SandboxActor.cpp
#include "SandboxActor.h"
#include "Components/AudioComponent.h"
#include "Kismet/KismetSystemLibrary.h"
ASandboxActor::ASandboxActor()
{
PrimaryActorTick.bCanEverTick = true;
ClockHandleCpp = CreateDefaultSubobject<UQuartzClockHandle>(TEXT("ClockHandleCpp"));
RootCpp = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
AudioComponentCpp = CreateDefaultSubobject<UAudioComponent>(TEXT("AudioCpp"));
SetRootComponent(RootCpp);
AudioComponentCpp->SetupAttachment(RootCpp);
}
void ASandboxActor::BeginPlay()
{
Super::BeginPlay();
EnableInput(GetWorld()->GetFirstPlayerController());
InputComponent->BindKey(EKeys::H, IE_Pressed, this, &ASandboxActor::PressedH);
}
void ASandboxActor::PressedH()
{
FQuartzQuantizationBoundary QuantizationBoundary = FQuartzQuantizationBoundary(EQuartzCommandQuantization::Bar);
AudioComponentCpp->PlayQuantized(
this,
ClockHandleCpp,
QuantizationBoundary,
FOnQuartzCommandEventBP(),
0.0f,
0.0f,
1.0f,
EAudioFaderCurve::Linear
);
FOnQuartzMetronomeEventBP OnQuantizationEvent;
OnQuantizationEvent.BindDynamic(this, &ASandboxActor::MyQuantizationEvent);
ClockHandleCpp->SubscribeToQuantizationEvent(
this,
EQuartzCommandQuantization::Bar,
OnQuantizationEvent,
ClockHandleCpp
);
ClockHandleCpp->ResumeClock(
this,
ClockHandleCpp
);
}
void ASandboxActor::MyQuantizationEvent(FName ClockName, EQuartzCommandQuantization QuantizationType, int32 NumBars, int32 Beat, float BeatFraction)
{
UKismetSystemLibrary::PrintString(this, "MyQuantizationEvent");
TickCpp(NumBars); // こういう演出はBP側でできた方が嬉しいのかな〜と思ってあえてBPに残してる
}SandboxActor.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Quartz/AudioMixerClockHandle.h"
#include "SandboxActor.generated.h"
UCLASS()
class SANDBOX_API ASandboxActor : public AActor
{
GENERATED_BODY()
public:
ASandboxActor();
protected:
virtual void BeginPlay() override;
public:
void PressedH();
UFUNCTION(BlueprintCallable)
void MyQuantizationEvent(FName ClockName, EQuartzCommandQuantization QuantizationType, int32 NumBars, int32 Beat, float BeatFraction);
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UQuartzClockHandle* ClockHandleCpp;
UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
void TickCpp(int32 numBars);
protected:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
USceneComponent* RootCpp;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
UAudioComponent* AudioComponentCpp;
};ハマったところ
ASandboxActor::MyQuantizationEventはUFUNCTIONで定義しないとビルドが通るのに呼ばれない。
C++なんだからビルドが通るなら動いて欲しい・・・。
疑問点
ClockHandleCpp->ResumeClock(
this,
ClockHandleCpp
);このへん、引数にClockHandleCpp(自分自身)を渡す意味何!?!?
たぶんBP用のinterfaceなんだろうけれど、C++からはどう呼ぶのが綺麗なんだろう
→ どうやらQuartzが特殊なだけで、他の機能はいい感じに呼べるっぽい。