void UAssetObjectProperty::ExportTextItem( FString& ValueStr, const void* PropertyValue, const void* DefaultValue, UObject* Parent, int32 PortFlags, UObject* ExportRootScope ) const { FAssetPtr& AssetPtr = *(FAssetPtr*)PropertyValue; FStringAssetReference ID; UObject *Object = AssetPtr.Get(); if (Object) { // Use object in case name has changed. ID = FStringAssetReference(Object); } else { ID = AssetPtr.GetUniqueID(); } if (0 != (PortFlags & PPF_ExportCpp)) { ValueStr += FString::Printf(TEXT("FStringAssetReference(TEXT(\"%s\"))"), *ID.ToString().ReplaceCharWithEscapedChar()); return; } if (!ID.ToString().IsEmpty()) { ValueStr += ID.ToString(); } else { ValueStr += TEXT("None"); } }
void FStreamableManager::AsyncLoadCallback(FStringAssetReference Request) { FStringAssetReference TargetName = Request; FStreamable* Existing = StreamableItems.FindRef(TargetName); UE_LOG(LogStreamableManager, Verbose, TEXT("Stream Complete callback %s"), *TargetName.ToString()); if (!Existing) { // hmm, maybe it was redirected by a consolidate TargetName = ResolveRedirects(TargetName); Existing = StreamableItems.FindRef(TargetName); } if (Existing && Existing->bAsyncLoadRequestOutstanding) { Existing->bAsyncLoadRequestOutstanding = false; if (!Existing->Target) { FindInMemory(TargetName, Existing); } CheckCompletedRequests(Request, Existing); } if (Existing->Target) { UE_LOG(LogStreamableManager, Verbose, TEXT(" Found target %s"), *Existing->Target->GetFullName()); } else { // Async load failed to find the object Existing->bLoadFailed = true; UE_LOG(LogStreamableManager, Verbose, TEXT(" Failed async load."), *TargetName.ToString()); } }
void UAssetObjectProperty::ExportTextItem( FString& ValueStr, const void* PropertyValue, const void* DefaultValue, UObject* Parent, int32 PortFlags, UObject* ExportRootScope ) const { FAssetPtr& AssetPtr = *(FAssetPtr*)PropertyValue; FStringAssetReference ID; UObject *Object = AssetPtr.Get(); if (Object) { // Use object in case name has changed. ID = FStringAssetReference(Object); } else { ID = AssetPtr.GetUniqueID(); } if (!ID.ToString().IsEmpty()) { ValueStr += ID.ToString(); } else { ValueStr += TEXT("None"); } }
struct FStreamable* FStreamableManager::StreamInternal(FStringAssetReference const& InTargetName) { check(IsInGameThread()); UE_LOG(LogStreamableManager, Verbose, TEXT("Asynchronous load %s"), *InTargetName.ToString()); if (FPackageName::IsShortPackageName(InTargetName.ToString())) { UE_LOG(LogStreamableManager, Error, TEXT(" Can't load invalid package name %s"), *InTargetName.ToString()); return NULL; } FStringAssetReference TargetName = ResolveRedirects(InTargetName); FStreamable* Existing = StreamableItems.FindRef(TargetName); if (Existing) { if (Existing->bAsyncUnloadRequestOutstanding) { // It's valid to have a live pointer if an async loaded object was hard referenced later check(!Existing->bAsyncLoadRequestOutstanding); // we should not be both loading and unloading UE_LOG(LogStreamableManager, Verbose, TEXT(" Aborted unload for %s"), *TargetName.ToString()); Existing->bAsyncUnloadRequestOutstanding = false; check(Existing->Target || Existing->bLoadFailed); // should not be an unload request unless the target is valid return Existing; } if (Existing->bAsyncLoadRequestOutstanding) { UE_LOG(LogStreamableManager, Verbose, TEXT(" Already in progress %s"), *TargetName.ToString()); check(!Existing->bAsyncUnloadRequestOutstanding); // we should not be both loading and unloading check(!Existing->Target); // should not be an load request unless the target is invalid return Existing; // already have one in process } if (Existing->Target) { UE_LOG(LogStreamableManager, Verbose, TEXT(" Already Loaded %s"), *TargetName.ToString()); return Existing; } } else { Existing = StreamableItems.Add(TargetName, new FStreamable()); } FindInMemory(TargetName, Existing); if (!Existing->Target) { FString Package = TargetName.ToString(); int32 FirstDot = Package.Find(TEXT(".")); if (FirstDot != INDEX_NONE) { Package = Package.Left(FirstDot); } Existing->bAsyncLoadRequestOutstanding = true; LoadPackageAsync(Package, FLoadPackageAsyncDelegate::CreateStatic(&AsyncLoadCallbackWrapper, new FCallback(TargetName, this)) ); } return Existing; }
/** Handles cleaning up an object library if it matches the passed in object */ void UGameplayCueManager::HandleAssetDeleted(UObject *Object) { FStringAssetReference StringRefToRemove; UBlueprint* Blueprint = Cast<UBlueprint>(Object); if (Blueprint && Blueprint->GeneratedClass) { UGameplayCueNotify_Static* StaticCDO = Cast<UGameplayCueNotify_Static>(Blueprint->GeneratedClass->ClassDefaultObject); AGameplayCueNotify_Actor* ActorCDO = Cast<AGameplayCueNotify_Actor>(Blueprint->GeneratedClass->ClassDefaultObject); if (StaticCDO || ActorCDO) { StringRefToRemove.SetPath(Blueprint->GeneratedClass->GetPathName()); } } if (StringRefToRemove.IsValid()) { TArray<FStringAssetReference> StringRefs; StringRefs.Add(StringRefToRemove); check(GlobalCueSet); GlobalCueSet->RemoveCuesByStringRefs(StringRefs); OnGameplayCueNotifyAddOrRemove.Broadcast(); } }
bool FStreamableManager::IsAsyncLoadComplete(FStringAssetReference const& InTargetName) { check(IsInGameThread()); FStringAssetReference TargetName = ResolveRedirects(InTargetName); FStreamable* Existing = StreamableItems.FindRef(TargetName); UE_LOG(LogStreamableManager, Verbose, TEXT("IsStreamComplete %s -> %d"), *TargetName.ToString(), !Existing || !Existing->bAsyncLoadRequestOutstanding); return !Existing || !Existing->bAsyncLoadRequestOutstanding; }
FArchive& FObjectReader::operator<<( class FAssetPtr& AssetPtr ) { FArchive& Ar = *this; FStringAssetReference ID; ID.Serialize(Ar); AssetPtr = ID; return Ar; }
FArchive& FDuplicateDataReader::operator<<( FAssetPtr& AssetPtr) { FArchive& Ar = *this; FStringAssetReference ID; ID.Serialize(Ar); AssetPtr = ID; return Ar; }
void USoundBase::PostInitProperties() { Super::PostInitProperties(); const FStringAssetReference DefaultSoundClassName = GetDefault<UAudioSettings>()->DefaultSoundClassName; if (DefaultSoundClassName.IsValid()) { SoundClassObject = LoadObject<USoundClass>(NULL, *DefaultSoundClassName.ToString()); } }
// Backwards compat for map strings void FixMapAssetRef(FStringAssetReference& MapAssetReference) { const FString AssetRefStr = MapAssetReference.ToString(); int32 DummyIndex; if (!AssetRefStr.IsEmpty() && !AssetRefStr.FindLastChar(TEXT('.'), DummyIndex)) { FString MapName, MapPath; AssetRefStr.Split(TEXT("/"), &MapPath, &MapName, ESearchCase::IgnoreCase, ESearchDir::FromEnd); MapAssetReference.SetPath(FString::Printf(TEXT("%s/%s.%s"),*MapPath, *MapName, *MapName)); } };
UObject* FStreamableManager::GetStreamed(FStringAssetReference const& InTargetName) { check(IsInGameThread()); FStringAssetReference TargetName = ResolveRedirects(InTargetName); FStreamable* Existing = StreamableItems.FindRef(TargetName); if (Existing && Existing->Target) { UE_LOG(LogStreamableManager, Verbose, TEXT("GetStreamed %s -> %s"), *TargetName.ToString(), *Existing->Target->GetFullName()); return Existing->Target; } UE_LOG(LogStreamableManager, Verbose, TEXT("GetStreamed %s -> NULL"), *TargetName.ToString()); return NULL; }
void USoundBase::PostInitProperties() { Super::PostInitProperties(); if (USoundBase::DefaultSoundClassObject == nullptr) { const FStringAssetReference DefaultSoundClassName = GetDefault<UAudioSettings>()->DefaultSoundClassName; if (DefaultSoundClassName.IsValid()) { USoundBase::DefaultSoundClassObject = LoadObject<USoundClass>(nullptr, *DefaultSoundClassName.ToString()); } } SoundClassObject = USoundBase::DefaultSoundClassObject; if (USoundBase::DefaultSoundSubmixObject == nullptr) { const FStringAssetReference DefaultSoundSubmixName = GetDefault<UAudioSettings>()->DefaultSoundSubmixName; if (DefaultSoundSubmixName.IsValid()) { USoundBase::DefaultSoundSubmixObject = LoadObject<USoundSubmix>(nullptr, *DefaultSoundSubmixName.ToString()); } } SoundSubmixObject = USoundBase::DefaultSoundSubmixObject; if (USoundBase::DefaultSoundConcurrencyObject == nullptr) { const FStringAssetReference DefaultSoundConcurrencyName = GetDefault<UAudioSettings>()->DefaultSoundConcurrencyName; if (DefaultSoundConcurrencyName.IsValid()) { USoundBase::DefaultSoundConcurrencyObject = LoadObject<USoundConcurrency>(nullptr, *DefaultSoundConcurrencyName.ToString()); } } SoundConcurrencySettings = USoundBase::DefaultSoundConcurrencyObject; }
void FStreamableManager::Unload(FStringAssetReference const& InTargetName) { check(IsInGameThread()); FStringAssetReference TargetName = ResolveRedirects(InTargetName); FStreamable* Existing = StreamableItems.FindRef(TargetName); if (Existing) { UE_LOG(LogStreamableManager, Verbose, TEXT("Unload %s"), *TargetName.ToString()); Existing->bAsyncLoadRequestOutstanding = false; Existing->bAsyncUnloadRequestOutstanding = true; } else { UE_LOG(LogStreamableManager, Verbose, TEXT("Attempt to unload %s, but it isn't loaded"), *TargetName.ToString()); } }
FArchive& FLinkerSave::operator<<( FAssetPtr& AssetPtr) { FStringAssetReference ID; UObject *Object = AssetPtr.Get(); if (Object) { // Use object in case name has changed. ID = FStringAssetReference(Object); } else { ID = AssetPtr.GetUniqueID(); } ID.Serialize(*this); return *this; }
FStringAssetReference FStreamableManager::ResolveRedirects(FStringAssetReference const& Target) const { FStringAssetReference const* Redir = StreamableRedirects.Find(Target); if (Redir) { check(Target != *Redir); UE_LOG(LogStreamableManager, Verbose, TEXT("Redirected %s -> %s"), *Target.ToString(), *Redir->ToString()); return *Redir; } return Target; }
void FPaperJsonSpriteSheetImporter::SetReimportData(const TArray<FString>& ExistingSpriteNames, const TArray< TAssetPtr<class UPaperSprite> >& ExistingSpriteAssetPtrs) { check(ExistingSpriteNames.Num() == ExistingSpriteAssetPtrs.Num()); if (ExistingSpriteNames.Num() == ExistingSpriteAssetPtrs.Num()) { for (int i = 0; i < ExistingSpriteAssetPtrs.Num(); ++i) { const TAssetPtr<class UPaperSprite> SpriteAssetPtr = ExistingSpriteAssetPtrs[i]; FStringAssetReference SpriteStringRef = SpriteAssetPtr.ToStringReference(); if (!SpriteStringRef.ToString().IsEmpty()) { UPaperSprite* LoadedSprite = Cast<UPaperSprite>(StaticLoadObject(UPaperSprite::StaticClass(), nullptr, *SpriteStringRef.ToString(), nullptr, LOAD_None, nullptr)); if (LoadedSprite != nullptr) { ExistingSprites.Add(ExistingSpriteNames[i], LoadedSprite); } } } } bIsReimporting = true; }
void UGameplayCueManager::HandleAssetAdded(UObject *Object) { UBlueprint* Blueprint = Cast<UBlueprint>(Object); if (Blueprint && Blueprint->GeneratedClass) { UGameplayCueNotify_Static* StaticCDO = Cast<UGameplayCueNotify_Static>(Blueprint->GeneratedClass->ClassDefaultObject); AGameplayCueNotify_Actor* ActorCDO = Cast<AGameplayCueNotify_Actor>(Blueprint->GeneratedClass->ClassDefaultObject); if (StaticCDO || ActorCDO) { if (IsAssetInLoadedPaths(Object)) { FStringAssetReference StringRef; StringRef.SetPath(Blueprint->GeneratedClass->GetPathName()); TArray<FGameplayCueReferencePair> CuesToAdd; if (StaticCDO) { CuesToAdd.Add(FGameplayCueReferencePair(StaticCDO->GameplayCueTag, StringRef)); } else if (ActorCDO) { CuesToAdd.Add(FGameplayCueReferencePair(ActorCDO->GameplayCueTag, StringRef)); } check(GlobalCueSet); GlobalCueSet->AddCues(CuesToAdd); OnGameplayCueNotifyAddOrRemove.Broadcast(); } else { VerifyNotifyAssetIsInValidPath(Blueprint->GetOuter()->GetPathName()); } } } }
USkeletalMesh* UAnimationAsset::GetPreviewMesh() { USkeletalMesh* PreviewMesh = PreviewSkeletalMesh.Get(); if(!PreviewMesh) { // if preview mesh isn't loaded, see if we have set FStringAssetReference PreviewMeshStringRef = PreviewSkeletalMesh.ToStringReference(); // load it since now is the time to load if(!PreviewMeshStringRef.ToString().IsEmpty()) { PreviewMesh = Cast<USkeletalMesh>(StaticLoadObject(USkeletalMesh::StaticClass(), NULL, *PreviewMeshStringRef.ToString(), NULL, LOAD_None, NULL)); // if somehow skeleton changes, just nullify it. if (PreviewMesh && PreviewMesh->Skeleton != Skeleton) { PreviewMesh = NULL; SetPreviewMesh(NULL); } } } return PreviewMesh; }
void FStreamableManager::FindInMemory(FStringAssetReference& InOutTargetName, struct FStreamable* Existing) { check(Existing); check(!Existing->bAsyncUnloadRequestOutstanding); check(!Existing->bAsyncLoadRequestOutstanding); UE_LOG(LogStreamableManager, Verbose, TEXT(" Searching in memory for %s"), *InOutTargetName.ToString()); Existing->Target = StaticFindObject(UObject::StaticClass(), NULL, *InOutTargetName.ToString()); UObjectRedirector* Redir = Cast<UObjectRedirector>(Existing->Target); if (Redir) { Existing->Target = Redir->DestinationObject; UE_LOG(LogStreamableManager, Verbose, TEXT(" Found redirect %s"), *Redir->GetFullName()); if (!Existing->Target) { Existing->bLoadFailed = true; UE_LOG(LogStreamableManager, Warning, TEXT("Destination of redirector was not found %s -> %s."), *InOutTargetName.ToString(), *Redir->GetFullName()); } else { UE_LOG(LogStreamableManager, Verbose, TEXT(" Redirect to %s"), *Redir->DestinationObject->GetFullName()); } } if (Existing->Target) { FStringAssetReference PossiblyNewName(Existing->Target->GetPathName()); if (InOutTargetName != PossiblyNewName) { UE_LOG(LogStreamableManager, Verbose, TEXT(" Name changed to %s"), *PossiblyNewName.ToString()); StreamableRedirects.Add(InOutTargetName, PossiblyNewName); StreamableItems.Add(PossiblyNewName, Existing); StreamableItems.Remove(InOutTargetName); InOutTargetName = PossiblyNewName; // we are done with the old name } UE_LOG(LogStreamableManager, Verbose, TEXT(" Found in memory %s"), *Existing->Target->GetFullName()); Existing->bLoadFailed = false; } }
USkeletalMesh* USkeleton::GetPreviewMesh(bool bFindIfNotSet) { USkeletalMesh* PreviewMesh = PreviewSkeletalMesh.Get(); if(!PreviewMesh) { // if preview mesh isn't loaded, see if we have set FStringAssetReference PreviewMeshStringRef = PreviewSkeletalMesh.ToStringReference(); // load it since now is the time to load if (!PreviewMeshStringRef.ToString().IsEmpty()) { PreviewMesh = Cast<USkeletalMesh>(StaticLoadObject(USkeletalMesh::StaticClass(), NULL, *PreviewMeshStringRef.ToString(), NULL, LOAD_None, NULL)); } // if not existing, and if bFindIfNotExisting is true, then try find one if (!PreviewMesh && bFindIfNotSet) { FARFilter Filter; Filter.ClassNames.Add(USkeletalMesh::StaticClass()->GetFName()); FString SkeletonString = FAssetData(this).GetExportTextName(); Filter.TagsAndValues.Add(GET_MEMBER_NAME_CHECKED(USkeletalMesh, Skeleton), SkeletonString); TArray<FAssetData> AssetList; FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry")); AssetRegistryModule.Get().GetAssets(Filter, AssetList); if(AssetList.Num() > 0) { SetPreviewMesh( Cast<USkeletalMesh>(AssetList[0].GetAsset()), false ); // update PreviewMesh PreviewMesh = PreviewSkeletalMesh.Get(); } } } return PreviewMesh; }
UAudioComponent* CreateVoiceAudioComponent(uint32 SampleRate) { UAudioComponent* AudioComponent = nullptr; if (GEngine != nullptr) { if (FAudioDevice* AudioDevice = GEngine->GetMainAudioDevice()) { USoundWaveProcedural* SoundStreaming = NewObject<USoundWaveProcedural>(); SoundStreaming->SampleRate = SampleRate; SoundStreaming->NumChannels = 1; SoundStreaming->Duration = INDEFINITELY_LOOPING_DURATION; SoundStreaming->SoundGroup = SOUNDGROUP_Voice; SoundStreaming->bLooping = false; AudioComponent = AudioDevice->CreateComponent(SoundStreaming, nullptr, nullptr, false); if (AudioComponent) { AudioComponent->bIsUISound = true; AudioComponent->bAllowSpatialization = false; AudioComponent->SetVolumeMultiplier(1.5f); const FStringAssetReference VoiPSoundClassName = GetDefault<UAudioSettings>()->VoiPSoundClass; if (VoiPSoundClassName.IsValid()) { AudioComponent->SoundClassOverride = LoadObject<USoundClass>(nullptr, *VoiPSoundClassName.ToString()); } } else { UE_LOG(LogVoiceDecode, Warning, TEXT("Unable to create voice audio component!")); } } } return AudioComponent; }
bool FStringAssetReference::operator==(FStringAssetReference const& Other) const { return ToString() == Other.ToString(); }
void FStringAssetReference::operator=(FStringAssetReference const& Other) { SetPath(Other.ToString()); }
FArchive& FObjectWriter::operator<<( class FAssetPtr& AssetPtr ) { FStringAssetReference ID = AssetPtr.GetUniqueID(); ID.Serialize(*this); return *this; }
void UGameplayCueManager::BuildCuesToAddToGlobalSet(const TArray<FAssetData>& AssetDataList, FName TagPropertyName, bool bAsyncLoadAfterAdd, TArray<FGameplayCueReferencePair>& OutCuesToAdd, FOnGameplayCueNotifySetLoaded OnLoaded, FShouldLoadGCNotifyDelegate ShouldLoad) { IGameplayTagsModule& GameplayTagsModule = IGameplayTagsModule::Get(); TArray<FStringAssetReference> AssetsToLoad; AssetsToLoad.Reserve(AssetDataList.Num()); for (FAssetData Data: AssetDataList) { // If ShouldLoad delegate is bound and it returns false, don't load this one if (ShouldLoad.IsBound() && (ShouldLoad.Execute(Data) == false)) { continue; } const FString* FoundGameplayTag = Data.TagsAndValues.Find(TagPropertyName); if (FoundGameplayTag && FoundGameplayTag->Equals(TEXT("None")) == false) { const FString* GeneratedClassTag = Data.TagsAndValues.Find(TEXT("GeneratedClass")); if (GeneratedClassTag == nullptr) { ABILITY_LOG(Warning, TEXT("Unable to find GeneratedClass value for AssetData %s"), *Data.ObjectPath.ToString()); continue; } ABILITY_LOG(Log, TEXT("GameplayCueManager Found: %s / %s"), **FoundGameplayTag, **GeneratedClassTag); FGameplayTag GameplayCueTag = GameplayTagsModule.GetGameplayTagsManager().RequestGameplayTag(FName(**FoundGameplayTag), false); if (GameplayCueTag.IsValid()) { // Add a new NotifyData entry to our flat list for this one FStringAssetReference StringRef; StringRef.SetPath(FPackageName::ExportTextPathToObjectPath(*GeneratedClassTag)); OutCuesToAdd.Add(FGameplayCueReferencePair(GameplayCueTag, StringRef)); AssetsToLoad.Add(StringRef); } else { ABILITY_LOG(Warning, TEXT("Found GameplayCue tag %s in asset %s but there is no corresponding tag in the GameplayTagManager."), **FoundGameplayTag, *Data.PackageName.ToString()); } } } if (bAsyncLoadAfterAdd) { auto ForwardLambda = [](TArray<FStringAssetReference> AssetList, FOnGameplayCueNotifySetLoaded OnLoadedDelegate) { OnLoadedDelegate.ExecuteIfBound(AssetList); }; if (AssetsToLoad.Num() > 0) { StreamableManager.RequestAsyncLoad(AssetsToLoad, FStreamableDelegate::CreateStatic( ForwardLambda, AssetsToLoad, OnLoaded)); } else { // Still fire the delegate even if nothing was found to load OnLoaded.ExecuteIfBound(AssetsToLoad); } } }
UObject* FStreamableManager::SynchronousLoad(FStringAssetReference const& InTargetName) { UE_LOG(LogStreamableManager, Verbose, TEXT("Synchronous load %s"), *InTargetName.ToString()); if (FPackageName::IsShortPackageName(InTargetName.ToString())) { UE_LOG(LogStreamableManager, Error, TEXT(" Can't load invalid package name %s"), *InTargetName.ToString()); return NULL; } FStringAssetReference TargetName = ResolveRedirects(InTargetName); FStreamable* Existing = StreamableItems.FindRef(TargetName); while (Existing && Existing->bAsyncLoadRequestOutstanding) { UE_LOG(LogStreamableManager, Verbose, TEXT(" Flushing async load for %s"), *TargetName.ToString()); check(!Existing->bAsyncUnloadRequestOutstanding); // we should not be both loading and unloading FlushAsyncLoading(); // the async request might have found a redirect and retried TargetName = ResolveRedirects(TargetName); Existing = StreamableItems.FindRef(TargetName); } if (!Existing) { Existing = StreamableItems.Add(TargetName, new FStreamable()); } check(!Existing->bAsyncLoadRequestOutstanding); // should have already dealt with this if (Existing->bAsyncUnloadRequestOutstanding) { check(!Existing->bAsyncLoadRequestOutstanding); // we should not be both loading and unloading UE_LOG(LogStreamableManager, Verbose, TEXT(" Aborted unload for %s"), *TargetName.ToString()); Existing->bAsyncUnloadRequestOutstanding = false; } check(!Existing->bAsyncUnloadRequestOutstanding); // should have already dealt with this check(!Existing->WeakTarget.Get()); // weak target is only valid during GC if (!Existing->Target) { UE_LOG(LogStreamableManager, Verbose, TEXT(" Static loading %s"), *TargetName.ToString()); Existing->Target = StaticLoadObject(UObject::StaticClass(), NULL, *TargetName.ToString()); // need to manually detect redirectors because the above call only expects to load a UObject::StaticClass() type while (UObjectRedirector* Redirector = Cast<UObjectRedirector>(Existing->Target)) { Existing->Target = Redirector->DestinationObject; } if (Existing->Target) { UE_LOG(LogStreamableManager, Verbose, TEXT(" Static loaded %s"), *Existing->Target->GetFullName()); FStringAssetReference PossiblyNewName(Existing->Target->GetPathName()); if (PossiblyNewName != TargetName) { UE_LOG(LogStreamableManager, Verbose, TEXT(" Which redirected to %s"), *PossiblyNewName.ToString()); StreamableRedirects.Add(TargetName, PossiblyNewName); StreamableItems.Add(PossiblyNewName, Existing); StreamableItems.Remove(TargetName); TargetName = PossiblyNewName; // we are done with the old name } } else { Existing->bLoadFailed = true; UE_LOG(LogStreamableManager, Log, TEXT("Failed attempt to load %s"), *TargetName.ToString()); } } else { Existing->bLoadFailed = false; } return Existing->Target; }
FArchive& FDuplicateDataWriter::operator<<(FAssetPtr& AssetPtr) { FStringAssetReference ID = AssetPtr.GetUniqueID(); ID.Serialize(*this); return *this; }
void FPaperSpriteSheetAssetTypeActions::ExecuteCreateFlipbooks(TArray<TWeakObjectPtr<UPaperSpriteSheet>> Objects) { for (int SpriteSheetIndex = 0; SpriteSheetIndex < Objects.Num(); ++SpriteSheetIndex) { UPaperSpriteSheet* SpriteSheet = Objects[SpriteSheetIndex].Get(); if (SpriteSheet != nullptr) { const FString PackagePath = FPackageName::GetLongPackagePath(SpriteSheet->GetOutermost()->GetPathName()); FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools"); FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked<FContentBrowserModule>("ContentBrowser"); check(SpriteSheet->SpriteNames.Num() == SpriteSheet->Sprites.Num()); bool useSpriteNames = (SpriteSheet->SpriteNames.Num() == SpriteSheet->Sprites.Num()); // Create a list of sprites and sprite names to feed into paper flipbook helpers TMap<FString, TArray<UPaperSprite*> > SpriteFlipbookMap; { TArray<UPaperSprite*> Sprites; TArray<FString> SpriteNames; for (int SpriteIndex = 0; SpriteIndex < SpriteSheet->Sprites.Num(); ++SpriteIndex) { auto SpriteAssetPtr = SpriteSheet->Sprites[SpriteIndex]; FStringAssetReference SpriteStringRef = SpriteAssetPtr.ToStringReference(); UPaperSprite* Sprite = nullptr; if (!SpriteStringRef.ToString().IsEmpty()) { Sprite = Cast<UPaperSprite>(StaticLoadObject(UPaperSprite::StaticClass(), nullptr, *SpriteStringRef.ToString(), nullptr, LOAD_None, nullptr)); } if (Sprite != nullptr) { const FString SpriteName = useSpriteNames ? SpriteSheet->SpriteNames[SpriteIndex] : Sprite->GetName(); Sprites.Add(Sprite); SpriteNames.Add(SpriteName); } } FPaperFlipbookHelpers::ExtractFlipbooksFromSprites(/*out*/ SpriteFlipbookMap, Sprites, SpriteNames); } // Create one flipbook for every grouped flipbook name if (SpriteFlipbookMap.Num() > 0) { UPaperFlipbookFactory* FlipbookFactory = NewObject<UPaperFlipbookFactory>(); GWarn->BeginSlowTask(NSLOCTEXT("Paper2D", "Paper2D_CreateFlipbooks", "Creating flipbooks from selection"), true, true); int Progress = 0; int TotalProgress = SpriteFlipbookMap.Num(); TArray<UObject*> ObjectsToSync; for (auto It : SpriteFlipbookMap) { GWarn->UpdateProgress(Progress++, TotalProgress); const FString& FlipbookName = It.Key; TArray<UPaperSprite*>& Sprites = It.Value; const FString TentativePackagePath = PackageTools::SanitizePackageName(PackagePath + TEXT("/") + FlipbookName); FString DefaultSuffix; FString AssetName; FString PackageName; AssetToolsModule.Get().CreateUniqueAssetName(TentativePackagePath, DefaultSuffix, /*out*/ PackageName, /*out*/ AssetName); FlipbookFactory->KeyFrames.Empty(); for (int32 SpriteIndex = 0; SpriteIndex < Sprites.Num(); ++SpriteIndex) { FPaperFlipbookKeyFrame* KeyFrame = new (FlipbookFactory->KeyFrames) FPaperFlipbookKeyFrame(); KeyFrame->Sprite = Sprites[SpriteIndex]; KeyFrame->FrameRun = 1; } if (UObject* NewAsset = AssetToolsModule.Get().CreateAsset(AssetName, PackagePath, UPaperFlipbook::StaticClass(), FlipbookFactory)) { ObjectsToSync.Add(NewAsset); } if (GWarn->ReceivedUserCancel()) { break; } } GWarn->EndSlowTask(); if (ObjectsToSync.Num() > 0) { ContentBrowserModule.Get().SyncBrowserToAssets(ObjectsToSync); } } } } }