概要
UnrealEngine5 のシーケンサー関連の小ネタです。
レベルシーケンス作成方法等は他のページをご覧ください。
更新履歴
日付 | 内容 |
---|---|
2024/08/09 | 初版 |
2024/09/06 | fbxでのカメラデータインポートについて追記 |
参考
以下の記事を参考にいたしました、ありがとうございます。
UE公式:シーケンサーの概要
【UE5】シーケンサーの使い方
【初心者向け】UE5 シーケンサーと Movie Render Queue の使い方【Cinematic Dive 2023】
[UE4][C++]シーケンサーで非対応のパラメータを制御可能にする方法
UE4 シーケンサーを一時停止する
環境
Windows10
Visual Studio 2022
UnrealEngine 5.3.2
関連ソース
"Engine\Source\Runtime\LevelSequence\Public\LevelSequence.h"
"Engine\Source\Runtime\LevelSequence\Public\LevelSequencePlayer.h"
"Engine\Source\Runtime\MovieScene\Public\MovieSceneSequencePlaybackSettings.h"
"Engine\Source\Runtime\MovieScene\Public\MovieSceneSequencePlayer.h"
"Engine\Source\Runtime\Engine\Classes\GameFramework\PlayerController.h"
シーケンサー
BPでの再生
プレイヤーを作成して再生します。
OutActor
に対してSelf
を入れていますがレベルシーケンス側でActorの位置による処理がなければ不要です。
C++での再生
C++でのシーケンサー再生コード例。
再生終了時のコールバックもやっています。
UCLASS()
class SAMPLE_API UMyComponent : public UActorComponent
{
GENERATED_BODY()
..省略..
public:
// デモを再生する
UFUNCTION(BlueprintCallable)
void PlayDemo(ULevelSequence* _LevelSequence);
// デモを停止する
UFUNCTION(BlueprintCallable)
void StopDemo();
// 再生中か?
UFUNCTION(BlueprintCallable)
bool IsDemo() const;
// レベルシーケンスアセット
UPROPERTY(EditAnywhere, BlueprintReadOnly)
TObjectPtr<ULevelSequence> LevelSequence;
// 再生終了時コールバック
UFUNCTION()
void CallBackFinished(){ UE_LOG(LogTemp, Log, TEXT("CallBackFinished.")); }
protected:
// レベルシーケンスプレイヤー
TWeakObjectPtr<ULevelSequencePlayer> LevelSequencePlayer = nullptr;
};
// 再生
void UMyComponent::PlayDemo(ULevelSequence* _LevelSequence)
{
FMovieSceneSequencePlaybackSettings _Settings;
ALevelSequenceActor* _OutActor;
// レベルシーケンスプレイヤーを作成
LevelSequencePlayer = ULevelSequencePlayer::CreateLevelSequencePlayer(this->GetWorld(), _LevelSequence, _Settings, _OutActor);
// イベントデリゲート(FOnMovieSceneSequencePlayerEvent)コールバック
LevelSequencePlayer.Get()->OnFinished.AddDynamic(this, &ThisClass::CallBackFinished);
if(::IsValid(_OutActor)){
_OutActor->bOverrideInstanceData = true;
auto _InstanceData = Cast<UDefaultLevelSequenceInstanceData>(_OutActor->DefaultInstanceData);
if (_InstanceData) {
_InstanceData->TransformOriginActor = GetOwner();
}
}
// 再生開始
if(LevelSequencePlayer.Get()){
LevelSequencePlayer.Get()->Play();
}
}
// 停止
void UMyComponent::StopDemo()
{
// 再生停止
if(LevelSequencePlayer.Get()){
LevelSequencePlayer.Get()->Stop();
}
}
// 再生中か?
bool UMyComponent::IsDemo() const
{
if(LevelSequencePlayer.Get()){
return(LevelSequencePlayer.Get()->IsPlaying());
}
return(false);
}
コールバックイベントは再生終了時OnFinished
の他に 再生開始時OnPlay
、逆再生開始時OnPlayReverse
、停止時OnStop
、一時停止時OnPause
があります。
再生/終了時の処理
シーケンサー再生時にシネマティックモードの設定として APlayerController
のSetCinematicMode(bool, bool, bool)
が呼ばれますがこれは実体のほうのUFUNCTION()がついたSetCinematicMode(bool, bool, bool, bool, bool)
から呼ばれているようです。
// シネマティックモードに基づいて入力を調整する
ENGINE_API virtual void SetCinematicMode(bool bInCinematicMode, bool bAffectsMovement, bool bAffectsTurning)
// プレイヤーがシネマティック モードかどうかを変更するためのサーバー/SP 専用関数。さまざまな状態変数の値を更新し、クライアントへの呼び出しを複製します
// * 現在のシネマティック モードを同期します。
UFUNCTION(BlueprintCallable, Category="Game|Cinematic", meta=(bHidePlayer="true", bAffectsHUD="true"))
ENGINE_API virtual void SetCinematicMode(bool bInCinematicMode, bool bHidePlayer, bool bAffectsHUD, bool bAffectsMovement, bool bAffectsTurning);
カメラデータ(fbx)のインポート
デザインツールなどからカメラデータを取り込むにはfbx形式で出力し、インポートすることができます。
再インポートはカメラアクターを右クリックしてインポートでできます、この時カメラアクター名が違うと警告が出ます。
CineCamera
レベルシーケンスのCine Camera Actor は ACineCameraActor
を継承したクラスに差し替えができます。
以下は ACineCameraActor
クラスを継承したコード例。
BecomeViewTarget
は ViewTargetになった時に呼ばれるメソッド、EndViewTarget
はViewTagetではなくなった時に呼ばれるメソッドです。
#pragma once
#include "CoreMinimal.h"
#include "CineCameraActor.h"
#include "GameplayTagContainer.h"
#include "MyCineCameraActor.generated.h"
UCLASS()
class SAMPLE_API AMyCineCameraActor : public ACineCameraActor
{
GENERATED_BODY()
public:
AMyCineCameraActor(const FObjectInitializer& ObjectInitializer);
// virtual void BeginPlay() override;
// virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
// このアクタが指定された PlayerController の ViewTarget になった時に呼び出されます。
virtual void BecomeViewTarget( class APlayerController* _PC );
// このアクタが指定された PlayerController の ViewTarget でなくなった時に呼び出されます。
virtual void EndViewTarget( class APlayerController* _PC );
};
#include "./MyCineCameraActor.h"
#include "GameFramework/PlayerController.h"
AMyCineCameraActor::AMyCineCameraActor(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
PrimaryActorTick.bCanEverTick = false;
SetActorTickEnabled(false);
}
// ViewTargetになった時に呼ばれる処理
void AMyCineCameraActor::BecomeViewTarget(class APlayerController* _PC)
{
Super::BecomeViewTarget(_PC);
UE_LOG(LogTemp, Log, TEXT("BecomeViewTarget"));
}
// ViewTargetではなくなった時に呼ばれる処理
void AMyCineCameraActor::EndViewTarget(class APlayerController* _PC)
{
Super::EndViewTarget(_PC);
UE_LOG(LogTemp, Log, TEXT("EndViewTarget"));
}
シーケンサーイベント後にゲームカメラへ繋ぐ処理などを作ることができると思います。
まとめ
会話イベントなど、ボタン送りをするイベントに使う方法はないものですかね。