Callstack
UE::PoseSearch::FSearchContext::UpdateContinuingPoseSearchResult (PoseSearchContext.cpp:945)
UPoseSearchLibrary::MotionMatch (PoseSearchLibrary.cpp:1478)
FAnimNode_MotionMatching::UpdateAssetPlayer (AnimNode_MotionMatching.cpp:204)
FPoseLinkBase::Update (AnimNodeBase.cpp:343)
FAnimNode_ApplyMeshSpaceAdditive::Update_AnyThread (AnimNode_ApplyMeshSpaceAdditive.cpp:41)
FPoseLinkBase::Update (AnimNodeBase.cpp:343)
FAnimNode_ApplyMeshSpaceAdditive::Update_AnyThread (AnimNode_ApplyMeshSpaceAdditive.cpp:41)
Looking at the callstack and the code, we end up in UpdateContinuingPoseSearchResult with an invalid SchemaContinuingPoseSearchResult.
issue seems to be in PoseSearchLibrary when iterating on the Continuing poses, we try to save the first pose search from each schema, but that first one could be invalid. Then if in a different loop we have a valid pose search result we still use the invalid one from earlier.
see
void UPoseSearchLibrary::MotionMatch
...
FCachedContinuingPoseSearchResults CachedContinuingPoseSearchResults;
for (const FAssetsToSearchPerDatabasePair& AssetsToSearchPerDatabasePair : ContinuingPoseAssetsToSearchPerDatabase)
{
const UPoseSearchDatabase* Database = AssetsToSearchPerDatabasePair.Key;
check(Database);
const bool bInvalidatingContinuingPose = IsInvalidatingContinuingPose(ContinuingProperties.InterruptMode, Database, AssetsToSearchPerDatabase);
if (!bInvalidatingContinuingPose)
{
// reconstructing and caching all the required continuing pose search results
FSearchResult DatabaseContinuingPoseSearchResult;
DatabaseContinuingPoseSearchResult.SetAssetTime(ContinuingProperties.PlayingAssetAccumulatedTime);
DatabaseContinuingPoseSearchResult.PoseIdx = Database->GetPoseIndex(ContinuingProperties.PlayingAsset.Get(), ContinuingProperties.PlayingAssetAccumulatedTime, ContinuingProperties.bIsPlayingAssetMirrored, ContinuingProperties.PlayingAssetBlendParameters);
DatabaseContinuingPoseSearchResult.Database = Database;
CachedContinuingPoseSearchResults.CheckedAdd(Database, DatabaseContinuingPoseSearchResult);
// EDITED COMMENT
//Here we save using the schema, but we save even if its invalid and canAdvance will later be false
//Then if we have a valid pose search result with the same Schema in a later loop, it will not override because we use find or add.
const FSearchResult& SchemaContinuingPoseSearchResult = CachedContinuingPoseSearchResults.FindOrAdd(Database->Schema, DatabaseContinuingPoseSearchResult);
const bool bForceInterrupt = IsForceInterrupt(ContinuingProperties.InterruptMode, Database, AssetsToSearchPerDatabase);
const bool bCanAdvance = DatabaseContinuingPoseSearchResult.PoseIdx != INDEX_NONE;
if (bCanAdvance && !bForceInterrupt)
{
SearchContext.UpdateContinuingPoseSearchResult(DatabaseContinuingPoseSearchResult, SchemaContinuingPoseSearchResult);
Database->SearchContinuingPose(SearchContext, SearchResults);
}
}
}
[Attachment Removed]