void UAnimPreviewInstance::MontagePreview_SetLoopAllSections(bool bIsLooping) { if (UAnimMontage* Montage = Cast<UAnimMontage>(CurrentAsset)) { int32 TotalSection = Montage->CompositeSections.Num(); if (TotalSection > 0) { if (bIsLooping) { for (int i = 0; i < TotalSection; ++ i) { Montage_SetNextSection(Montage->CompositeSections[i].SectionName, Montage->CompositeSections[(i+1) % TotalSection].SectionName); } } else { for (int i = 0; i < TotalSection - 1; ++ i) { Montage_SetNextSection(Montage->CompositeSections[i].SectionName, Montage->CompositeSections[i+1].SectionName); } Montage_SetNextSection(Montage->CompositeSections[TotalSection - 1].SectionName, NAME_None); } } } }
void UAnimPreviewInstance::MontagePreview_SetLoopAllSetupSections(bool bIsLooping) { if (UAnimMontage* Montage = Cast<UAnimMontage>(CurrentAsset)) { MontagePreview_ResetSectionsOrder(); int32 TotalSection = Montage->CompositeSections.Num(); if (TotalSection > 0) { FName FirstSection = Montage->CompositeSections[0].SectionName; FName PreviousSection = FirstSection; TArray<bool> AlreadyUsed; AlreadyUsed.AddZeroed(TotalSection); while (true) { // find first not already used section int32 NotUsedIdx = 0; while (NotUsedIdx < TotalSection) { if (! AlreadyUsed[NotUsedIdx]) { break; } ++ NotUsedIdx; } if (NotUsedIdx >= TotalSection) { break; } // go through all connected to join them into one big chain int CurSectionIdx = NotUsedIdx; while (true) { AlreadyUsed[CurSectionIdx] = true; FName CurrentSection = Montage->CompositeSections[CurSectionIdx].SectionName; Montage_SetNextSection(PreviousSection, CurrentSection); PreviousSection = CurrentSection; FName NextSection = Montage->CompositeSections[CurSectionIdx].NextSectionName; CurSectionIdx = Montage->GetSectionIndex(NextSection); if (CurSectionIdx == INDEX_NONE || AlreadyUsed[CurSectionIdx]) // break loops { break; } } } if (bIsLooping) { // and loop all Montage_SetNextSection(PreviousSection, FirstSection); } } } }
void UAnimSingleNodeInstance::SetMontageLoop(UAnimMontage* Montage, bool bIsLooping, FName StartingSection) { check (Montage); int32 TotalSection = Montage->CompositeSections.Num(); if( TotalSection > 0 ) { if (StartingSection == NAME_None) { StartingSection = Montage->CompositeSections[0].SectionName; } FName FirstSection = StartingSection; FName LastSection = StartingSection; bool bSucceeded = false; // find last section int32 CurSection = Montage->GetSectionIndex(FirstSection); int32 Count = TotalSection; while( Count-- > 0 ) { FName NewLastSection = Montage->CompositeSections[CurSection].NextSectionName; CurSection = Montage->GetSectionIndex(NewLastSection); if( CurSection != INDEX_NONE ) { // used to rebuild next/prev Montage_SetNextSection(LastSection, NewLastSection); LastSection = NewLastSection; } else { bSucceeded = true; break; } } if( bSucceeded ) { if ( bIsLooping ) { Montage_SetNextSection(LastSection, FirstSection); } else { Montage_SetNextSection(LastSection, NAME_None); } } // else the default is already looping } }
void UAnimPreviewInstance::MontagePreview_ResetSectionsOrder() { if (UAnimMontage* Montage = Cast<UAnimMontage>(CurrentAsset)) { int32 TotalSection = Montage->CompositeSections.Num(); // restore to default for (int i = 0; i < TotalSection; ++ i) { Montage_SetNextSection(Montage->CompositeSections[i].SectionName, Montage->CompositeSections[i].NextSectionName); } } }