DaySequence基本
UE5.7のDaySequenceプラグインについての調査メモ
2026/05/18 更新
1日を何時間とするか、再生速度、開始時刻はどこで制御しているか
- DayLength:
1日の長さ。デフォルトは24時間 - TimePerCycle:
1日が実時間のどれだけの長さで過ぎるか。デフォルトは5分 - InitialTimeOfDay:
再生開始時刻の指定。デフォルトは6時
DayLengthはデフォルトのままで良さそう。
InitialTImeOfDayはゲームに合わせて調整したら良さそう。
TimePerCycleが制御難しそう。
基本の再生速度をこれで定義して、動的に変化させるのは別途タイムスケールみたいなの用意したい。
SunMoonDaySequenceActor調査
SunLight(DirectionalLight)はどこで制御されてる?
動的生成されてるRootSequencerが持つ、SubSequenceがSunLightを動かしてた。
このSubSequenceは特にアセットがあるわけではなく、動的生成されてるっぽい?
SunLightはDaySequenceCollectionAssetが持つFProceduralDaySequenceのリストデータを元に、動的にシーケンスデータ化して再生されてる。
FProceduralDaySequenceを継承した構造体を独自で用意すれば、複数ライトを独自の制御するシーケンス作れるかも?
ただし基本的に一定の動きをするシーケンスを動的生成するための定義を作るだけのデータなので、細かい独自の動きをするシーケンスを生成する物作るとかは難しそう。
一つのオブジェクトを制御するのに一つFProceduralDaySequence継承構造体を作ってDataAssetのリストデータに登録。
FProceduralDaySequence継承構造体で複数のオブジェクトを制御するシーケンスは作れない。
やる必要もないけど。
例えばMoonLightを制御したいなら、それ用の構造体を用意するか、SunPositionSequence構造体使って制御するコンポーネントをMoonLight指定すればいい。
DaySequenceCollectionAsset.h
public:
UPROPERTY(EditAnywhere, Category="Day Sequence")
TArray<FDaySequenceCollectionEntry> DaySequences;
// このリストにFProceduralDaySequence継承構造体を複数登録していく
UPROPERTY(EditAnywhere, Category="Day Sequence", meta = (ExcludeBaseStruct))
TArray<TInstancedStruct<FProceduralDaySequence>> ProceduralDaySequences;
DaySequenceにはFProceduralDaySequenceを継承した構造体が以下の種類用意されてる。
基本的に用途が決まってるので専用の構造体を継承して作ったほうが良さそう。
- FSunPositionSequence
- FSunAngleSequence
- FSineSequence
InitialTimeOfDayをランタイムで外部パラメータから設定したい
できる?
できなさそう。
できるかも。下記参照。
関数は用意されているが、InitialTimeOfDayを反映させるにはルートシーケンスデータの作り直しが必要になる。
ランタイム中に動的に作り直しは可能か?
もしくは開始時刻分のDaySequenceActorを用意して、シーンに合わせて生成?
そもそもこのアクターを動的生成っていけるのか?
レベルに直置きしてないと使えない?
InitialTimeOfDayを変更しようとするのではなく、SetTimeOfDay関数で時刻操作してやる
/**
* Set the initial time of day in game time in hours.
*
* This is currently intentionally not exposed to Blueprint since
* this property can only be realized by rebuilding the root sequence.
*
* @param InHours initial time of day.
*/
UE_API void SetInitialTimeOfDay(float InHours);
シーケンスのセットアップはActor::PostLoad関数から行われてる。
PostLoadから色々経て最終的にFSunPositionSequence::BuildSequence関数内でシーケンスデータとして生成されてる。
PostLoad関数はレベルにおいてあるアクターがレベルがロードされるタイミングで呼び出される。
SpawnActorからは呼ばれない関数らしい。
SpawnActorからは代わりにPostActorCreated関数が呼ばれる。
この関数からの実装は無さそうなので、DaySequenceActorをSpawnActorするのはうまくいかないかも。
独自実装したActor作ってやればいいか?
PostInitializeComponentsから2回目のシーケンスデータのセットアップ呼ばれてるから動的生成でもいけそう。
タイミング的にSpawnActorしたあとにInitialTimeOfDay変更してもFSunPositionSequence::BuildSequence関数はもう処理されたあとなので、別途独自にBuildSequence呼び出す流れ作らないとダメかも。
1回目のBuildSequence関数 FSunPositionSequence::BuildSequence(UProceduralDaySequenceBuilder *) SunPositionSequence.cpp:175 FProceduralDaySequence::GetSequence(ADaySequenceActor *) ProceduralDaySequence.cpp:22 ADaySequenceActor::InitializeDaySequences() DaySequenceActor.cpp:825 ADaySequenceActor::InitializeRootSequence() DaySequenceActor.cpp:682 ADaySequenceActor::PostLoad() DaySequenceActor.cpp:277 UObject::ConditionalPostLoad() Obj.cpp:1388 UObject::PostLoadSubobjects(FObjectInstancingGraph *) Obj.cpp:1446 UObject::ConditionalPostLoadSubobjects(FObjectInstancingGraph *) Obj.cpp:1514 UObject::ConditionalPostLoad() Obj.cpp:1367 UObject::PostLoadSubobjects(FObjectInstancingGraph *) Obj.cpp:1446 UObject::ConditionalPostLoadSubobjects(FObjectInstancingGraph *) Obj.cpp:1514 UObject::ConditionalPostLoad() Obj.cpp:1367 FStaticMeshComponentHelper::GetMaterial<…>(const UStaticMeshComponent &, int, bool, bool) StaticMeshComponentHelper.h:127 [Inlined] UE::Core::Private::Function::TFunctionRefBase::operator()(int) Function.h:414 UStaticMesh::GetUsedMaterials(TArray<…> &, TFunctionRef<…>) StaticMesh.cpp:9960 FStaticMeshComponentHelper::GetUsedMaterials<…>(const UStaticMeshComponent &, TArray<…> &, bool) StaticMeshComponentHelper.h:144 `UWorld::PostDuplicate'::`48'::<lambda_1>::operator()() World.cpp:1434 UWorld::PostDuplicate(bool) World.cpp:1457 StaticDuplicateObjectEx(FObjectDuplicationParameters &) UObjectGlobals.cpp:3305 UWorld::GetDuplicatedWorldForPIE(UWorld *, UPackage *, int) World.cpp:4409 UEditorEngine::CreatePIEWorldByDuplication(FWorldContext &, UWorld *, FString &) PlayLevel.cpp:2381 UGameInstance::InitializeForPlayInEditor(int, const FGameInstancePIEParameters &) GameInstance.cpp:337 UEditorEngine::CreateInnerProcessPIEGameInstance(FRequestPlaySessionParams &, const FGameInstancePIEParameters &, int) PlayLevel.cpp:3002 UEditorEngine::OnLoginPIEComplete_Deferred(int, bool, FString, FPieLoginStruct) PlayLevel.cpp:1628 UEditorEngine::CreateNewPlayInEditorInstance(FRequestPlaySessionParams &, const bool, EPlayNetMode) PlayLevel.cpp:1892 UEditorEngine::StartPlayInEditorSession(FRequestPlaySessionParams &) PlayLevel.cpp:2911 UEditorEngine::StartQueuedPlaySessionRequestImpl() PlayLevel.cpp:1206 UEditorEngine::StartQueuedPlaySessionRequest() PlayLevel.cpp:1103 UEditorEngine::Tick(float, bool) EditorEngine.cpp:2057 UUnrealEdEngine::Tick(float, bool) UnrealEdEngine.cpp:534 FEngineLoop::Tick() LaunchEngineLoop.cpp:5828 [Inlined] EngineTick() Launch.cpp:60 GuardedMain(const wchar_t *) Launch.cpp:192 LaunchWindowsStartup(HINSTANCE__ *, HINSTANCE__ *, char *, int, const wchar_t *) LaunchWindows.cpp:266 WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int) LaunchWindows.cpp:334 2回目のBuildSequence関数 FSunPositionSequence::BuildSequence(UProceduralDaySequenceBuilder *) SunPositionSequence.cpp:175 FProceduralDaySequence::GetSequence(ADaySequenceActor *) ProceduralDaySequence.cpp:22 ADaySequenceActor::InitializeDaySequences() DaySequenceActor.cpp:825 ADaySequenceActor::InitializeRootSequence() DaySequenceActor.cpp:682 ADaySequenceActor::InitializePlayer() DaySequenceActor.cpp:560 ULevel::RouteActorInitialize(int) Level.cpp:3855 UWorld::InitializeActorsForPlay(const FURL &, bool, FRegisterComponentContext *) World.cpp:5933 UGameInstance::StartPlayInEditorGameInstance(ULocalPlayer *, const FGameInstancePIEParameters &) GameInstance.cpp:528 UEditorEngine::CreateInnerProcessPIEGameInstance(FRequestPlaySessionParams &, const FGameInstancePIEParameters &, int) PlayLevel.cpp:3187 UEditorEngine::OnLoginPIEComplete_Deferred(int, bool, FString, FPieLoginStruct) PlayLevel.cpp:1628 UEditorEngine::CreateNewPlayInEditorInstance(FRequestPlaySessionParams &, const bool, EPlayNetMode) PlayLevel.cpp:1892 UEditorEngine::StartPlayInEditorSession(FRequestPlaySessionParams &) PlayLevel.cpp:2911 UEditorEngine::StartQueuedPlaySessionRequestImpl() PlayLevel.cpp:1206 UEditorEngine::StartQueuedPlaySessionRequest() PlayLevel.cpp:1103 UEditorEngine::Tick(float, bool) EditorEngine.cpp:2057 UUnrealEdEngine::Tick(float, bool) UnrealEdEngine.cpp:534 FEngineLoop::Tick() LaunchEngineLoop.cpp:5828 [Inlined] EngineTick() Launch.cpp:60 GuardedMain(const wchar_t *) Launch.cpp:192 LaunchWindowsStartup(HINSTANCE__ *, HINSTANCE__ *, char *, int, const wchar_t *) LaunchWindows.cpp:266 WinMain(HINSTANCE__ *, HINSTANCE__ *, char *, int) LaunchWindows.cpp:334
InitialTimeOfDayを無理に変更しない
無理にInitialTimeOfDay変えて開始時刻を変えようとするのではなく、SetTimeOfDay関数を使って時刻制御してやる
UFUNCTION(BlueprintCallable, Category="TimeOfDay") UE_API bool SetTimeOfDay(float InHours);
ゲーム内で状況に合わせてDaySequenceデータ変えたい場合
例えばシーンごとに1日の長さが変わったりとかする場合、
Sequencerアセットを動的に切り替えるより、プレイヤーであるDaySequenceActorごとバリエーション用意して、状況に合わせて生成するのが良さそう。
DaySequenceActorのBP参照コレクションアセットを用意して、そのコレクションから動的に生成が良いかも。
既存のDaySequenceActorはレベルに直置き前提の作りになってるから、独自にPostActorCreatedからの実装を用意しないとSpawnActorで動的配置無理そう。
PostInitializeComponentsから2回目のシーケンスデータのセットアップ呼ばれてるから動的生成でもいけそう。

