|
| 1 | +#include "GameFeatureModTemplateDescription.h" |
| 2 | +#include "AssetToolsModule.h" |
| 3 | +#include "Editor.h" |
| 4 | +#include "FileHelpers.h" |
| 5 | +#include "GameFeaturesSubsystem.h" |
| 6 | +#include "AssetRegistry/IAssetRegistry.h" |
| 7 | +#include "Engine/AssetManagerTypes.h" |
| 8 | +#include "HAL/FileManager.h" |
| 9 | +#include "Interfaces/IPluginManager.h" |
| 10 | +#include "Misc/ConfigCacheIni.h" |
| 11 | +#include "Misc/FeedbackContext.h" |
| 12 | +#include "Misc/Paths.h" |
| 13 | +#include "Subsystems/AssetEditorSubsystem.h" |
| 14 | + |
| 15 | +void FGameFeatureModTemplateDescription::UpdatePathWhenTemplateSelected(FString& InOutPath) |
| 16 | +{ |
| 17 | + FString ResultPluginRoot = IFileManager::Get().ConvertToAbsolutePathForExternalAppForWrite(*(FPaths::ProjectModsDir() / TEXT("GameFeatures/"))); |
| 18 | + if (!DefaultSubfolder.IsEmpty()) |
| 19 | + { |
| 20 | + ResultPluginRoot /= DefaultSubfolder + TEXT("/"); |
| 21 | + } |
| 22 | + FPaths::MakePlatformFilename(ResultPluginRoot); |
| 23 | + InOutPath = ResultPluginRoot; |
| 24 | +} |
| 25 | + |
| 26 | +void FGameFeatureModTemplateDescription::UpdatePathWhenTemplateUnselected(FString& InOutPath) |
| 27 | +{ |
| 28 | + InOutPath = IFileManager::Get().ConvertToAbsolutePathForExternalAppForWrite(*FPaths::ProjectModsDir()); |
| 29 | + FPaths::MakePlatformFilename(InOutPath); |
| 30 | +} |
| 31 | + |
| 32 | +void FGameFeatureModTemplateDescription::OnPluginCreated(const TSharedPtr<IPlugin> NewPlugin) |
| 33 | +{ |
| 34 | + // Create a new game feature data asset |
| 35 | + const FAssetToolsModule& AssetToolsModule = FModuleManager::Get().LoadModuleChecked<FAssetToolsModule>(TEXT("AssetTools")); |
| 36 | + const FString AssetName = !GameFeatureDataName.IsEmpty() ? GameFeatureDataName : NewPlugin->GetName(); |
| 37 | + UGameFeatureData* GameFeatureDataAsset = Cast<UGameFeatureData>(AssetToolsModule.Get().CreateAsset(AssetName, NewPlugin->GetMountedAssetPath(), GameFeatureDataClass, nullptr)); |
| 38 | + |
| 39 | + if (GameFeatureDataAsset != nullptr) |
| 40 | + { |
| 41 | + // Populate asset manager primary asset data for it from the template |
| 42 | + TArray<FString> PrimaryAssetTypeTemplates; |
| 43 | + GConfig->GetArray(TEXT("GameFeatureModTemplateDescription"), TEXT("PrimaryAssetTypeTemplates"), PrimaryAssetTypeTemplates, GConfig->GetConfigFilename(TEXT("Alpakit"))); |
| 44 | + for (const FString& PrimaryAssetTypeTemplate : PrimaryAssetTypeTemplates) |
| 45 | + { |
| 46 | + const FString PrimaryAssetTypeString = PrimaryAssetTypeTemplate.Replace(TEXT("$PluginName"), *NewPlugin->GetName()); |
| 47 | + FPrimaryAssetTypeInfo PrimaryAssetTypeInfo; |
| 48 | + UScriptStruct* ScriptStruct = FindObjectChecked<UScriptStruct>(nullptr, TEXT("/Script/Engine.PrimaryAssetTypeInfo")); |
| 49 | + ScriptStruct->ImportText(*PrimaryAssetTypeString, &PrimaryAssetTypeInfo, nullptr, PPF_None, GWarn, TEXT("PrimaryAssetTypeInfo")); |
| 50 | + GameFeatureDataAsset->GetPrimaryAssetTypesToScan().Add(PrimaryAssetTypeInfo); |
| 51 | + GameFeatureDataAsset->MarkPackageDirty(); |
| 52 | + } |
| 53 | + |
| 54 | + // Save the asset now before we attempt to activate the game feature plugin |
| 55 | + UEditorLoadingAndSavingUtils::SavePackages({GameFeatureDataAsset->GetPackage()}, false); |
| 56 | + |
| 57 | + // Activate the new game feature plugin |
| 58 | + auto AdditionalFilter = [](const FString&, const FGameFeaturePluginDetails&, FBuiltInGameFeaturePluginBehaviorOptions&) -> bool { return true; }; |
| 59 | + UGameFeaturesSubsystem::Get().LoadBuiltInGameFeaturePlugin(NewPlugin.ToSharedRef(), AdditionalFilter, FGameFeaturePluginLoadComplete::CreateLambda([GameFeatureDataAsset](const UE::GameFeatures::FResult&) |
| 60 | + { |
| 61 | + // Edit the new game feature data |
| 62 | + if (GameFeatureDataAsset != nullptr) |
| 63 | + { |
| 64 | + GEditor->GetEditorSubsystem<UAssetEditorSubsystem>()->OpenEditorForAsset(GameFeatureDataAsset); |
| 65 | + } |
| 66 | + })); |
| 67 | + } |
| 68 | +} |
0 commit comments