监听资源创建 / 操作事件

资源创建

在 Editor 中创建资源,并没有直接保存到磁盘上,所以要监听OnInMemoryAssetCreated

1
2
3
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(
TEXT("AssetRegistry"));
AssetRegistryModule.Get().OnInMemoryAssetCreated().AddRaw(this, &FTestEditorModule::OnInMemoryAssetCreated);

回调过来的就是一个UObject*,实际上是一个UBlueprint*

1
2
3
4
5
6
7
8
void FTestEditorModule::OnInMemoryAssetCreated(UObject* Object)
{
if (nullptr == Object) return;

UBlueprint* Blueprint = Cast<UBlueprint>(Object);
if (nullptr == Blueprint) return;
// ...
}

可以实现监听 uasset 创建事件,对该 uasset 执行一些操作(如默认添加接口等)。

拿到 UBlueprint 后就可以通过 FBlueprintEditorUtils 等辅助类来实现对蓝图资源的操作了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
bool FTestEditor::AddInterface(UBlueprint* Blueprint)
{
if (nullptr == Blueprint) return false;

UClass* Class = Blueprint ? *Blueprint->GeneratedClass : Blueprint ? Blueprint->GetClass() : NULL;
if (nullptr == Class) return false;

if (!Class->IsChildOf<UUserWidget>()) return false;

static UClass* InterfaceClass = UUnLuaInterface::StaticClass();

UFunction* Func = FBlueprintEditorUtils::GetInterfaceFunction(Blueprint, FName("GetModuleName"));
if (nullptr == Func)
{
FBlueprintEditorUtils::ImplementNewInterface(Blueprint, InterfaceClass->GetFName());
}

Func = FBlueprintEditorUtils::GetInterfaceFunction(Blueprint, FName("GetModuleName"));
if (nullptr == Func) return false;

auto ImplementedInterfaces = Blueprint->ImplementedInterfaces;
if (ImplementedInterfaces.Num() <= 0) return false;

auto InterfacesDesc = ImplementedInterfaces[0];

auto Graphs = InterfacesDesc.Graphs;
if (Graphs.Num() <= 0) return false;

auto Graph = Graphs[0]; //UEdGraph
if (nullptr == Graph) return false;

auto Nodes = Graph->Nodes;
if (Nodes.Num() <= 0) return false;

auto Node = Nodes[1]; //UEdGraphNode
if (nullptr == Node) return false;

auto Pins = Node->Pins;
if (Pins.Num() <= 0) return false;

auto Pin = Pins[1]; //UEdGraphPin
if (nullptr == Pin) return false;

FString moduleName;
UnLuaExtensionUtils::GetLuaModuleName(Class->GetName(), Class->GetPathName(), moduleName);

Pin->DefaultValue = moduleName;

return true;
}

监听资源操作事件

可以通过 IAssetRegistry 获取到下列事件的 delegate 并监听:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DECLARE_DERIVED_EVENT(UAssetRegistryImpl, IAssetRegistry::FAssetAddedEvent, FAssetAddedEvent);
virtual FAssetAddedEvent& OnAssetAdded() override { return AssetAddedEvent; }

DECLARE_DERIVED_EVENT(UAssetRegistryImpl, IAssetRegistry::FAssetRemovedEvent, FAssetRemovedEvent);
virtual FAssetRemovedEvent& OnAssetRemoved() override { return AssetRemovedEvent; }

DECLARE_DERIVED_EVENT(UAssetRegistryImpl, IAssetRegistry::FAssetRenamedEvent, FAssetRenamedEvent);
virtual FAssetRenamedEvent& OnAssetRenamed() override { return AssetRenamedEvent; }

DECLARE_DERIVED_EVENT(UAssetRegistryImpl, IAssetRegistry::FAssetUpdatedEvent, FAssetUpdatedEvent);
virtual FAssetUpdatedEvent& OnAssetUpdated() override { return AssetUpdatedEvent; }

DECLARE_DERIVED_EVENT(UAssetRegistryImpl, IAssetRegistry::FInMemoryAssetCreatedEvent, FInMemoryAssetCreatedEvent);
virtual FInMemoryAssetCreatedEvent& OnInMemoryAssetCreated() override { return InMemoryAssetCreatedEvent; }

DECLARE_DERIVED_EVENT(UAssetRegistryImpl, IAssetRegistry::FInMemoryAssetDeletedEvent, FInMemoryAssetDeletedEvent);
virtual FInMemoryAssetDeletedEvent& OnInMemoryAssetDeleted() override { return InMemoryAssetDeletedEvent; }

DECLARE_DERIVED_EVENT(UAssetRegistryImpl, IAssetRegistry::FFilesLoadedEvent, FFilesLoadedEvent);
virtual FFilesLoadedEvent& OnFilesLoaded() override { return FileLoadedEvent; }

DECLARE_DERIVED_EVENT(UAssetRegistryImpl, IAssetRegistry::FFileLoadProgressUpdatedEvent, FFileLoadProgressUpdatedEvent);
virtual FFileLoadProgressUpdatedEvent& OnFileLoadProgressUpdated() override { return FileLoadProgressUpdatedEvent; }

监听资源保存的事件

1
2
3
4
5
6
7
8
void PackageSaved(const FString& PacStr,UObject* PackageSaved)
{
UE_LOG(LogTemp,Log,TEXT("Package %s Saved."),*PacStr);
}
void FEmptyProjectModule::StartupModule()
{
UPackage::PackageSavedEvent.AddStatic(&PackageSaved);
}