🚚 move unreal plugin to separate repository
|
|
@ -1,10 +0,0 @@
|
|||
# Building the plugin
|
||||
|
||||
In order to successfully build the plugin, make sure that the path to the UnrealBuildTool.exe is specified correctly.
|
||||
After the UBT path specify for which platform it will be compiled. in the -Project parameter, specify the path to the
|
||||
CommandletProject.uproject file. Next the build type has to be specified (DebugGame, Development, Package, etc.) and then the -TargetType (Editor, Runtime, etc.)
|
||||
|
||||
`BuildPlugin_[Ver].bat` runs the building process in the background. If you want to show the progress inside the
|
||||
command prompt, use the `BuildPlugin_[Ver]_Window.bat` file.
|
||||
|
||||
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
/Binaries
|
||||
/Intermediate
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
{
|
||||
"FileVersion": 3,
|
||||
"Version": 1,
|
||||
"VersionName": "1.0",
|
||||
"FriendlyName": "Ayon",
|
||||
"Description": "Ayon Integration",
|
||||
"Category": "Ayon.Integration",
|
||||
"CreatedBy": "Ondrej Samohel",
|
||||
"CreatedByURL": "https://ayon.ynput.io",
|
||||
"DocsURL": "https://ayon.ynput.io/docs/artist_hosts_unreal",
|
||||
"MarketplaceURL": "",
|
||||
"SupportURL": "https://ynput.io/",
|
||||
"EngineVersion": "4.27",
|
||||
"CanContainContent": true,
|
||||
"Installed": true,
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "Ayon",
|
||||
"Type": "Editor",
|
||||
"LoadingPhase": "Default"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[/Script/Ayon.AyonSettings]
|
||||
FolderColor=(R=91,G=197,B=220,A=255)
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
[FilterPlugin]
|
||||
; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and
|
||||
; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively.
|
||||
;
|
||||
; Examples:
|
||||
; /README.txt
|
||||
; /Extras/...
|
||||
; /Binaries/ThirdParty/*.dll
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
import unreal
|
||||
|
||||
ayon_detected = True
|
||||
try:
|
||||
from openpype.pipeline import install_host
|
||||
from openpype.hosts.unreal.api import UnrealHost
|
||||
|
||||
ayon_host = UnrealHost()
|
||||
except ImportError as exc:
|
||||
ayon_host = None
|
||||
ayon_detected = False
|
||||
unreal.log_error(f"OpenPype: cannot load Ayon [ {exc} ]")
|
||||
|
||||
if ayon_detected:
|
||||
install_host(ayon_host)
|
||||
|
||||
|
||||
@unreal.uclass()
|
||||
class AyonIntegration(unreal.AyonPythonBridge):
|
||||
@unreal.ufunction(override=True)
|
||||
def RunInPython_Popup(self):
|
||||
unreal.log_warning("Ayon: showing tools popup")
|
||||
if ayon_detected:
|
||||
ayon_host.show_tools_popup()
|
||||
|
||||
@unreal.ufunction(override=True)
|
||||
def RunInPython_Dialog(self):
|
||||
unreal.log_warning("Ayon: showing tools dialog")
|
||||
if ayon_detected:
|
||||
ayon_host.show_tools_dialog()
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
# Ayon Unreal Integration plugin - UE 4.x
|
||||
|
||||
This is plugin for Unreal Editor, creating menu for [Ayon](https://github.com/ynput/OpenPype) tools to run.
|
||||
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 721 B |
|
Before Width: | Height: | Size: 16 KiB |
|
|
@ -1,61 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class Ayon : ModuleRules
|
||||
{
|
||||
public Ayon(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[]
|
||||
{
|
||||
// ... add public include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[]
|
||||
{
|
||||
// ... add other private include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
// ... add other public dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"GameProjectGeneration",
|
||||
"Projects",
|
||||
"InputCore",
|
||||
"UnrealEd",
|
||||
"LevelEditor",
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
"AssetTools"
|
||||
// ... add private dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
// ... add any modules that your module loads dynamically here ...
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#include "Ayon.h"
|
||||
|
||||
#include "ISettingsContainer.h"
|
||||
#include "ISettingsModule.h"
|
||||
#include "ISettingsSection.h"
|
||||
#include "LevelEditor.h"
|
||||
#include "AyonPythonBridge.h"
|
||||
#include "AyonSettings.h"
|
||||
#include "AyonStyle.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
|
||||
static const FName AyonTabName("Ayon");
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FAyonModule"
|
||||
|
||||
// This function is triggered when the plugin is staring up
|
||||
void FAyonModule::StartupModule()
|
||||
{
|
||||
if (!IsRunningCommandlet()) {
|
||||
FAyonStyle::Initialize();
|
||||
FAyonStyle::SetIcon("Logo", "ayon40");
|
||||
|
||||
// Create the Extender that will add content to the menu
|
||||
FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
|
||||
|
||||
TSharedPtr<FExtender> MenuExtender = MakeShareable(new FExtender());
|
||||
TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender());
|
||||
|
||||
MenuExtender->AddMenuExtension(
|
||||
"LevelEditor",
|
||||
EExtensionHook::After,
|
||||
NULL,
|
||||
FMenuExtensionDelegate::CreateRaw(this, &FAyonModule::AddMenuEntry)
|
||||
);
|
||||
ToolbarExtender->AddToolBarExtension(
|
||||
"Settings",
|
||||
EExtensionHook::After,
|
||||
NULL,
|
||||
FToolBarExtensionDelegate::CreateRaw(this, &FAyonModule::AddToobarEntry));
|
||||
|
||||
|
||||
LevelEditorModule.GetMenuExtensibilityManager()->AddExtender(MenuExtender);
|
||||
LevelEditorModule.GetToolBarExtensibilityManager()->AddExtender(ToolbarExtender);
|
||||
|
||||
RegisterSettings();
|
||||
}
|
||||
}
|
||||
|
||||
void FAyonModule::ShutdownModule()
|
||||
{
|
||||
FAyonStyle::Shutdown();
|
||||
}
|
||||
|
||||
|
||||
void FAyonModule::AddMenuEntry(FMenuBuilder& MenuBuilder)
|
||||
{
|
||||
// Create Section
|
||||
MenuBuilder.BeginSection("Ayon", TAttribute<FText>(FText::FromString("Ayon")));
|
||||
{
|
||||
// Create a Submenu inside of the Section
|
||||
MenuBuilder.AddMenuEntry(
|
||||
FText::FromString("Tools..."),
|
||||
FText::FromString("Pipeline tools"),
|
||||
FSlateIcon(FAyonStyle::GetStyleSetName(), "Ayon.Logo"),
|
||||
FUIAction(FExecuteAction::CreateRaw(this, &FAyonModule::MenuPopup))
|
||||
);
|
||||
|
||||
MenuBuilder.AddMenuEntry(
|
||||
FText::FromString("Tools dialog..."),
|
||||
FText::FromString("Pipeline tools dialog"),
|
||||
FSlateIcon(FAyonStyle::GetStyleSetName(), "Ayon.Logo"),
|
||||
FUIAction(FExecuteAction::CreateRaw(this, &FAyonModule::MenuDialog))
|
||||
);
|
||||
}
|
||||
MenuBuilder.EndSection();
|
||||
}
|
||||
|
||||
void FAyonModule::AddToobarEntry(FToolBarBuilder& ToolbarBuilder)
|
||||
{
|
||||
ToolbarBuilder.BeginSection(TEXT("Ayon"));
|
||||
{
|
||||
ToolbarBuilder.AddToolBarButton(
|
||||
FUIAction(
|
||||
FExecuteAction::CreateRaw(this, &FAyonModule::MenuPopup),
|
||||
NULL,
|
||||
FIsActionChecked()
|
||||
|
||||
),
|
||||
NAME_None,
|
||||
LOCTEXT("Ayon_label", "Ayon"),
|
||||
LOCTEXT("Ayon_tooltip", "Ayon Tools"),
|
||||
FSlateIcon(FAyonStyle::GetStyleSetName(), "Ayon.Logo")
|
||||
);
|
||||
}
|
||||
ToolbarBuilder.EndSection();
|
||||
}
|
||||
|
||||
void FAyonModule::RegisterSettings()
|
||||
{
|
||||
ISettingsModule& SettingsModule = FModuleManager::LoadModuleChecked<ISettingsModule>("Settings");
|
||||
|
||||
// Create the new category
|
||||
// TODO: After the movement of the plugin from the game to editor, it might be necessary to move this!
|
||||
ISettingsContainerPtr SettingsContainer = SettingsModule.GetContainer("Project");
|
||||
|
||||
UAyonSettings* Settings = GetMutableDefault<UAyonSettings>();
|
||||
|
||||
// Register the settings
|
||||
ISettingsSectionPtr SettingsSection = SettingsModule.RegisterSettings("Project", "Ayon", "General",
|
||||
LOCTEXT("RuntimeGeneralSettingsName",
|
||||
"General"),
|
||||
LOCTEXT("RuntimeGeneralSettingsDescription",
|
||||
"Base configuration for Open Pype Module"),
|
||||
Settings
|
||||
);
|
||||
|
||||
// Register the save handler to your settings, you might want to use it to
|
||||
// validate those or just act to settings changes.
|
||||
if (SettingsSection.IsValid())
|
||||
{
|
||||
SettingsSection->OnModified().BindRaw(this, &FAyonModule::HandleSettingsSaved);
|
||||
}
|
||||
}
|
||||
|
||||
bool FAyonModule::HandleSettingsSaved()
|
||||
{
|
||||
UAyonSettings* Settings = GetMutableDefault<UAyonSettings>();
|
||||
bool ResaveSettings = false;
|
||||
|
||||
// You can put any validation code in here and resave the settings in case an invalid
|
||||
// value has been entered
|
||||
|
||||
if (ResaveSettings)
|
||||
{
|
||||
Settings->SaveConfig();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void FAyonModule::MenuPopup()
|
||||
{
|
||||
UAyonPythonBridge* bridge = UAyonPythonBridge::Get();
|
||||
bridge->RunInPython_Popup();
|
||||
}
|
||||
|
||||
void FAyonModule::MenuDialog()
|
||||
{
|
||||
UAyonPythonBridge* bridge = UAyonPythonBridge::Get();
|
||||
bridge->RunInPython_Dialog();
|
||||
}
|
||||
|
||||
IMPLEMENT_MODULE(FAyonModule, Ayon)
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#include "AyonAssetContainer.h"
|
||||
#include "AssetRegistryModule.h"
|
||||
#include "Misc/PackageName.h"
|
||||
#include "Containers/UnrealString.h"
|
||||
|
||||
UAyonAssetContainer::UAyonAssetContainer(const FObjectInitializer& ObjectInitializer)
|
||||
: UAssetUserData(ObjectInitializer)
|
||||
{
|
||||
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
|
||||
FString path = UAyonAssetContainer::GetPathName();
|
||||
UE_LOG(LogTemp, Warning, TEXT("UAyonAssetContainer %s"), *path);
|
||||
FARFilter Filter;
|
||||
Filter.PackagePaths.Add(FName(*path));
|
||||
|
||||
AssetRegistryModule.Get().OnAssetAdded().AddUObject(this, &UAyonAssetContainer::OnAssetAdded);
|
||||
AssetRegistryModule.Get().OnAssetRemoved().AddUObject(this, &UAyonAssetContainer::OnAssetRemoved);
|
||||
AssetRegistryModule.Get().OnAssetRenamed().AddUObject(this, &UAyonAssetContainer::OnAssetRenamed);
|
||||
}
|
||||
|
||||
void UAyonAssetContainer::OnAssetAdded(const FAssetData& AssetData)
|
||||
{
|
||||
TArray<FString> split;
|
||||
|
||||
// get directory of current container
|
||||
FString selfFullPath = UAyonAssetContainer::GetPathName();
|
||||
FString selfDir = FPackageName::GetLongPackagePath(*selfFullPath);
|
||||
|
||||
// get asset path and class
|
||||
FString assetPath = AssetData.GetFullName();
|
||||
FString assetFName = AssetData.AssetClass.ToString();
|
||||
|
||||
// split path
|
||||
assetPath.ParseIntoArray(split, TEXT(" "), true);
|
||||
|
||||
FString assetDir = FPackageName::GetLongPackagePath(*split[1]);
|
||||
|
||||
// take interest only in paths starting with path of current container
|
||||
if (assetDir.StartsWith(*selfDir))
|
||||
{
|
||||
// exclude self
|
||||
if (assetFName != "AyonAssetContainer")
|
||||
{
|
||||
assets.Add(assetPath);
|
||||
assetsData.Add(AssetData);
|
||||
UE_LOG(LogTemp, Log, TEXT("%s: asset added to %s"), *selfFullPath, *selfDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UAyonAssetContainer::OnAssetRemoved(const FAssetData& AssetData)
|
||||
{
|
||||
TArray<FString> split;
|
||||
|
||||
// get directory of current container
|
||||
FString selfFullPath = UAyonAssetContainer::GetPathName();
|
||||
FString selfDir = FPackageName::GetLongPackagePath(*selfFullPath);
|
||||
|
||||
// get asset path and class
|
||||
FString assetPath = AssetData.GetFullName();
|
||||
FString assetFName = AssetData.AssetClass.ToString();
|
||||
|
||||
// split path
|
||||
assetPath.ParseIntoArray(split, TEXT(" "), true);
|
||||
|
||||
FString assetDir = FPackageName::GetLongPackagePath(*split[1]);
|
||||
|
||||
// take interest only in paths starting with path of current container
|
||||
FString path = UAyonAssetContainer::GetPathName();
|
||||
FString lpp = FPackageName::GetLongPackagePath(*path);
|
||||
|
||||
if (assetDir.StartsWith(*selfDir))
|
||||
{
|
||||
// exclude self
|
||||
if (assetFName != "AyonAssetContainer")
|
||||
{
|
||||
// UE_LOG(LogTemp, Warning, TEXT("%s: asset removed"), *lpp);
|
||||
assets.Remove(assetPath);
|
||||
assetsData.Remove(AssetData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UAyonAssetContainer::OnAssetRenamed(const FAssetData& AssetData, const FString& str)
|
||||
{
|
||||
TArray<FString> split;
|
||||
|
||||
// get directory of current container
|
||||
FString selfFullPath = UAyonAssetContainer::GetPathName();
|
||||
FString selfDir = FPackageName::GetLongPackagePath(*selfFullPath);
|
||||
|
||||
// get asset path and class
|
||||
FString assetPath = AssetData.GetFullName();
|
||||
FString assetFName = AssetData.AssetClass.ToString();
|
||||
|
||||
// split path
|
||||
assetPath.ParseIntoArray(split, TEXT(" "), true);
|
||||
|
||||
FString assetDir = FPackageName::GetLongPackagePath(*split[1]);
|
||||
if (assetDir.StartsWith(*selfDir))
|
||||
{
|
||||
// exclude self
|
||||
if (assetFName != "AyonAssetContainer")
|
||||
{
|
||||
|
||||
assets.Remove(str);
|
||||
assets.Add(assetPath);
|
||||
assetsData.Remove(AssetData);
|
||||
// UE_LOG(LogTemp, Warning, TEXT("%s: asset renamed %s"), *lpp, *str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
#include "AyonAssetContainerFactory.h"
|
||||
#include "AyonAssetContainer.h"
|
||||
|
||||
UAyonAssetContainerFactory::UAyonAssetContainerFactory(const FObjectInitializer& ObjectInitializer)
|
||||
: UFactory(ObjectInitializer)
|
||||
{
|
||||
SupportedClass = UAyonAssetContainer::StaticClass();
|
||||
bCreateNew = false;
|
||||
bEditorImport = true;
|
||||
}
|
||||
|
||||
UObject* UAyonAssetContainerFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn)
|
||||
{
|
||||
UAyonAssetContainer* AssetContainer = NewObject<UAyonAssetContainer>(InParent, Class, Name, Flags);
|
||||
return AssetContainer;
|
||||
}
|
||||
|
||||
bool UAyonAssetContainerFactory::ShouldShowInNewMenu() const {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#include "AyonLib.h"
|
||||
|
||||
#include "AssetViewUtils.h"
|
||||
#include "Misc/Paths.h"
|
||||
#include "Misc/ConfigCacheIni.h"
|
||||
#include "UObject/UnrealType.h"
|
||||
|
||||
/**
|
||||
* Sets color on folder icon on given path
|
||||
* @param InPath - path to folder
|
||||
* @param InFolderColor - color of the folder
|
||||
* @warning This color will appear only after Editor restart. Is there a better way?
|
||||
*/
|
||||
|
||||
bool UAyonLib::SetFolderColor(const FString& FolderPath, const FLinearColor& FolderColor, const bool& bForceAdd)
|
||||
{
|
||||
if (AssetViewUtils::DoesFolderExist(FolderPath))
|
||||
{
|
||||
const TSharedPtr<FLinearColor> LinearColor = MakeShared<FLinearColor>(FolderColor);
|
||||
|
||||
AssetViewUtils::SaveColor(FolderPath, LinearColor, true);
|
||||
UE_LOG(LogAssetData, Display, TEXT("A color {%s} has been set to folder \"%s\""), *LinearColor->ToString(),
|
||||
*FolderPath)
|
||||
return true;
|
||||
}
|
||||
|
||||
UE_LOG(LogAssetData, Display, TEXT("Setting a color {%s} to folder \"%s\" has failed! Directory doesn't exist!"),
|
||||
*FolderColor.ToString(), *FolderPath)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all poperties on given object
|
||||
* @param cls - class
|
||||
* @return TArray of properties
|
||||
*/
|
||||
TArray<FString> UAyonLib::GetAllProperties(UClass* cls)
|
||||
{
|
||||
TArray<FString> Ret;
|
||||
if (cls != nullptr)
|
||||
{
|
||||
for (TFieldIterator<FProperty> It(cls); It; ++It)
|
||||
{
|
||||
FProperty* Property = *It;
|
||||
if (Property->HasAnyPropertyFlags(EPropertyFlags::CPF_Edit))
|
||||
{
|
||||
Ret.Add(Property->GetName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
|
@ -1,203 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
// Deprecation warning: this is left here just for backwards compatibility
|
||||
// and will be removed in next versions of Ayon.
|
||||
#pragma once
|
||||
|
||||
#include "AyonPublishInstance.h"
|
||||
#include "AssetRegistryModule.h"
|
||||
#include "AyonLib.h"
|
||||
#include "AyonSettings.h"
|
||||
#include "Framework/Notifications/NotificationManager.h"
|
||||
#include "Widgets/Notifications/SNotificationList.h"
|
||||
|
||||
//Moves all the invalid pointers to the end to prepare them for the shrinking
|
||||
#define REMOVE_INVALID_ENTRIES(VAR) VAR.CompactStable(); \
|
||||
VAR.Shrink();
|
||||
|
||||
UAyonPublishInstance::UAyonPublishInstance(const FObjectInitializer& ObjectInitializer)
|
||||
: UPrimaryDataAsset(ObjectInitializer)
|
||||
{
|
||||
const FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<
|
||||
FAssetRegistryModule>("AssetRegistry");
|
||||
|
||||
const FPropertyEditorModule& PropertyEditorModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>(
|
||||
"PropertyEditor");
|
||||
|
||||
FString Left, Right;
|
||||
GetPathName().Split("/" + GetName(), &Left, &Right);
|
||||
|
||||
FARFilter Filter;
|
||||
Filter.PackagePaths.Emplace(FName(Left));
|
||||
|
||||
TArray<FAssetData> FoundAssets;
|
||||
AssetRegistryModule.GetRegistry().GetAssets(Filter, FoundAssets);
|
||||
|
||||
for (const FAssetData& AssetData : FoundAssets)
|
||||
OnAssetCreated(AssetData);
|
||||
|
||||
REMOVE_INVALID_ENTRIES(AssetDataInternal)
|
||||
REMOVE_INVALID_ENTRIES(AssetDataExternal)
|
||||
|
||||
AssetRegistryModule.Get().OnAssetAdded().AddUObject(this, &UAyonPublishInstance::OnAssetCreated);
|
||||
AssetRegistryModule.Get().OnAssetRemoved().AddUObject(this, &UAyonPublishInstance::OnAssetRemoved);
|
||||
AssetRegistryModule.Get().OnAssetUpdated().AddUObject(this, &UAyonPublishInstance::OnAssetUpdated);
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
ColorAyonDirs();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void UAyonPublishInstance::OnAssetCreated(const FAssetData& InAssetData)
|
||||
{
|
||||
TArray<FString> split;
|
||||
|
||||
UObject* Asset = InAssetData.GetAsset();
|
||||
|
||||
if (!IsValid(Asset))
|
||||
{
|
||||
UE_LOG(LogAssetData, Warning, TEXT("Asset \"%s\" is not valid! Skipping the addition."),
|
||||
*InAssetData.ObjectPath.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
const bool result = IsUnderSameDir(Asset) && Cast<UAyonPublishInstance>(Asset) == nullptr;
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (AssetDataInternal.Emplace(Asset).IsValidId())
|
||||
{
|
||||
UE_LOG(LogTemp, Log, TEXT("Added an Asset to PublishInstance - Publish Instance: %s, Asset %s"),
|
||||
*this->GetName(), *Asset->GetName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UAyonPublishInstance::OnAssetRemoved(const FAssetData& InAssetData)
|
||||
{
|
||||
if (Cast<UAyonPublishInstance>(InAssetData.GetAsset()) == nullptr)
|
||||
{
|
||||
if (AssetDataInternal.Contains(nullptr))
|
||||
{
|
||||
AssetDataInternal.Remove(nullptr);
|
||||
REMOVE_INVALID_ENTRIES(AssetDataInternal)
|
||||
}
|
||||
else
|
||||
{
|
||||
AssetDataExternal.Remove(nullptr);
|
||||
REMOVE_INVALID_ENTRIES(AssetDataExternal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UAyonPublishInstance::OnAssetUpdated(const FAssetData& InAssetData)
|
||||
{
|
||||
REMOVE_INVALID_ENTRIES(AssetDataInternal);
|
||||
REMOVE_INVALID_ENTRIES(AssetDataExternal);
|
||||
}
|
||||
|
||||
bool UAyonPublishInstance::IsUnderSameDir(const UObject* InAsset) const
|
||||
{
|
||||
FString ThisLeft, ThisRight;
|
||||
this->GetPathName().Split(this->GetName(), &ThisLeft, &ThisRight);
|
||||
|
||||
return InAsset->GetPathName().StartsWith(ThisLeft);
|
||||
}
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
|
||||
void UAyonPublishInstance::ColorAyonDirs()
|
||||
{
|
||||
FString PathName = this->GetPathName();
|
||||
|
||||
//Check whether the path contains the defined Ayon folder
|
||||
if (!PathName.Contains(TEXT("Ayon"))) return;
|
||||
|
||||
//Get the base path for open pype
|
||||
FString PathLeft, PathRight;
|
||||
PathName.Split(FString("Ayon"), &PathLeft, &PathRight);
|
||||
|
||||
if (PathLeft.IsEmpty() || PathRight.IsEmpty())
|
||||
{
|
||||
UE_LOG(LogAssetData, Error, TEXT("Failed to retrieve the base Ayon directory!"))
|
||||
return;
|
||||
}
|
||||
|
||||
PathName.RemoveFromEnd(PathRight, ESearchCase::CaseSensitive);
|
||||
|
||||
//Get the current settings
|
||||
const UAyonSettings* Settings = GetMutableDefault<UAyonSettings>();
|
||||
|
||||
//Color the base folder
|
||||
UAyonLib::SetFolderColor(PathName, Settings->GetFolderFColor(), false);
|
||||
|
||||
//Get Sub paths, iterate through them and color them according to the folder color in UAyonSettings
|
||||
const FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(
|
||||
"AssetRegistry");
|
||||
|
||||
TArray<FString> PathList;
|
||||
|
||||
AssetRegistryModule.Get().GetSubPaths(PathName, PathList, true);
|
||||
|
||||
if (PathList.Num() > 0)
|
||||
{
|
||||
for (const FString& Path : PathList)
|
||||
{
|
||||
UAyonLib::SetFolderColor(Path, Settings->GetFolderFColor(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UAyonPublishInstance::SendNotification(const FString& Text) const
|
||||
{
|
||||
FNotificationInfo Info{FText::FromString(Text)};
|
||||
|
||||
Info.bFireAndForget = true;
|
||||
Info.bUseLargeFont = false;
|
||||
Info.bUseThrobber = false;
|
||||
Info.bUseSuccessFailIcons = false;
|
||||
Info.ExpireDuration = 4.f;
|
||||
Info.FadeOutDuration = 2.f;
|
||||
|
||||
FSlateNotificationManager::Get().AddNotification(Info);
|
||||
|
||||
UE_LOG(LogAssetData, Warning,
|
||||
TEXT(
|
||||
"Removed duplicated asset from the AssetsDataExternal in Container \"%s\", Asset is already included in the AssetDataInternal!"
|
||||
), *GetName()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
void UAyonPublishInstance::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
||||
{
|
||||
Super::PostEditChangeProperty(PropertyChangedEvent);
|
||||
|
||||
if (PropertyChangedEvent.ChangeType == EPropertyChangeType::ValueSet &&
|
||||
PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(
|
||||
UAyonPublishInstance, AssetDataExternal))
|
||||
{
|
||||
// Check for duplicated assets
|
||||
for (const auto& Asset : AssetDataInternal)
|
||||
{
|
||||
if (AssetDataExternal.Contains(Asset))
|
||||
{
|
||||
AssetDataExternal.Remove(Asset);
|
||||
return SendNotification(
|
||||
"You are not allowed to add assets into AssetDataExternal which are already included in AssetDataInternal!");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if no UAyonPublishInstance type assets are included
|
||||
for (const auto& Asset : AssetDataExternal)
|
||||
{
|
||||
if (Cast<UAyonPublishInstance>(Asset.Get()) != nullptr)
|
||||
{
|
||||
AssetDataExternal.Remove(Asset);
|
||||
return SendNotification("You are not allowed to add publish instances!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
// Deprecation warning: this is left here just for backwards compatibility
|
||||
// and will be removed in next versions of Ayon.
|
||||
#include "AyonPublishInstanceFactory.h"
|
||||
#include "AyonPublishInstance.h"
|
||||
|
||||
UAyonPublishInstanceFactory::UAyonPublishInstanceFactory(const FObjectInitializer& ObjectInitializer)
|
||||
: UFactory(ObjectInitializer)
|
||||
{
|
||||
SupportedClass = UAyonPublishInstance::StaticClass();
|
||||
bCreateNew = false;
|
||||
bEditorImport = true;
|
||||
}
|
||||
|
||||
UObject* UAyonPublishInstanceFactory::FactoryCreateNew(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn)
|
||||
{
|
||||
check(InClass->IsChildOf(UAyonPublishInstance::StaticClass()));
|
||||
return NewObject<UAyonPublishInstance>(InParent, InClass, InName, Flags);
|
||||
}
|
||||
|
||||
bool UAyonPublishInstanceFactory::ShouldShowInNewMenu() const {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#include "AyonPythonBridge.h"
|
||||
|
||||
UAyonPythonBridge* UAyonPythonBridge::Get()
|
||||
{
|
||||
TArray<UClass*> AyonPythonBridgeClasses;
|
||||
GetDerivedClasses(UAyonPythonBridge::StaticClass(), AyonPythonBridgeClasses);
|
||||
int32 NumClasses = AyonPythonBridgeClasses.Num();
|
||||
if (NumClasses > 0)
|
||||
{
|
||||
return Cast<UAyonPythonBridge>(AyonPythonBridgeClasses[NumClasses - 1]->GetDefaultObject());
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
#include "AyonSettings.h"
|
||||
|
||||
#include "Interfaces/IPluginManager.h"
|
||||
|
||||
/**
|
||||
* Mainly is used for initializing default values if the DefaultAyonSettings.ini file does not exist in the saved config
|
||||
*/
|
||||
UAyonSettings::UAyonSettings(const FObjectInitializer& ObjectInitializer)
|
||||
{
|
||||
|
||||
const FString ConfigFilePath = AYON_SETTINGS_FILEPATH;
|
||||
|
||||
// This has to be probably in the future set using the UE Reflection system
|
||||
FColor Color;
|
||||
GConfig->GetColor(TEXT("/Script/Ayon.AyonSettings"), TEXT("FolderColor"), Color, ConfigFilePath);
|
||||
|
||||
FolderColor = Color;
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#include "AyonStyle.h"
|
||||
#include "Framework/Application/SlateApplication.h"
|
||||
#include "Styling/SlateStyle.h"
|
||||
#include "Styling/SlateStyleRegistry.h"
|
||||
|
||||
|
||||
TUniquePtr< FSlateStyleSet > FAyonStyle::AyonStyleInstance = nullptr;
|
||||
|
||||
void FAyonStyle::Initialize()
|
||||
{
|
||||
if (!AyonStyleInstance.IsValid())
|
||||
{
|
||||
AyonStyleInstance = Create();
|
||||
FSlateStyleRegistry::RegisterSlateStyle(*AyonStyleInstance);
|
||||
}
|
||||
}
|
||||
|
||||
void FAyonStyle::Shutdown()
|
||||
{
|
||||
if (AyonStyleInstance.IsValid())
|
||||
{
|
||||
FSlateStyleRegistry::UnRegisterSlateStyle(*AyonStyleInstance);
|
||||
AyonStyleInstance.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
FName FAyonStyle::GetStyleSetName()
|
||||
{
|
||||
static FName StyleSetName(TEXT("AyonStyle"));
|
||||
return StyleSetName;
|
||||
}
|
||||
|
||||
FName FAyonStyle::GetContextName()
|
||||
{
|
||||
static FName ContextName(TEXT("Ayon"));
|
||||
return ContextName;
|
||||
}
|
||||
|
||||
#define IMAGE_BRUSH(RelativePath, ...) FSlateImageBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ )
|
||||
|
||||
const FVector2D Icon40x40(40.0f, 40.0f);
|
||||
|
||||
TUniquePtr< FSlateStyleSet > FAyonStyle::Create()
|
||||
{
|
||||
TUniquePtr< FSlateStyleSet > Style = MakeUnique<FSlateStyleSet>(GetStyleSetName());
|
||||
Style->SetContentRoot(FPaths::EnginePluginsDir() / TEXT("Marketplace/Ayon/Resources"));
|
||||
|
||||
return Style;
|
||||
}
|
||||
|
||||
void FAyonStyle::SetIcon(const FString& StyleName, const FString& ResourcePath)
|
||||
{
|
||||
FSlateStyleSet* Style = AyonStyleInstance.Get();
|
||||
|
||||
FString Name(GetContextName().ToString());
|
||||
Name = Name + "." + StyleName;
|
||||
Style->Set(*Name, new FSlateImageBrush(Style->RootToContentDir(ResourcePath, TEXT(".png")), Icon40x40));
|
||||
|
||||
|
||||
FSlateApplication::Get().GetRenderer()->ReloadTextureResources();
|
||||
}
|
||||
|
||||
#undef IMAGE_BRUSH
|
||||
|
||||
const ISlateStyle& FAyonStyle::Get()
|
||||
{
|
||||
check(AyonStyleInstance);
|
||||
return *AyonStyleInstance;
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
|
||||
#include "Commandlets/AyonActionResult.h"
|
||||
#include "Logging/Ayon_Log.h"
|
||||
|
||||
EAyon_ActionResult::Type& FAyon_ActionResult::GetStatus()
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
FText& FAyon_ActionResult::GetReason()
|
||||
{
|
||||
return Reason;
|
||||
}
|
||||
|
||||
FAyon_ActionResult::FAyon_ActionResult():Status(EAyon_ActionResult::Type::Ok)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FAyon_ActionResult::FAyon_ActionResult(const EAyon_ActionResult::Type& InEnum):Status(InEnum)
|
||||
{
|
||||
TryLog();
|
||||
}
|
||||
|
||||
FAyon_ActionResult::FAyon_ActionResult(const EAyon_ActionResult::Type& InEnum, const FText& InReason):Status(InEnum), Reason(InReason)
|
||||
{
|
||||
TryLog();
|
||||
};
|
||||
|
||||
bool FAyon_ActionResult::IsProblem() const
|
||||
{
|
||||
return Status != EAyon_ActionResult::Ok;
|
||||
}
|
||||
|
||||
void FAyon_ActionResult::TryLog() const
|
||||
{
|
||||
if(IsProblem())
|
||||
UE_LOG(LogCommandletOPGenerateProject, Error, TEXT("%s"), *Reason.ToString());
|
||||
}
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#include "Commandlets/Implementations/AyonGenerateProjectCommandlet.h"
|
||||
|
||||
#include "Editor.h"
|
||||
#include "GameProjectUtils.h"
|
||||
#include "AyonConstants.h"
|
||||
#include "Commandlets/AyonActionResult.h"
|
||||
#include "ProjectDescriptor.h"
|
||||
|
||||
int32 UAyonGenerateProjectCommandlet::Main(const FString& CommandLineParams)
|
||||
{
|
||||
//Parses command line parameters & creates structure FProjectInformation
|
||||
const FAyonGenerateProjectParams ParsedParams = FAyonGenerateProjectParams(CommandLineParams);
|
||||
ProjectInformation = ParsedParams.GenerateUEProjectInformation();
|
||||
|
||||
//Creates .uproject & other UE files
|
||||
EVALUATE_AYON_ACTION_RESULT(TryCreateProject());
|
||||
|
||||
//Loads created .uproject
|
||||
EVALUATE_AYON_ACTION_RESULT(TryLoadProjectDescriptor());
|
||||
|
||||
//Adds needed plugin to .uproject
|
||||
AttachPluginsToProjectDescriptor();
|
||||
|
||||
//Saves .uproject
|
||||
EVALUATE_AYON_ACTION_RESULT(TrySave());
|
||||
|
||||
//When we are here, there should not be problems in generating Unreal Project for Ayon
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FAyonGenerateProjectParams::FAyonGenerateProjectParams(): FAyonGenerateProjectParams("")
|
||||
{
|
||||
}
|
||||
|
||||
FAyonGenerateProjectParams::FAyonGenerateProjectParams(const FString& CommandLineParams): CommandLineParams(
|
||||
CommandLineParams)
|
||||
{
|
||||
UCommandlet::ParseCommandLine(*CommandLineParams, Tokens, Switches);
|
||||
}
|
||||
|
||||
FProjectInformation FAyonGenerateProjectParams::GenerateUEProjectInformation() const
|
||||
{
|
||||
FProjectInformation ProjectInformation = FProjectInformation();
|
||||
ProjectInformation.ProjectFilename = GetProjectFileName();
|
||||
|
||||
ProjectInformation.bShouldGenerateCode = IsSwitchPresent("GenerateCode");
|
||||
|
||||
return ProjectInformation;
|
||||
}
|
||||
|
||||
FString FAyonGenerateProjectParams::TryGetToken(const int32 Index) const
|
||||
{
|
||||
return Tokens.IsValidIndex(Index) ? Tokens[Index] : "";
|
||||
}
|
||||
|
||||
FString FAyonGenerateProjectParams::GetProjectFileName() const
|
||||
{
|
||||
return TryGetToken(0);
|
||||
}
|
||||
|
||||
bool FAyonGenerateProjectParams::IsSwitchPresent(const FString& Switch) const
|
||||
{
|
||||
return INDEX_NONE != Switches.IndexOfByPredicate([&Switch](const FString& Item) -> bool
|
||||
{
|
||||
return Item.Equals(Switch);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
UAyonGenerateProjectCommandlet::UAyonGenerateProjectCommandlet()
|
||||
{
|
||||
LogToConsole = true;
|
||||
}
|
||||
|
||||
FAyon_ActionResult UAyonGenerateProjectCommandlet::TryCreateProject() const
|
||||
{
|
||||
FText FailReason;
|
||||
FText FailLog;
|
||||
TArray<FString> OutCreatedFiles;
|
||||
|
||||
if (!GameProjectUtils::CreateProject(ProjectInformation, FailReason, FailLog, &OutCreatedFiles))
|
||||
return FAyon_ActionResult(EAyon_ActionResult::ProjectNotCreated, FailReason);
|
||||
return FAyon_ActionResult();
|
||||
}
|
||||
|
||||
FAyon_ActionResult UAyonGenerateProjectCommandlet::TryLoadProjectDescriptor()
|
||||
{
|
||||
FText FailReason;
|
||||
const bool bLoaded = ProjectDescriptor.Load(ProjectInformation.ProjectFilename, FailReason);
|
||||
|
||||
return FAyon_ActionResult(bLoaded ? EAyon_ActionResult::Ok : EAyon_ActionResult::ProjectNotLoaded, FailReason);
|
||||
}
|
||||
|
||||
void UAyonGenerateProjectCommandlet::AttachPluginsToProjectDescriptor()
|
||||
{
|
||||
FPluginReferenceDescriptor AyonPluginDescriptor;
|
||||
AyonPluginDescriptor.bEnabled = true;
|
||||
AyonPluginDescriptor.Name = AyonConstants::Ayon_PluginName;
|
||||
ProjectDescriptor.Plugins.Add(AyonPluginDescriptor);
|
||||
|
||||
FPluginReferenceDescriptor PythonPluginDescriptor;
|
||||
PythonPluginDescriptor.bEnabled = true;
|
||||
PythonPluginDescriptor.Name = AyonConstants::PythonScript_PluginName;
|
||||
ProjectDescriptor.Plugins.Add(PythonPluginDescriptor);
|
||||
|
||||
FPluginReferenceDescriptor SequencerScriptingPluginDescriptor;
|
||||
SequencerScriptingPluginDescriptor.bEnabled = true;
|
||||
SequencerScriptingPluginDescriptor.Name = AyonConstants::SequencerScripting_PluginName;
|
||||
ProjectDescriptor.Plugins.Add(SequencerScriptingPluginDescriptor);
|
||||
|
||||
FPluginReferenceDescriptor MovieRenderPipelinePluginDescriptor;
|
||||
MovieRenderPipelinePluginDescriptor.bEnabled = true;
|
||||
MovieRenderPipelinePluginDescriptor.Name = AyonConstants::MovieRenderPipeline_PluginName;
|
||||
ProjectDescriptor.Plugins.Add(MovieRenderPipelinePluginDescriptor);
|
||||
|
||||
FPluginReferenceDescriptor EditorScriptingPluginDescriptor;
|
||||
EditorScriptingPluginDescriptor.bEnabled = true;
|
||||
EditorScriptingPluginDescriptor.Name = AyonConstants::EditorScriptingUtils_PluginName;
|
||||
ProjectDescriptor.Plugins.Add(EditorScriptingPluginDescriptor);
|
||||
}
|
||||
|
||||
FAyon_ActionResult UAyonGenerateProjectCommandlet::TrySave()
|
||||
{
|
||||
FText FailReason;
|
||||
const bool bSaved = ProjectDescriptor.Save(ProjectInformation.ProjectFilename, FailReason);
|
||||
|
||||
return FAyon_ActionResult(bSaved ? EAyon_ActionResult::Ok : EAyon_ActionResult::ProjectNotSaved, FailReason);
|
||||
}
|
||||
|
||||
FAyonGenerateProjectParams UAyonGenerateProjectCommandlet::ParseParameters(const FString& Params) const
|
||||
{
|
||||
FAyonGenerateProjectParams ParamsResult;
|
||||
|
||||
TArray<FString> Tokens, Switches;
|
||||
ParseCommandLine(*Params, Tokens, Switches);
|
||||
|
||||
return ParamsResult;
|
||||
}
|
||||
|
|
@ -1,203 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
// Deprecation warning: this is left here just for backwards compatibility
|
||||
// and will be removed in next versions of Ayon.
|
||||
#pragma once
|
||||
|
||||
#include "OpenPypePublishInstance.h"
|
||||
#include "AssetRegistryModule.h"
|
||||
#include "AyonLib.h"
|
||||
#include "AyonSettings.h"
|
||||
#include "Framework/Notifications/NotificationManager.h"
|
||||
#include "Widgets/Notifications/SNotificationList.h"
|
||||
|
||||
//Moves all the invalid pointers to the end to prepare them for the shrinking
|
||||
#define REMOVE_INVALID_ENTRIES(VAR) VAR.CompactStable(); \
|
||||
VAR.Shrink();
|
||||
|
||||
UOpenPypePublishInstance::UOpenPypePublishInstance(const FObjectInitializer& ObjectInitializer)
|
||||
: UPrimaryDataAsset(ObjectInitializer)
|
||||
{
|
||||
const FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<
|
||||
FAssetRegistryModule>("AssetRegistry");
|
||||
|
||||
const FPropertyEditorModule& PropertyEditorModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>(
|
||||
"PropertyEditor");
|
||||
|
||||
FString Left, Right;
|
||||
GetPathName().Split("/" + GetName(), &Left, &Right);
|
||||
|
||||
FARFilter Filter;
|
||||
Filter.PackagePaths.Emplace(FName(Left));
|
||||
|
||||
TArray<FAssetData> FoundAssets;
|
||||
AssetRegistryModule.GetRegistry().GetAssets(Filter, FoundAssets);
|
||||
|
||||
for (const FAssetData& AssetData : FoundAssets)
|
||||
OnAssetCreated(AssetData);
|
||||
|
||||
REMOVE_INVALID_ENTRIES(AssetDataInternal)
|
||||
REMOVE_INVALID_ENTRIES(AssetDataExternal)
|
||||
|
||||
AssetRegistryModule.Get().OnAssetAdded().AddUObject(this, &UOpenPypePublishInstance::OnAssetCreated);
|
||||
AssetRegistryModule.Get().OnAssetRemoved().AddUObject(this, &UOpenPypePublishInstance::OnAssetRemoved);
|
||||
AssetRegistryModule.Get().OnAssetUpdated().AddUObject(this, &UOpenPypePublishInstance::OnAssetUpdated);
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
ColorOpenPypeDirs();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void UOpenPypePublishInstance::OnAssetCreated(const FAssetData& InAssetData)
|
||||
{
|
||||
TArray<FString> split;
|
||||
|
||||
UObject* Asset = InAssetData.GetAsset();
|
||||
|
||||
if (!IsValid(Asset))
|
||||
{
|
||||
UE_LOG(LogAssetData, Warning, TEXT("Asset \"%s\" is not valid! Skipping the addition."),
|
||||
*InAssetData.ObjectPath.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
const bool result = IsUnderSameDir(Asset) && Cast<UOpenPypePublishInstance>(Asset) == nullptr;
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (AssetDataInternal.Emplace(Asset).IsValidId())
|
||||
{
|
||||
UE_LOG(LogTemp, Log, TEXT("Added an Asset to PublishInstance - Publish Instance: %s, Asset %s"),
|
||||
*this->GetName(), *Asset->GetName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UOpenPypePublishInstance::OnAssetRemoved(const FAssetData& InAssetData)
|
||||
{
|
||||
if (Cast<UOpenPypePublishInstance>(InAssetData.GetAsset()) == nullptr)
|
||||
{
|
||||
if (AssetDataInternal.Contains(nullptr))
|
||||
{
|
||||
AssetDataInternal.Remove(nullptr);
|
||||
REMOVE_INVALID_ENTRIES(AssetDataInternal)
|
||||
}
|
||||
else
|
||||
{
|
||||
AssetDataExternal.Remove(nullptr);
|
||||
REMOVE_INVALID_ENTRIES(AssetDataExternal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UOpenPypePublishInstance::OnAssetUpdated(const FAssetData& InAssetData)
|
||||
{
|
||||
REMOVE_INVALID_ENTRIES(AssetDataInternal);
|
||||
REMOVE_INVALID_ENTRIES(AssetDataExternal);
|
||||
}
|
||||
|
||||
bool UOpenPypePublishInstance::IsUnderSameDir(const UObject* InAsset) const
|
||||
{
|
||||
FString ThisLeft, ThisRight;
|
||||
this->GetPathName().Split(this->GetName(), &ThisLeft, &ThisRight);
|
||||
|
||||
return InAsset->GetPathName().StartsWith(ThisLeft);
|
||||
}
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
|
||||
void UOpenPypePublishInstance::ColorOpenPypeDirs()
|
||||
{
|
||||
FString PathName = this->GetPathName();
|
||||
|
||||
//Check whether the path contains the defined OpenPype folder
|
||||
if (!PathName.Contains(TEXT("OpenPype"))) return;
|
||||
|
||||
//Get the base path for open pype
|
||||
FString PathLeft, PathRight;
|
||||
PathName.Split(FString("OpenPype"), &PathLeft, &PathRight);
|
||||
|
||||
if (PathLeft.IsEmpty() || PathRight.IsEmpty())
|
||||
{
|
||||
UE_LOG(LogAssetData, Error, TEXT("Failed to retrieve the base OpenPype directory!"))
|
||||
return;
|
||||
}
|
||||
|
||||
PathName.RemoveFromEnd(PathRight, ESearchCase::CaseSensitive);
|
||||
|
||||
//Get the current settings
|
||||
const UAyonSettings* Settings = GetMutableDefault<UAyonSettings>();
|
||||
|
||||
//Color the base folder
|
||||
UAyonLib::SetFolderColor(PathName, Settings->GetFolderFColor(), false);
|
||||
|
||||
//Get Sub paths, iterate through them and color them according to the folder color in UAyonSettings
|
||||
const FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(
|
||||
"AssetRegistry");
|
||||
|
||||
TArray<FString> PathList;
|
||||
|
||||
AssetRegistryModule.Get().GetSubPaths(PathName, PathList, true);
|
||||
|
||||
if (PathList.Num() > 0)
|
||||
{
|
||||
for (const FString& Path : PathList)
|
||||
{
|
||||
UAyonLib::SetFolderColor(Path, Settings->GetFolderFColor(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UOpenPypePublishInstance::SendNotification(const FString& Text) const
|
||||
{
|
||||
FNotificationInfo Info{FText::FromString(Text)};
|
||||
|
||||
Info.bFireAndForget = true;
|
||||
Info.bUseLargeFont = false;
|
||||
Info.bUseThrobber = false;
|
||||
Info.bUseSuccessFailIcons = false;
|
||||
Info.ExpireDuration = 4.f;
|
||||
Info.FadeOutDuration = 2.f;
|
||||
|
||||
FSlateNotificationManager::Get().AddNotification(Info);
|
||||
|
||||
UE_LOG(LogAssetData, Warning,
|
||||
TEXT(
|
||||
"Removed duplicated asset from the AssetsDataExternal in Container \"%s\", Asset is already included in the AssetDataInternal!"
|
||||
), *GetName()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
void UOpenPypePublishInstance::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
||||
{
|
||||
Super::PostEditChangeProperty(PropertyChangedEvent);
|
||||
|
||||
if (PropertyChangedEvent.ChangeType == EPropertyChangeType::ValueSet &&
|
||||
PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(
|
||||
UOpenPypePublishInstance, AssetDataExternal))
|
||||
{
|
||||
// Check for duplicated assets
|
||||
for (const auto& Asset : AssetDataInternal)
|
||||
{
|
||||
if (AssetDataExternal.Contains(Asset))
|
||||
{
|
||||
AssetDataExternal.Remove(Asset);
|
||||
return SendNotification(
|
||||
"You are not allowed to add assets into AssetDataExternal which are already included in AssetDataInternal!");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if no UOpenPypePublishInstance type assets are included
|
||||
for (const auto& Asset : AssetDataExternal)
|
||||
{
|
||||
if (Cast<UOpenPypePublishInstance>(Asset.Get()) != nullptr)
|
||||
{
|
||||
AssetDataExternal.Remove(Asset);
|
||||
return SendNotification("You are not allowed to add publish instances!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
class FAyonModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
|
||||
private:
|
||||
void RegisterSettings();
|
||||
bool HandleSettingsSaved();
|
||||
|
||||
void AddMenuEntry(FMenuBuilder& MenuBuilder);
|
||||
void AddToobarEntry(FToolBarBuilder& ToolbarBuilder);
|
||||
void MenuPopup();
|
||||
void MenuDialog();
|
||||
};
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/NoExportTypes.h"
|
||||
#include "Engine/AssetUserData.h"
|
||||
#include "AssetData.h"
|
||||
#include "AyonAssetContainer.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS(Blueprintable)
|
||||
class AYON_API UAyonAssetContainer : public UAssetUserData
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UAyonAssetContainer(const FObjectInitializer& ObjectInitalizer);
|
||||
// ~UAyonAssetContainer();
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Assets")
|
||||
TArray<FString> assets;
|
||||
|
||||
// There seems to be no reflection option to expose array of FAssetData
|
||||
/*
|
||||
UPROPERTY(Transient, BlueprintReadOnly, Category = "Python", meta=(DisplayName="Assets Data"))
|
||||
TArray<FAssetData> assetsData;
|
||||
*/
|
||||
private:
|
||||
TArray<FAssetData> assetsData;
|
||||
void OnAssetAdded(const FAssetData& AssetData);
|
||||
void OnAssetRemoved(const FAssetData& AssetData);
|
||||
void OnAssetRenamed(const FAssetData& AssetData, const FString& str);
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Factories/Factory.h"
|
||||
#include "AyonAssetContainerFactory.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class AYON_API UAyonAssetContainerFactory : public UFactory
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UAyonAssetContainerFactory(const FObjectInitializer& ObjectInitializer);
|
||||
virtual UObject* FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override;
|
||||
virtual bool ShouldShowInNewMenu() const override;
|
||||
};
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
namespace AyonConstants
|
||||
{
|
||||
const FString Ayon_PluginName = "Ayon";
|
||||
const FString PythonScript_PluginName = "PythonScriptPlugin";
|
||||
const FString SequencerScripting_PluginName = "SequencerScripting";
|
||||
const FString MovieRenderPipeline_PluginName = "MovieRenderPipeline";
|
||||
const FString EditorScriptingUtils_PluginName = "EditorScriptingUtilities";
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#pragma once
|
||||
|
||||
#include "AyonLib.generated.h"
|
||||
|
||||
|
||||
UCLASS(Blueprintable)
|
||||
class AYON_API UAyonLib : public UBlueprintFunctionLibrary
|
||||
{
|
||||
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, Category = Python)
|
||||
static bool SetFolderColor(const FString& FolderPath, const FLinearColor& FolderColor,const bool& bForceAdd);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = Python)
|
||||
static TArray<FString> GetAllProperties(UClass* cls);
|
||||
};
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
// Deprecation warning: this is left here just for backwards compatibility
|
||||
// and will be removed in next versions of Ayon.
|
||||
#pragma once
|
||||
|
||||
#include "AyonPublishInstance.generated.h"
|
||||
|
||||
|
||||
UCLASS(Blueprintable)
|
||||
class AYON_API UAyonPublishInstance : public UPrimaryDataAsset
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
public:
|
||||
/**
|
||||
* Retrieves all the assets which are monitored by the Publish Instance (Monitors assets in the directory which is
|
||||
* placed in)
|
||||
*
|
||||
* @return - Set of UObjects. Careful! They are returning raw pointers. Seems like an issue in UE5
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Python")
|
||||
TSet<UObject*> GetInternalAssets() const
|
||||
{
|
||||
//For some reason it can only return Raw Pointers? Seems like an issue which they haven't fixed.
|
||||
TSet<UObject*> ResultSet;
|
||||
|
||||
for (const auto& Asset : AssetDataInternal)
|
||||
ResultSet.Add(Asset.LoadSynchronous());
|
||||
|
||||
return ResultSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all the assets which have been added manually by the Publish Instance
|
||||
*
|
||||
* @return - TSet of assets (UObjects). Careful! They are returning raw pointers. Seems like an issue in UE5
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Python")
|
||||
TSet<UObject*> GetExternalAssets() const
|
||||
{
|
||||
//For some reason it can only return Raw Pointers? Seems like an issue which they haven't fixed.
|
||||
TSet<UObject*> ResultSet;
|
||||
|
||||
for (const auto& Asset : AssetDataExternal)
|
||||
ResultSet.Add(Asset.LoadSynchronous());
|
||||
|
||||
return ResultSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for returning all the assets in the container combined.
|
||||
*
|
||||
* @return Returns all the internal and externally added assets into one set (TSet of UObjects). Careful! They are
|
||||
* returning raw pointers. Seems like an issue in UE5
|
||||
*
|
||||
* @attention If the bAddExternalAssets variable is false, external assets won't be included!
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Python")
|
||||
TSet<UObject*> GetAllAssets() const
|
||||
{
|
||||
const TSet<TSoftObjectPtr<UObject>>& IteratedSet = bAddExternalAssets
|
||||
? AssetDataInternal.Union(AssetDataExternal)
|
||||
: AssetDataInternal;
|
||||
|
||||
//Create a new TSet only with raw pointers.
|
||||
TSet<UObject*> ResultSet;
|
||||
|
||||
for (auto& Asset : IteratedSet)
|
||||
ResultSet.Add(Asset.LoadSynchronous());
|
||||
|
||||
return ResultSet;
|
||||
}
|
||||
|
||||
private:
|
||||
UPROPERTY(VisibleAnywhere, Category="Assets")
|
||||
TSet<TSoftObjectPtr<UObject>> AssetDataInternal;
|
||||
|
||||
/**
|
||||
* This property allows exposing the array to include other assets from any other directory than what it's currently
|
||||
* monitoring. NOTE: that these assets have to be added manually! They are not automatically registered or added!
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, Category = "Assets")
|
||||
bool bAddExternalAssets = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, meta=(EditCondition="bAddExternalAssets"), Category="Assets")
|
||||
TSet<TSoftObjectPtr<UObject>> AssetDataExternal;
|
||||
|
||||
|
||||
void OnAssetCreated(const FAssetData& InAssetData);
|
||||
void OnAssetRemoved(const FAssetData& InAssetData);
|
||||
void OnAssetUpdated(const FAssetData& InAssetData);
|
||||
|
||||
bool IsUnderSameDir(const UObject* InAsset) const;
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
|
||||
void ColorAyonDirs();
|
||||
|
||||
void SendNotification(const FString& Text) const;
|
||||
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
// Deprecation warning: this is left here just for backwards compatibility
|
||||
// and will be removed in next versions of Ayon.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Factories/Factory.h"
|
||||
#include "AyonPublishInstanceFactory.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class AYON_API UAyonPublishInstanceFactory : public UFactory
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UAyonPublishInstanceFactory(const FObjectInitializer& ObjectInitializer);
|
||||
virtual UObject* FactoryCreateNew(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override;
|
||||
virtual bool ShouldShowInNewMenu() const override;
|
||||
};
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#pragma once
|
||||
#include "AyonPythonBridge.generated.h"
|
||||
|
||||
UCLASS(Blueprintable)
|
||||
class UAyonPythonBridge : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, Category = Python)
|
||||
static UAyonPythonBridge* Get();
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = Python)
|
||||
void RunInPython_Popup() const;
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = Python)
|
||||
void RunInPython_Dialog() const;
|
||||
|
||||
};
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "AyonSettings.generated.h"
|
||||
|
||||
#define AYON_SETTINGS_FILEPATH IPluginManager::Get().FindPlugin("Ayon")->GetBaseDir() / TEXT("Config") / TEXT("DefaultAyonSettings.ini")
|
||||
|
||||
UCLASS(Config=AyonSettings, DefaultConfig)
|
||||
class AYON_API UAyonSettings : public UObject
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = Settings)
|
||||
FColor GetFolderFColor() const
|
||||
{
|
||||
return FolderColor;
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = Settings)
|
||||
FLinearColor GetFolderFLinearColor() const
|
||||
{
|
||||
return FLinearColor(FolderColor);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
UPROPERTY(config, EditAnywhere, Category = Folders)
|
||||
FColor FolderColor = FColor(25,45,223);
|
||||
};
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#pragma once
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
class FSlateStyleSet;
|
||||
class ISlateStyle;
|
||||
|
||||
|
||||
class FAyonStyle
|
||||
{
|
||||
public:
|
||||
static void Initialize();
|
||||
static void Shutdown();
|
||||
static const ISlateStyle& Get();
|
||||
static FName GetStyleSetName();
|
||||
static FName GetContextName();
|
||||
|
||||
static void SetIcon(const FString& StyleName, const FString& ResourcePath);
|
||||
|
||||
private:
|
||||
static TUniquePtr< FSlateStyleSet > Create();
|
||||
static TUniquePtr< FSlateStyleSet > AyonStyleInstance;
|
||||
};
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "AyonActionResult.generated.h"
|
||||
|
||||
/**
|
||||
* @brief This macro returns error code when is problem or does nothing when there is no problem.
|
||||
* @param ActionResult FAyon_ActionResult structure
|
||||
*/
|
||||
#define EVALUATE_AYON_ACTION_RESULT(ActionResult) \
|
||||
if(ActionResult.IsProblem()) \
|
||||
return ActionResult.GetStatus();
|
||||
|
||||
/**
|
||||
* @brief This enum values are humanly readable mapping of error codes.
|
||||
* Here should be all error codes to be possible find what went wrong.
|
||||
* TODO: In the future should exists an web document where is mapped error code & what problem occured & how to repair it...
|
||||
*/
|
||||
UENUM()
|
||||
namespace EAyon_ActionResult
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Ok,
|
||||
ProjectNotCreated,
|
||||
ProjectNotLoaded,
|
||||
ProjectNotSaved,
|
||||
//....Here insert another values
|
||||
|
||||
//Do not remove!
|
||||
//Usable for looping through enum values
|
||||
__Last UMETA(Hidden)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This struct holds action result enum and optionally reason of fail
|
||||
*/
|
||||
USTRUCT()
|
||||
struct FAyon_ActionResult
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/** @brief Default constructor usable when there is no problem */
|
||||
FAyon_ActionResult();
|
||||
|
||||
/**
|
||||
* @brief This constructor initializes variables & attempts to log when is error
|
||||
* @param InEnum Status
|
||||
*/
|
||||
FAyon_ActionResult(const EAyon_ActionResult::Type& InEnum);
|
||||
|
||||
/**
|
||||
* @brief This constructor initializes variables & attempts to log when is error
|
||||
* @param InEnum Status
|
||||
* @param InReason Reason of potential fail
|
||||
*/
|
||||
FAyon_ActionResult(const EAyon_ActionResult::Type& InEnum, const FText& InReason);
|
||||
|
||||
private:
|
||||
/** @brief Action status */
|
||||
EAyon_ActionResult::Type Status;
|
||||
|
||||
/** @brief Optional reason of fail */
|
||||
FText Reason;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Checks if there is problematic state
|
||||
* @return true when status is not equal to EAyon_ActionResult::Ok
|
||||
*/
|
||||
bool IsProblem() const;
|
||||
EAyon_ActionResult::Type& GetStatus();
|
||||
FText& GetReason();
|
||||
|
||||
private:
|
||||
void TryLog() const;
|
||||
};
|
||||
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#pragma once
|
||||
|
||||
#include "GameProjectUtils.h"
|
||||
#include "Commandlets/AyonActionResult.h"
|
||||
#include "ProjectDescriptor.h"
|
||||
#include "Commandlets/Commandlet.h"
|
||||
#include "AyonGenerateProjectCommandlet.generated.h"
|
||||
|
||||
struct FProjectDescriptor;
|
||||
struct FProjectInformation;
|
||||
|
||||
/**
|
||||
* @brief Structure which parses command line parameters and generates FProjectInformation
|
||||
*/
|
||||
USTRUCT()
|
||||
struct FAyonGenerateProjectParams
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
private:
|
||||
FString CommandLineParams;
|
||||
TArray<FString> Tokens;
|
||||
TArray<FString> Switches;
|
||||
|
||||
public:
|
||||
FAyonGenerateProjectParams();
|
||||
FAyonGenerateProjectParams(const FString& CommandLineParams);
|
||||
|
||||
FProjectInformation GenerateUEProjectInformation() const;
|
||||
|
||||
private:
|
||||
FString TryGetToken(const int32 Index) const;
|
||||
FString GetProjectFileName() const;
|
||||
|
||||
bool IsSwitchPresent(const FString& Switch) const;
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
class AYON_API UAyonGenerateProjectCommandlet : public UCommandlet
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
private:
|
||||
FProjectInformation ProjectInformation;
|
||||
FProjectDescriptor ProjectDescriptor;
|
||||
|
||||
public:
|
||||
UAyonGenerateProjectCommandlet();
|
||||
|
||||
virtual int32 Main(const FString& CommandLineParams) override;
|
||||
|
||||
private:
|
||||
FAyonGenerateProjectParams ParseParameters(const FString& Params) const;
|
||||
FAyon_ActionResult TryCreateProject() const;
|
||||
FAyon_ActionResult TryLoadProjectDescriptor();
|
||||
void AttachPluginsToProjectDescriptor();
|
||||
FAyon_ActionResult TrySave();
|
||||
};
|
||||
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#pragma once
|
||||
|
||||
DEFINE_LOG_CATEGORY_STATIC(LogCommandletOPGenerateProject, Log, All);
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
// Deprecation warning: this is left here just for backwards compatibility
|
||||
// and will be removed in next versions of Ayon.
|
||||
#pragma once
|
||||
|
||||
#include "OpenPypePublishInstance.generated.h"
|
||||
|
||||
|
||||
UCLASS(Blueprintable)
|
||||
class AYON_API UOpenPypePublishInstance : public UPrimaryDataAsset
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
public:
|
||||
/**
|
||||
* Retrieves all the assets which are monitored by the Publish Instance (Monitors assets in the directory which is
|
||||
* placed in)
|
||||
*
|
||||
* @return - Set of UObjects. Careful! They are returning raw pointers. Seems like an issue in UE5
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Python")
|
||||
TSet<UObject*> GetInternalAssets() const
|
||||
{
|
||||
//For some reason it can only return Raw Pointers? Seems like an issue which they haven't fixed.
|
||||
TSet<UObject*> ResultSet;
|
||||
|
||||
for (const auto& Asset : AssetDataInternal)
|
||||
ResultSet.Add(Asset.LoadSynchronous());
|
||||
|
||||
return ResultSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all the assets which have been added manually by the Publish Instance
|
||||
*
|
||||
* @return - TSet of assets (UObjects). Careful! They are returning raw pointers. Seems like an issue in UE5
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Python")
|
||||
TSet<UObject*> GetExternalAssets() const
|
||||
{
|
||||
//For some reason it can only return Raw Pointers? Seems like an issue which they haven't fixed.
|
||||
TSet<UObject*> ResultSet;
|
||||
|
||||
for (const auto& Asset : AssetDataExternal)
|
||||
ResultSet.Add(Asset.LoadSynchronous());
|
||||
|
||||
return ResultSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for returning all the assets in the container combined.
|
||||
*
|
||||
* @return Returns all the internal and externally added assets into one set (TSet of UObjects). Careful! They are
|
||||
* returning raw pointers. Seems like an issue in UE5
|
||||
*
|
||||
* @attention If the bAddExternalAssets variable is false, external assets won't be included!
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Python")
|
||||
TSet<UObject*> GetAllAssets() const
|
||||
{
|
||||
const TSet<TSoftObjectPtr<UObject>>& IteratedSet = bAddExternalAssets
|
||||
? AssetDataInternal.Union(AssetDataExternal)
|
||||
: AssetDataInternal;
|
||||
|
||||
//Create a new TSet only with raw pointers.
|
||||
TSet<UObject*> ResultSet;
|
||||
|
||||
for (auto& Asset : IteratedSet)
|
||||
ResultSet.Add(Asset.LoadSynchronous());
|
||||
|
||||
return ResultSet;
|
||||
}
|
||||
|
||||
private:
|
||||
UPROPERTY(VisibleAnywhere, Category="Assets")
|
||||
TSet<TSoftObjectPtr<UObject>> AssetDataInternal;
|
||||
|
||||
/**
|
||||
* This property allows exposing the array to include other assets from any other directory than what it's currently
|
||||
* monitoring. NOTE: that these assets have to be added manually! They are not automatically registered or added!
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, Category = "Assets")
|
||||
bool bAddExternalAssets = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, meta=(EditCondition="bAddExternalAssets"), Category="Assets")
|
||||
TSet<TSoftObjectPtr<UObject>> AssetDataExternal;
|
||||
|
||||
|
||||
void OnAssetCreated(const FAssetData& InAssetData);
|
||||
void OnAssetRemoved(const FAssetData& InAssetData);
|
||||
void OnAssetUpdated(const FAssetData& InAssetData);
|
||||
|
||||
bool IsUnderSameDir(const UObject* InAsset) const;
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
|
||||
void ColorOpenPypeDirs();
|
||||
|
||||
void SendNotification(const FString& Text) const;
|
||||
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
|
@ -1 +0,0 @@
|
|||
D:\UE4\UE_4.27\Engine\Build\BatchFiles\RunUAT.bat BuildPlugin -plugin="D:\OpenPype\openpype\hosts\unreal\integration\UE_4.27\Ayon\Ayon.uplugin" -Package="D:\BuiltPlugins\4.27"
|
||||
|
|
@ -1 +0,0 @@
|
|||
cmd /k "BuildPlugin_4-27.bat"
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
/Saved
|
||||
/DerivedDataCache
|
||||
/Intermediate
|
||||
/Content
|
||||
/Config
|
||||
/Binaries
|
||||
/.idea
|
||||
/.vs
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"FileVersion": 3,
|
||||
"EngineAssociation": "4.27",
|
||||
"Category": "",
|
||||
"Description": "",
|
||||
"Plugins": [
|
||||
{
|
||||
"Name": "Ayon",
|
||||
"Enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
/Binaries
|
||||
/Intermediate
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
{
|
||||
"FileVersion": 3,
|
||||
"Version": 1,
|
||||
"VersionName": "1.0",
|
||||
"FriendlyName": "Ayon",
|
||||
"Description": "Ayon Integration",
|
||||
"Category": "Ayon.Integration",
|
||||
"CreatedBy": "Ondrej Samohel",
|
||||
"CreatedByURL": "https://ayon.ynput.io",
|
||||
"DocsURL": "https://ayon.ynput.io/docs/artist_hosts_unreal",
|
||||
"MarketplaceURL": "",
|
||||
"SupportURL": "https://ynput.io/",
|
||||
"CanContainContent": true,
|
||||
"EngineVersion": "5.0",
|
||||
"IsExperimentalVersion": false,
|
||||
"Installed": true,
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "Ayon",
|
||||
"Type": "Editor",
|
||||
"LoadingPhase": "Default"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[/Script/Ayon.AyonSettings]
|
||||
FolderColor=(R=91,G=197,B=220,A=255)
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
[FilterPlugin]
|
||||
; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and
|
||||
; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively.
|
||||
;
|
||||
; Examples:
|
||||
; /README.txt
|
||||
; /Extras/...
|
||||
; /Binaries/ThirdParty/*.dll
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
import unreal
|
||||
|
||||
ayon_detected = True
|
||||
try:
|
||||
from openpype.pipeline import install_host
|
||||
from openpype.hosts.unreal.api import UnrealHost
|
||||
|
||||
ayon_host = UnrealHost()
|
||||
except ImportError as exc:
|
||||
ayon_host = None
|
||||
ayon_detected = False
|
||||
unreal.log_error(f"Ayon: cannot load Ayon integration [ {exc} ]")
|
||||
|
||||
if ayon_detected:
|
||||
install_host(ayon_host)
|
||||
|
||||
|
||||
@unreal.uclass()
|
||||
class AyonIntegration(unreal.AyonPythonBridge):
|
||||
@unreal.ufunction(override=True)
|
||||
def RunInPython_Popup(self):
|
||||
unreal.log_warning("Ayon: showing tools popup")
|
||||
if ayon_detected:
|
||||
ayon_host.show_tools_popup()
|
||||
|
||||
@unreal.ufunction(override=True)
|
||||
def RunInPython_Dialog(self):
|
||||
unreal.log_warning("Ayon: showing tools dialog")
|
||||
if ayon_detected:
|
||||
ayon_host.show_tools_dialog()
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
# Ayon Unreal Integration plugin - UE 5.0
|
||||
|
||||
This is plugin for Unreal Editor, creating menu for [Ayon](https://github.com/ynput/OpenPype) tools to run.
|
||||
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 721 B |
|
Before Width: | Height: | Size: 16 KiB |
|
|
@ -1,65 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class Ayon : ModuleRules
|
||||
{
|
||||
public Ayon(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
DefaultBuildSettings = BuildSettingsVersion.V2;
|
||||
bLegacyPublicIncludePaths = false;
|
||||
ShadowVariableWarningLevel = WarningLevel.Error;
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
//IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_0;
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add public include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add other private include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
"CoreUObject"
|
||||
// ... add other public dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"GameProjectGeneration",
|
||||
"Projects",
|
||||
"InputCore",
|
||||
"EditorFramework",
|
||||
"UnrealEd",
|
||||
"ToolMenus",
|
||||
"LevelEditor",
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
"AssetTools"
|
||||
// ... add private dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
// ... add any modules that your module loads dynamically here ...
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#include "Ayon.h"
|
||||
|
||||
#include "ISettingsContainer.h"
|
||||
#include "ISettingsModule.h"
|
||||
#include "ISettingsSection.h"
|
||||
#include "AyonStyle.h"
|
||||
#include "AyonCommands.h"
|
||||
#include "AyonPythonBridge.h"
|
||||
#include "AyonSettings.h"
|
||||
#include "ToolMenus.h"
|
||||
|
||||
|
||||
static const FName AyonTabName("Ayon");
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FAyonModule"
|
||||
|
||||
// This function is triggered when the plugin is staring up
|
||||
void FAyonModule::StartupModule()
|
||||
{
|
||||
FAyonStyle::Initialize();
|
||||
FAyonStyle::ReloadTextures();
|
||||
FAyonCommands::Register();
|
||||
|
||||
PluginCommands = MakeShareable(new FUICommandList);
|
||||
|
||||
PluginCommands->MapAction(
|
||||
FAyonCommands::Get().AyonTools,
|
||||
FExecuteAction::CreateRaw(this, &FAyonModule::MenuPopup),
|
||||
FCanExecuteAction());
|
||||
PluginCommands->MapAction(
|
||||
FAyonCommands::Get().AyonToolsDialog,
|
||||
FExecuteAction::CreateRaw(this, &FAyonModule::MenuDialog),
|
||||
FCanExecuteAction());
|
||||
|
||||
UToolMenus::RegisterStartupCallback(
|
||||
FSimpleMulticastDelegate::FDelegate::CreateRaw(this, &FAyonModule::RegisterMenus));
|
||||
|
||||
RegisterSettings();
|
||||
}
|
||||
|
||||
void FAyonModule::ShutdownModule()
|
||||
{
|
||||
UToolMenus::UnRegisterStartupCallback(this);
|
||||
|
||||
UToolMenus::UnregisterOwner(this);
|
||||
|
||||
FAyonStyle::Shutdown();
|
||||
|
||||
FAyonCommands::Unregister();
|
||||
}
|
||||
|
||||
|
||||
void FAyonModule::RegisterSettings()
|
||||
{
|
||||
ISettingsModule& SettingsModule = FModuleManager::LoadModuleChecked<ISettingsModule>("Settings");
|
||||
|
||||
// Create the new category
|
||||
// TODO: After the movement of the plugin from the game to editor, it might be necessary to move this!
|
||||
ISettingsContainerPtr SettingsContainer = SettingsModule.GetContainer("Project");
|
||||
|
||||
UAyonSettings* Settings = GetMutableDefault<UAyonSettings>();
|
||||
|
||||
// Register the settings
|
||||
ISettingsSectionPtr SettingsSection = SettingsModule.RegisterSettings("Project", "Ayon", "General",
|
||||
LOCTEXT("RuntimeGeneralSettingsName",
|
||||
"General"),
|
||||
LOCTEXT("RuntimeGeneralSettingsDescription",
|
||||
"Base configuration for Open Pype Module"),
|
||||
Settings
|
||||
);
|
||||
|
||||
// Register the save handler to your settings, you might want to use it to
|
||||
// validate those or just act to settings changes.
|
||||
if (SettingsSection.IsValid())
|
||||
{
|
||||
SettingsSection->OnModified().BindRaw(this, &FAyonModule::HandleSettingsSaved);
|
||||
}
|
||||
}
|
||||
|
||||
bool FAyonModule::HandleSettingsSaved()
|
||||
{
|
||||
UAyonSettings* Settings = GetMutableDefault<UAyonSettings>();
|
||||
bool ResaveSettings = false;
|
||||
|
||||
// You can put any validation code in here and resave the settings in case an invalid
|
||||
// value has been entered
|
||||
|
||||
if (ResaveSettings)
|
||||
{
|
||||
Settings->SaveConfig();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FAyonModule::RegisterMenus()
|
||||
{
|
||||
// Owner will be used for cleanup in call to UToolMenus::UnregisterOwner
|
||||
FToolMenuOwnerScoped OwnerScoped(this);
|
||||
|
||||
{
|
||||
UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.MainMenu.Tools");
|
||||
{
|
||||
// FToolMenuSection& Section = Menu->FindOrAddSection("Ayon");
|
||||
FToolMenuSection& Section = Menu->AddSection(
|
||||
"Ayon",
|
||||
TAttribute<FText>(FText::FromString("Ayon")),
|
||||
FToolMenuInsert("Programming", EToolMenuInsertType::Before)
|
||||
);
|
||||
Section.AddMenuEntryWithCommandList(FAyonCommands::Get().AyonTools, PluginCommands);
|
||||
Section.AddMenuEntryWithCommandList(FAyonCommands::Get().AyonToolsDialog, PluginCommands);
|
||||
}
|
||||
UToolMenu* ToolbarMenu = UToolMenus::Get()->ExtendMenu("LevelEditor.LevelEditorToolBar.PlayToolBar");
|
||||
{
|
||||
FToolMenuSection& Section = ToolbarMenu->FindOrAddSection("PluginTools");
|
||||
{
|
||||
FToolMenuEntry& Entry = Section.AddEntry(
|
||||
FToolMenuEntry::InitToolBarButton(FAyonCommands::Get().AyonTools));
|
||||
Entry.SetCommandList(PluginCommands);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FAyonModule::MenuPopup()
|
||||
{
|
||||
UAyonPythonBridge* bridge = UAyonPythonBridge::Get();
|
||||
bridge->RunInPython_Popup();
|
||||
}
|
||||
|
||||
void FAyonModule::MenuDialog()
|
||||
{
|
||||
UAyonPythonBridge* bridge = UAyonPythonBridge::Get();
|
||||
bridge->RunInPython_Dialog();
|
||||
}
|
||||
|
||||
IMPLEMENT_MODULE(FAyonModule, Ayon)
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#include "AyonAssetContainer.h"
|
||||
#include "AssetRegistry/AssetRegistryModule.h"
|
||||
#include "Misc/PackageName.h"
|
||||
#include "Containers/UnrealString.h"
|
||||
|
||||
UAyonAssetContainer::UAyonAssetContainer(const FObjectInitializer& ObjectInitializer)
|
||||
: UAssetUserData(ObjectInitializer)
|
||||
{
|
||||
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
|
||||
FString path = UAyonAssetContainer::GetPathName();
|
||||
UE_LOG(LogTemp, Warning, TEXT("UAyonAssetContainer %s"), *path);
|
||||
FARFilter Filter;
|
||||
Filter.PackagePaths.Add(FName(*path));
|
||||
|
||||
AssetRegistryModule.Get().OnAssetAdded().AddUObject(this, &UAyonAssetContainer::OnAssetAdded);
|
||||
AssetRegistryModule.Get().OnAssetRemoved().AddUObject(this, &UAyonAssetContainer::OnAssetRemoved);
|
||||
AssetRegistryModule.Get().OnAssetRenamed().AddUObject(this, &UAyonAssetContainer::OnAssetRenamed);
|
||||
}
|
||||
|
||||
void UAyonAssetContainer::OnAssetAdded(const FAssetData& AssetData)
|
||||
{
|
||||
TArray<FString> split;
|
||||
|
||||
// get directory of current container
|
||||
FString selfFullPath = UAyonAssetContainer::GetPathName();
|
||||
FString selfDir = FPackageName::GetLongPackagePath(*selfFullPath);
|
||||
|
||||
// get asset path and class
|
||||
FString assetPath = AssetData.GetFullName();
|
||||
FString assetFName = AssetData.ObjectPath.ToString();
|
||||
UE_LOG(LogTemp, Log, TEXT("asset name %s"), *assetFName);
|
||||
// split path
|
||||
assetPath.ParseIntoArray(split, TEXT(" "), true);
|
||||
|
||||
FString assetDir = FPackageName::GetLongPackagePath(*split[1]);
|
||||
|
||||
// take interest only in paths starting with path of current container
|
||||
if (assetDir.StartsWith(*selfDir))
|
||||
{
|
||||
// exclude self
|
||||
if (assetFName != "AssetContainer")
|
||||
{
|
||||
assets.Add(assetPath);
|
||||
assetsData.Add(AssetData);
|
||||
UE_LOG(LogTemp, Log, TEXT("%s: asset added to %s"), *selfFullPath, *selfDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UAyonAssetContainer::OnAssetRemoved(const FAssetData& AssetData)
|
||||
{
|
||||
TArray<FString> split;
|
||||
|
||||
// get directory of current container
|
||||
FString selfFullPath = UAyonAssetContainer::GetPathName();
|
||||
FString selfDir = FPackageName::GetLongPackagePath(*selfFullPath);
|
||||
|
||||
// get asset path and class
|
||||
FString assetPath = AssetData.GetFullName();
|
||||
FString assetFName = AssetData.ObjectPath.ToString();
|
||||
|
||||
// split path
|
||||
assetPath.ParseIntoArray(split, TEXT(" "), true);
|
||||
|
||||
FString assetDir = FPackageName::GetLongPackagePath(*split[1]);
|
||||
|
||||
// take interest only in paths starting with path of current container
|
||||
FString path = UAyonAssetContainer::GetPathName();
|
||||
FString lpp = FPackageName::GetLongPackagePath(*path);
|
||||
|
||||
if (assetDir.StartsWith(*selfDir))
|
||||
{
|
||||
// exclude self
|
||||
if (assetFName != "AssetContainer")
|
||||
{
|
||||
// UE_LOG(LogTemp, Warning, TEXT("%s: asset removed"), *lpp);
|
||||
assets.Remove(assetPath);
|
||||
assetsData.Remove(AssetData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UAyonAssetContainer::OnAssetRenamed(const FAssetData& AssetData, const FString& str)
|
||||
{
|
||||
TArray<FString> split;
|
||||
|
||||
// get directory of current container
|
||||
FString selfFullPath = UAyonAssetContainer::GetPathName();
|
||||
FString selfDir = FPackageName::GetLongPackagePath(*selfFullPath);
|
||||
|
||||
// get asset path and class
|
||||
FString assetPath = AssetData.GetFullName();
|
||||
FString assetFName = AssetData.ObjectPath.ToString();
|
||||
|
||||
// split path
|
||||
assetPath.ParseIntoArray(split, TEXT(" "), true);
|
||||
|
||||
FString assetDir = FPackageName::GetLongPackagePath(*split[1]);
|
||||
if (assetDir.StartsWith(*selfDir))
|
||||
{
|
||||
// exclude self
|
||||
if (assetFName != "AssetContainer")
|
||||
{
|
||||
|
||||
assets.Remove(str);
|
||||
assets.Add(assetPath);
|
||||
assetsData.Remove(AssetData);
|
||||
// UE_LOG(LogTemp, Warning, TEXT("%s: asset renamed %s"), *lpp, *str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
#include "AyonAssetContainerFactory.h"
|
||||
#include "AyonAssetContainer.h"
|
||||
|
||||
UAyonAssetContainerFactory::UAyonAssetContainerFactory(const FObjectInitializer& ObjectInitializer)
|
||||
: UFactory(ObjectInitializer)
|
||||
{
|
||||
SupportedClass = UAyonAssetContainer::StaticClass();
|
||||
bCreateNew = false;
|
||||
bEditorImport = true;
|
||||
}
|
||||
|
||||
UObject* UAyonAssetContainerFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn)
|
||||
{
|
||||
UAyonAssetContainer* AssetContainer = NewObject<UAyonAssetContainer>(InParent, Class, Name, Flags);
|
||||
return AssetContainer;
|
||||
}
|
||||
|
||||
bool UAyonAssetContainerFactory::ShouldShowInNewMenu() const {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
#include "AyonCommands.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FAyonModule"
|
||||
|
||||
void FAyonCommands::RegisterCommands()
|
||||
{
|
||||
UI_COMMAND(AyonTools, "Ayon Tools", "Pipeline tools", EUserInterfaceActionType::Button, FInputChord());
|
||||
UI_COMMAND(AyonToolsDialog, "Ayon Tools Dialog", "Pipeline tools dialog", EUserInterfaceActionType::Button, FInputChord());
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#include "AyonLib.h"
|
||||
|
||||
#include "AssetViewUtils.h"
|
||||
#include "UObject/UnrealType.h"
|
||||
|
||||
/**
|
||||
* Sets color on folder icon on given path
|
||||
* @param InPath - path to folder
|
||||
* @param InFolderColor - color of the folder
|
||||
* @warning This color will appear only after Editor restart. Is there a better way?
|
||||
*/
|
||||
|
||||
bool UAyonLib::SetFolderColor(const FString& FolderPath, const FLinearColor& FolderColor, const bool& bForceAdd)
|
||||
{
|
||||
if (AssetViewUtils::DoesFolderExist(FolderPath))
|
||||
{
|
||||
const TSharedPtr<FLinearColor> LinearColor = MakeShared<FLinearColor>(FolderColor);
|
||||
|
||||
AssetViewUtils::SaveColor(FolderPath, LinearColor, true);
|
||||
UE_LOG(LogAssetData, Display, TEXT("A color {%s} has been set to folder \"%s\""), *LinearColor->ToString(),
|
||||
*FolderPath)
|
||||
return true;
|
||||
}
|
||||
|
||||
UE_LOG(LogAssetData, Display, TEXT("Setting a color {%s} to folder \"%s\" has failed! Directory doesn't exist!"),
|
||||
*FolderColor.ToString(), *FolderPath)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all poperties on given object
|
||||
* @param cls - class
|
||||
* @return TArray of properties
|
||||
*/
|
||||
TArray<FString> UAyonLib::GetAllProperties(UClass* cls)
|
||||
{
|
||||
TArray<FString> Ret;
|
||||
if (cls != nullptr)
|
||||
{
|
||||
for (TFieldIterator<FProperty> It(cls); It; ++It)
|
||||
{
|
||||
FProperty* Property = *It;
|
||||
if (Property->HasAnyPropertyFlags(EPropertyFlags::CPF_Edit))
|
||||
{
|
||||
Ret.Add(Property->GetName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
|
@ -1,204 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
// Deprecation warning: this is left here just for backwards compatibility
|
||||
// and will be removed in next versions of Ayon.
|
||||
#pragma once
|
||||
|
||||
#include "AyonPublishInstance.h"
|
||||
#include "AssetRegistry/AssetRegistryModule.h"
|
||||
#include "AssetToolsModule.h"
|
||||
#include "Framework/Notifications/NotificationManager.h"
|
||||
#include "AyonLib.h"
|
||||
#include "AyonSettings.h"
|
||||
#include "Widgets/Notifications/SNotificationList.h"
|
||||
|
||||
|
||||
//Moves all the invalid pointers to the end to prepare them for the shrinking
|
||||
#define REMOVE_INVALID_ENTRIES(VAR) VAR.CompactStable(); \
|
||||
VAR.Shrink();
|
||||
|
||||
UAyonPublishInstance::UAyonPublishInstance(const FObjectInitializer& ObjectInitializer)
|
||||
: UPrimaryDataAsset(ObjectInitializer)
|
||||
{
|
||||
const FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<
|
||||
FAssetRegistryModule>("AssetRegistry");
|
||||
|
||||
const FPropertyEditorModule& PropertyEditorModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>(
|
||||
"PropertyEditor");
|
||||
|
||||
FString Left, Right;
|
||||
GetPathName().Split("/" + GetName(), &Left, &Right);
|
||||
|
||||
FARFilter Filter;
|
||||
Filter.PackagePaths.Emplace(FName(Left));
|
||||
|
||||
TArray<FAssetData> FoundAssets;
|
||||
AssetRegistryModule.GetRegistry().GetAssets(Filter, FoundAssets);
|
||||
|
||||
for (const FAssetData& AssetData : FoundAssets)
|
||||
OnAssetCreated(AssetData);
|
||||
|
||||
REMOVE_INVALID_ENTRIES(AssetDataInternal)
|
||||
REMOVE_INVALID_ENTRIES(AssetDataExternal)
|
||||
|
||||
AssetRegistryModule.Get().OnAssetAdded().AddUObject(this, &UAyonPublishInstance::OnAssetCreated);
|
||||
AssetRegistryModule.Get().OnAssetRemoved().AddUObject(this, &UAyonPublishInstance::OnAssetRemoved);
|
||||
AssetRegistryModule.Get().OnAssetUpdated().AddUObject(this, &UAyonPublishInstance::OnAssetUpdated);
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
ColorAyonDirs();
|
||||
#endif
|
||||
}
|
||||
|
||||
void UAyonPublishInstance::OnAssetCreated(const FAssetData& InAssetData)
|
||||
{
|
||||
TArray<FString> split;
|
||||
|
||||
UObject* Asset = InAssetData.GetAsset();
|
||||
|
||||
if (!IsValid(Asset))
|
||||
{
|
||||
UE_LOG(LogAssetData, Warning, TEXT("Asset \"%s\" is not valid! Skipping the addition."),
|
||||
*InAssetData.ObjectPath.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
const bool result = IsUnderSameDir(Asset) && Cast<UAyonPublishInstance>(Asset) == nullptr;
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (AssetDataInternal.Emplace(Asset).IsValidId())
|
||||
{
|
||||
UE_LOG(LogTemp, Log, TEXT("Added an Asset to PublishInstance - Publish Instance: %s, Asset %s"),
|
||||
*this->GetName(), *Asset->GetName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UAyonPublishInstance::OnAssetRemoved(const FAssetData& InAssetData)
|
||||
{
|
||||
if (Cast<UAyonPublishInstance>(InAssetData.GetAsset()) == nullptr)
|
||||
{
|
||||
if (AssetDataInternal.Contains(nullptr))
|
||||
{
|
||||
AssetDataInternal.Remove(nullptr);
|
||||
REMOVE_INVALID_ENTRIES(AssetDataInternal)
|
||||
}
|
||||
else
|
||||
{
|
||||
AssetDataExternal.Remove(nullptr);
|
||||
REMOVE_INVALID_ENTRIES(AssetDataExternal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UAyonPublishInstance::OnAssetUpdated(const FAssetData& InAssetData)
|
||||
{
|
||||
REMOVE_INVALID_ENTRIES(AssetDataInternal);
|
||||
REMOVE_INVALID_ENTRIES(AssetDataExternal);
|
||||
}
|
||||
|
||||
bool UAyonPublishInstance::IsUnderSameDir(const UObject* InAsset) const
|
||||
{
|
||||
FString ThisLeft, ThisRight;
|
||||
this->GetPathName().Split(this->GetName(), &ThisLeft, &ThisRight);
|
||||
|
||||
return InAsset->GetPathName().StartsWith(ThisLeft);
|
||||
}
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
|
||||
void UAyonPublishInstance::ColorAyonDirs()
|
||||
{
|
||||
FString PathName = this->GetPathName();
|
||||
|
||||
//Check whether the path contains the defined Ayon folder
|
||||
if (!PathName.Contains(TEXT("Ayon"))) return;
|
||||
|
||||
//Get the base path for open pype
|
||||
FString PathLeft, PathRight;
|
||||
PathName.Split(FString("Ayon"), &PathLeft, &PathRight);
|
||||
|
||||
if (PathLeft.IsEmpty() || PathRight.IsEmpty())
|
||||
{
|
||||
UE_LOG(LogAssetData, Error, TEXT("Failed to retrieve the base Ayon directory!"))
|
||||
return;
|
||||
}
|
||||
|
||||
PathName.RemoveFromEnd(PathRight, ESearchCase::CaseSensitive);
|
||||
|
||||
//Get the current settings
|
||||
const UAyonSettings* Settings = GetMutableDefault<UAyonSettings>();
|
||||
|
||||
//Color the base folder
|
||||
UAyonLib::SetFolderColor(PathName, Settings->GetFolderFColor(), false);
|
||||
|
||||
//Get Sub paths, iterate through them and color them according to the folder color in UAyonSettings
|
||||
const FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(
|
||||
"AssetRegistry");
|
||||
|
||||
TArray<FString> PathList;
|
||||
|
||||
AssetRegistryModule.Get().GetSubPaths(PathName, PathList, true);
|
||||
|
||||
if (PathList.Num() > 0)
|
||||
{
|
||||
for (const FString& Path : PathList)
|
||||
{
|
||||
UAyonLib::SetFolderColor(Path, Settings->GetFolderFColor(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UAyonPublishInstance::SendNotification(const FString& Text) const
|
||||
{
|
||||
FNotificationInfo Info{FText::FromString(Text)};
|
||||
|
||||
Info.bFireAndForget = true;
|
||||
Info.bUseLargeFont = false;
|
||||
Info.bUseThrobber = false;
|
||||
Info.bUseSuccessFailIcons = false;
|
||||
Info.ExpireDuration = 4.f;
|
||||
Info.FadeOutDuration = 2.f;
|
||||
|
||||
FSlateNotificationManager::Get().AddNotification(Info);
|
||||
|
||||
UE_LOG(LogAssetData, Warning,
|
||||
TEXT(
|
||||
"Removed duplicated asset from the AssetsDataExternal in Container \"%s\", Asset is already included in the AssetDataInternal!"
|
||||
), *GetName()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
void UAyonPublishInstance::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
||||
{
|
||||
Super::PostEditChangeProperty(PropertyChangedEvent);
|
||||
|
||||
if (PropertyChangedEvent.ChangeType == EPropertyChangeType::ValueSet &&
|
||||
PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(
|
||||
UAyonPublishInstance, AssetDataExternal))
|
||||
{
|
||||
// Check for duplicated assets
|
||||
for (const auto& Asset : AssetDataInternal)
|
||||
{
|
||||
if (AssetDataExternal.Contains(Asset))
|
||||
{
|
||||
AssetDataExternal.Remove(Asset);
|
||||
return SendNotification(
|
||||
"You are not allowed to add assets into AssetDataExternal which are already included in AssetDataInternal!");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if no UAyonPublishInstance type assets are included
|
||||
for (const auto& Asset : AssetDataExternal)
|
||||
{
|
||||
if (Cast<UAyonPublishInstance>(Asset.Get()) != nullptr)
|
||||
{
|
||||
AssetDataExternal.Remove(Asset);
|
||||
return SendNotification("You are not allowed to add publish instances!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
// Deprecation warning: this is left here just for backwards compatibility
|
||||
// and will be removed in next versions of Ayon.
|
||||
#include "AyonPublishInstanceFactory.h"
|
||||
#include "AyonPublishInstance.h"
|
||||
|
||||
UAyonPublishInstanceFactory::UAyonPublishInstanceFactory(const FObjectInitializer& ObjectInitializer)
|
||||
: UFactory(ObjectInitializer)
|
||||
{
|
||||
SupportedClass = UAyonPublishInstance::StaticClass();
|
||||
bCreateNew = false;
|
||||
bEditorImport = true;
|
||||
}
|
||||
|
||||
UObject* UAyonPublishInstanceFactory::FactoryCreateNew(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn)
|
||||
{
|
||||
check(InClass->IsChildOf(UAyonPublishInstance::StaticClass()));
|
||||
return NewObject<UAyonPublishInstance>(InParent, InClass, InName, Flags);
|
||||
}
|
||||
|
||||
bool UAyonPublishInstanceFactory::ShouldShowInNewMenu() const {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#include "AyonPythonBridge.h"
|
||||
|
||||
UAyonPythonBridge* UAyonPythonBridge::Get()
|
||||
{
|
||||
TArray<UClass*> AyonPythonBridgeClasses;
|
||||
GetDerivedClasses(UAyonPythonBridge::StaticClass(), AyonPythonBridgeClasses);
|
||||
int32 NumClasses = AyonPythonBridgeClasses.Num();
|
||||
if (NumClasses > 0)
|
||||
{
|
||||
return Cast<UAyonPythonBridge>(AyonPythonBridgeClasses[NumClasses - 1]->GetDefaultObject());
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
#include "AyonSettings.h"
|
||||
|
||||
#include "Interfaces/IPluginManager.h"
|
||||
#include "UObject/UObjectGlobals.h"
|
||||
|
||||
/**
|
||||
* Mainly is used for initializing default values if the DefaultAyonSettings.ini file does not exist in the saved config
|
||||
*/
|
||||
UAyonSettings::UAyonSettings(const FObjectInitializer& ObjectInitializer)
|
||||
{
|
||||
|
||||
const FString ConfigFilePath = AYON_SETTINGS_FILEPATH;
|
||||
|
||||
// This has to be probably in the future set using the UE Reflection system
|
||||
FColor Color;
|
||||
GConfig->GetColor(TEXT("/Script/Ayon.AyonSettings"), TEXT("FolderColor"), Color, ConfigFilePath);
|
||||
|
||||
FolderColor = Color;
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
#include "AyonStyle.h"
|
||||
#include "Framework/Application/SlateApplication.h"
|
||||
#include "Styling/SlateStyleRegistry.h"
|
||||
#include "Slate/SlateGameResources.h"
|
||||
#include "Interfaces/IPluginManager.h"
|
||||
#include "Styling/SlateStyleMacros.h"
|
||||
|
||||
#define RootToContentDir Style->RootToContentDir
|
||||
|
||||
TSharedPtr<FSlateStyleSet> FAyonStyle::AyonStyleInstance = nullptr;
|
||||
|
||||
void FAyonStyle::Initialize()
|
||||
{
|
||||
if (!AyonStyleInstance.IsValid())
|
||||
{
|
||||
AyonStyleInstance = Create();
|
||||
FSlateStyleRegistry::RegisterSlateStyle(*AyonStyleInstance);
|
||||
}
|
||||
}
|
||||
|
||||
void FAyonStyle::Shutdown()
|
||||
{
|
||||
FSlateStyleRegistry::UnRegisterSlateStyle(*AyonStyleInstance);
|
||||
ensure(AyonStyleInstance.IsUnique());
|
||||
AyonStyleInstance.Reset();
|
||||
}
|
||||
|
||||
FName FAyonStyle::GetStyleSetName()
|
||||
{
|
||||
static FName StyleSetName(TEXT("AyonStyle"));
|
||||
return StyleSetName;
|
||||
}
|
||||
|
||||
const FVector2D Icon16x16(16.0f, 16.0f);
|
||||
const FVector2D Icon20x20(20.0f, 20.0f);
|
||||
const FVector2D Icon40x40(40.0f, 40.0f);
|
||||
|
||||
TSharedRef< FSlateStyleSet > FAyonStyle::Create()
|
||||
{
|
||||
TSharedRef< FSlateStyleSet > Style = MakeShareable(new FSlateStyleSet("AyonStyle"));
|
||||
Style->SetContentRoot(IPluginManager::Get().FindPlugin("Ayon")->GetBaseDir() / TEXT("Resources"));
|
||||
|
||||
Style->Set("Ayon.AyonTools", new IMAGE_BRUSH(TEXT("ayon40"), Icon40x40));
|
||||
Style->Set("Ayon.AyonToolsDialog", new IMAGE_BRUSH(TEXT("ayon40"), Icon40x40));
|
||||
|
||||
return Style;
|
||||
}
|
||||
|
||||
void FAyonStyle::ReloadTextures()
|
||||
{
|
||||
if (FSlateApplication::IsInitialized())
|
||||
{
|
||||
FSlateApplication::Get().GetRenderer()->ReloadTextureResources();
|
||||
}
|
||||
}
|
||||
|
||||
const ISlateStyle& FAyonStyle::Get()
|
||||
{
|
||||
return *AyonStyleInstance;
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
#include "Commandlets/AyonActionResult.h"
|
||||
#include "Logging/Ayon_Log.h"
|
||||
|
||||
EAyon_ActionResult::Type& FAyon_ActionResult::GetStatus()
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
FText& FAyon_ActionResult::GetReason()
|
||||
{
|
||||
return Reason;
|
||||
}
|
||||
|
||||
FAyon_ActionResult::FAyon_ActionResult():Status(EAyon_ActionResult::Type::Ok)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FAyon_ActionResult::FAyon_ActionResult(const EAyon_ActionResult::Type& InEnum):Status(InEnum)
|
||||
{
|
||||
TryLog();
|
||||
}
|
||||
|
||||
FAyon_ActionResult::FAyon_ActionResult(const EAyon_ActionResult::Type& InEnum, const FText& InReason):Status(InEnum), Reason(InReason)
|
||||
{
|
||||
TryLog();
|
||||
};
|
||||
|
||||
bool FAyon_ActionResult::IsProblem() const
|
||||
{
|
||||
return Status != EAyon_ActionResult::Ok;
|
||||
}
|
||||
|
||||
void FAyon_ActionResult::TryLog() const
|
||||
{
|
||||
if(IsProblem())
|
||||
UE_LOG(LogCommandletAyonGenerateProject, Error, TEXT("%s"), *Reason.ToString());
|
||||
}
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#include "Commandlets/Implementations/AyonGenerateProjectCommandlet.h"
|
||||
|
||||
#include "GameProjectUtils.h"
|
||||
#include "AyonConstants.h"
|
||||
#include "Commandlets/AyonActionResult.h"
|
||||
#include "ProjectDescriptor.h"
|
||||
|
||||
int32 UAyonGenerateProjectCommandlet::Main(const FString& CommandLineParams)
|
||||
{
|
||||
//Parses command line parameters & creates structure FProjectInformation
|
||||
const FAyonGenerateProjectParams ParsedParams = FAyonGenerateProjectParams(CommandLineParams);
|
||||
ProjectInformation = ParsedParams.GenerateUEProjectInformation();
|
||||
|
||||
//Creates .uproject & other UE files
|
||||
EVALUATE_Ayon_ACTION_RESULT(TryCreateProject());
|
||||
|
||||
//Loads created .uproject
|
||||
EVALUATE_Ayon_ACTION_RESULT(TryLoadProjectDescriptor());
|
||||
|
||||
//Adds needed plugin to .uproject
|
||||
AttachPluginsToProjectDescriptor();
|
||||
|
||||
//Saves .uproject
|
||||
EVALUATE_Ayon_ACTION_RESULT(TrySave());
|
||||
|
||||
//When we are here, there should not be problems in generating Unreal Project for Ayon
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FAyonGenerateProjectParams::FAyonGenerateProjectParams(): FAyonGenerateProjectParams("")
|
||||
{
|
||||
}
|
||||
|
||||
FAyonGenerateProjectParams::FAyonGenerateProjectParams(const FString& CommandLineParams): CommandLineParams(
|
||||
CommandLineParams)
|
||||
{
|
||||
UCommandlet::ParseCommandLine(*CommandLineParams, Tokens, Switches);
|
||||
}
|
||||
|
||||
FProjectInformation FAyonGenerateProjectParams::GenerateUEProjectInformation() const
|
||||
{
|
||||
FProjectInformation ProjectInformation = FProjectInformation();
|
||||
ProjectInformation.ProjectFilename = GetProjectFileName();
|
||||
|
||||
ProjectInformation.bShouldGenerateCode = IsSwitchPresent("GenerateCode");
|
||||
|
||||
return ProjectInformation;
|
||||
}
|
||||
|
||||
FString FAyonGenerateProjectParams::TryGetToken(const int32 Index) const
|
||||
{
|
||||
return Tokens.IsValidIndex(Index) ? Tokens[Index] : "";
|
||||
}
|
||||
|
||||
FString FAyonGenerateProjectParams::GetProjectFileName() const
|
||||
{
|
||||
return TryGetToken(0);
|
||||
}
|
||||
|
||||
bool FAyonGenerateProjectParams::IsSwitchPresent(const FString& Switch) const
|
||||
{
|
||||
return INDEX_NONE != Switches.IndexOfByPredicate([&Switch](const FString& Item) -> bool
|
||||
{
|
||||
return Item.Equals(Switch);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
UAyonGenerateProjectCommandlet::UAyonGenerateProjectCommandlet()
|
||||
{
|
||||
LogToConsole = true;
|
||||
}
|
||||
|
||||
FAyon_ActionResult UAyonGenerateProjectCommandlet::TryCreateProject() const
|
||||
{
|
||||
FText FailReason;
|
||||
FText FailLog;
|
||||
TArray<FString> OutCreatedFiles;
|
||||
|
||||
if (!GameProjectUtils::CreateProject(ProjectInformation, FailReason, FailLog, &OutCreatedFiles))
|
||||
return FAyon_ActionResult(EAyon_ActionResult::ProjectNotCreated, FailReason);
|
||||
return FAyon_ActionResult();
|
||||
}
|
||||
|
||||
FAyon_ActionResult UAyonGenerateProjectCommandlet::TryLoadProjectDescriptor()
|
||||
{
|
||||
FText FailReason;
|
||||
const bool bLoaded = ProjectDescriptor.Load(ProjectInformation.ProjectFilename, FailReason);
|
||||
|
||||
return FAyon_ActionResult(bLoaded ? EAyon_ActionResult::Ok : EAyon_ActionResult::ProjectNotLoaded, FailReason);
|
||||
}
|
||||
|
||||
void UAyonGenerateProjectCommandlet::AttachPluginsToProjectDescriptor()
|
||||
{
|
||||
FPluginReferenceDescriptor AyonPluginDescriptor;
|
||||
AyonPluginDescriptor.bEnabled = true;
|
||||
AyonPluginDescriptor.Name = AyonConstants::Ayon_PluginName;
|
||||
ProjectDescriptor.Plugins.Add(AyonPluginDescriptor);
|
||||
|
||||
FPluginReferenceDescriptor PythonPluginDescriptor;
|
||||
PythonPluginDescriptor.bEnabled = true;
|
||||
PythonPluginDescriptor.Name = AyonConstants::PythonScript_PluginName;
|
||||
ProjectDescriptor.Plugins.Add(PythonPluginDescriptor);
|
||||
|
||||
FPluginReferenceDescriptor SequencerScriptingPluginDescriptor;
|
||||
SequencerScriptingPluginDescriptor.bEnabled = true;
|
||||
SequencerScriptingPluginDescriptor.Name = AyonConstants::SequencerScripting_PluginName;
|
||||
ProjectDescriptor.Plugins.Add(SequencerScriptingPluginDescriptor);
|
||||
|
||||
FPluginReferenceDescriptor MovieRenderPipelinePluginDescriptor;
|
||||
MovieRenderPipelinePluginDescriptor.bEnabled = true;
|
||||
MovieRenderPipelinePluginDescriptor.Name = AyonConstants::MovieRenderPipeline_PluginName;
|
||||
ProjectDescriptor.Plugins.Add(MovieRenderPipelinePluginDescriptor);
|
||||
|
||||
FPluginReferenceDescriptor EditorScriptingPluginDescriptor;
|
||||
EditorScriptingPluginDescriptor.bEnabled = true;
|
||||
EditorScriptingPluginDescriptor.Name = AyonConstants::EditorScriptingUtils_PluginName;
|
||||
ProjectDescriptor.Plugins.Add(EditorScriptingPluginDescriptor);
|
||||
}
|
||||
|
||||
FAyon_ActionResult UAyonGenerateProjectCommandlet::TrySave()
|
||||
{
|
||||
FText FailReason;
|
||||
const bool bSaved = ProjectDescriptor.Save(ProjectInformation.ProjectFilename, FailReason);
|
||||
|
||||
return FAyon_ActionResult(bSaved ? EAyon_ActionResult::Ok : EAyon_ActionResult::ProjectNotSaved, FailReason);
|
||||
}
|
||||
|
||||
FAyonGenerateProjectParams UAyonGenerateProjectCommandlet::ParseParameters(const FString& Params) const
|
||||
{
|
||||
FAyonGenerateProjectParams ParamsResult;
|
||||
|
||||
TArray<FString> Tokens, Switches;
|
||||
ParseCommandLine(*Params, Tokens, Switches);
|
||||
|
||||
return ParamsResult;
|
||||
}
|
||||
|
|
@ -1,204 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
// Deprecation warning: this is left here just for backwards compatibility
|
||||
// and will be removed in next versions of Ayon.
|
||||
#pragma once
|
||||
|
||||
#include "OpenPypePublishInstance.h"
|
||||
#include "AssetRegistry/AssetRegistryModule.h"
|
||||
#include "AssetToolsModule.h"
|
||||
#include "Framework/Notifications/NotificationManager.h"
|
||||
#include "AyonLib.h"
|
||||
#include "AyonSettings.h"
|
||||
#include "Widgets/Notifications/SNotificationList.h"
|
||||
|
||||
|
||||
//Moves all the invalid pointers to the end to prepare them for the shrinking
|
||||
#define REMOVE_INVALID_ENTRIES(VAR) VAR.CompactStable(); \
|
||||
VAR.Shrink();
|
||||
|
||||
UOpenPypePublishInstance::UOpenPypePublishInstance(const FObjectInitializer& ObjectInitializer)
|
||||
: UPrimaryDataAsset(ObjectInitializer)
|
||||
{
|
||||
const FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<
|
||||
FAssetRegistryModule>("AssetRegistry");
|
||||
|
||||
const FPropertyEditorModule& PropertyEditorModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>(
|
||||
"PropertyEditor");
|
||||
|
||||
FString Left, Right;
|
||||
GetPathName().Split("/" + GetName(), &Left, &Right);
|
||||
|
||||
FARFilter Filter;
|
||||
Filter.PackagePaths.Emplace(FName(Left));
|
||||
|
||||
TArray<FAssetData> FoundAssets;
|
||||
AssetRegistryModule.GetRegistry().GetAssets(Filter, FoundAssets);
|
||||
|
||||
for (const FAssetData& AssetData : FoundAssets)
|
||||
OnAssetCreated(AssetData);
|
||||
|
||||
REMOVE_INVALID_ENTRIES(AssetDataInternal)
|
||||
REMOVE_INVALID_ENTRIES(AssetDataExternal)
|
||||
|
||||
AssetRegistryModule.Get().OnAssetAdded().AddUObject(this, &UOpenPypePublishInstance::OnAssetCreated);
|
||||
AssetRegistryModule.Get().OnAssetRemoved().AddUObject(this, &UOpenPypePublishInstance::OnAssetRemoved);
|
||||
AssetRegistryModule.Get().OnAssetUpdated().AddUObject(this, &UOpenPypePublishInstance::OnAssetUpdated);
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
ColorOpenPypeDirs();
|
||||
#endif
|
||||
}
|
||||
|
||||
void UOpenPypePublishInstance::OnAssetCreated(const FAssetData& InAssetData)
|
||||
{
|
||||
TArray<FString> split;
|
||||
|
||||
UObject* Asset = InAssetData.GetAsset();
|
||||
|
||||
if (!IsValid(Asset))
|
||||
{
|
||||
UE_LOG(LogAssetData, Warning, TEXT("Asset \"%s\" is not valid! Skipping the addition."),
|
||||
*InAssetData.ObjectPath.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
const bool result = IsUnderSameDir(Asset) && Cast<UOpenPypePublishInstance>(Asset) == nullptr;
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (AssetDataInternal.Emplace(Asset).IsValidId())
|
||||
{
|
||||
UE_LOG(LogTemp, Log, TEXT("Added an Asset to PublishInstance - Publish Instance: %s, Asset %s"),
|
||||
*this->GetName(), *Asset->GetName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UOpenPypePublishInstance::OnAssetRemoved(const FAssetData& InAssetData)
|
||||
{
|
||||
if (Cast<UOpenPypePublishInstance>(InAssetData.GetAsset()) == nullptr)
|
||||
{
|
||||
if (AssetDataInternal.Contains(nullptr))
|
||||
{
|
||||
AssetDataInternal.Remove(nullptr);
|
||||
REMOVE_INVALID_ENTRIES(AssetDataInternal)
|
||||
}
|
||||
else
|
||||
{
|
||||
AssetDataExternal.Remove(nullptr);
|
||||
REMOVE_INVALID_ENTRIES(AssetDataExternal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UOpenPypePublishInstance::OnAssetUpdated(const FAssetData& InAssetData)
|
||||
{
|
||||
REMOVE_INVALID_ENTRIES(AssetDataInternal);
|
||||
REMOVE_INVALID_ENTRIES(AssetDataExternal);
|
||||
}
|
||||
|
||||
bool UOpenPypePublishInstance::IsUnderSameDir(const UObject* InAsset) const
|
||||
{
|
||||
FString ThisLeft, ThisRight;
|
||||
this->GetPathName().Split(this->GetName(), &ThisLeft, &ThisRight);
|
||||
|
||||
return InAsset->GetPathName().StartsWith(ThisLeft);
|
||||
}
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
|
||||
void UOpenPypePublishInstance::ColorOpenPypeDirs()
|
||||
{
|
||||
FString PathName = this->GetPathName();
|
||||
|
||||
//Check whether the path contains the defined OpenPype folder
|
||||
if (!PathName.Contains(TEXT("OpenPype"))) return;
|
||||
|
||||
//Get the base path for open pype
|
||||
FString PathLeft, PathRight;
|
||||
PathName.Split(FString("OpenPype"), &PathLeft, &PathRight);
|
||||
|
||||
if (PathLeft.IsEmpty() || PathRight.IsEmpty())
|
||||
{
|
||||
UE_LOG(LogAssetData, Error, TEXT("Failed to retrieve the base OpenPype directory!"))
|
||||
return;
|
||||
}
|
||||
|
||||
PathName.RemoveFromEnd(PathRight, ESearchCase::CaseSensitive);
|
||||
|
||||
//Get the current settings
|
||||
const UAyonSettings* Settings = GetMutableDefault<UAyonSettings>();
|
||||
|
||||
//Color the base folder
|
||||
UAyonLib::SetFolderColor(PathName, Settings->GetFolderFColor(), false);
|
||||
|
||||
//Get Sub paths, iterate through them and color them according to the folder color in UOpenPypeSettings
|
||||
const FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(
|
||||
"AssetRegistry");
|
||||
|
||||
TArray<FString> PathList;
|
||||
|
||||
AssetRegistryModule.Get().GetSubPaths(PathName, PathList, true);
|
||||
|
||||
if (PathList.Num() > 0)
|
||||
{
|
||||
for (const FString& Path : PathList)
|
||||
{
|
||||
UAyonLib::SetFolderColor(Path, Settings->GetFolderFColor(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UOpenPypePublishInstance::SendNotification(const FString& Text) const
|
||||
{
|
||||
FNotificationInfo Info{FText::FromString(Text)};
|
||||
|
||||
Info.bFireAndForget = true;
|
||||
Info.bUseLargeFont = false;
|
||||
Info.bUseThrobber = false;
|
||||
Info.bUseSuccessFailIcons = false;
|
||||
Info.ExpireDuration = 4.f;
|
||||
Info.FadeOutDuration = 2.f;
|
||||
|
||||
FSlateNotificationManager::Get().AddNotification(Info);
|
||||
|
||||
UE_LOG(LogAssetData, Warning,
|
||||
TEXT(
|
||||
"Removed duplicated asset from the AssetsDataExternal in Container \"%s\", Asset is already included in the AssetDataInternal!"
|
||||
), *GetName()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
void UOpenPypePublishInstance::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
||||
{
|
||||
Super::PostEditChangeProperty(PropertyChangedEvent);
|
||||
|
||||
if (PropertyChangedEvent.ChangeType == EPropertyChangeType::ValueSet &&
|
||||
PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(
|
||||
UOpenPypePublishInstance, AssetDataExternal))
|
||||
{
|
||||
// Check for duplicated assets
|
||||
for (const auto& Asset : AssetDataInternal)
|
||||
{
|
||||
if (AssetDataExternal.Contains(Asset))
|
||||
{
|
||||
AssetDataExternal.Remove(Asset);
|
||||
return SendNotification(
|
||||
"You are not allowed to add assets into AssetDataExternal which are already included in AssetDataInternal!");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if no UOpenPypePublishInstance type assets are included
|
||||
for (const auto& Asset : AssetDataExternal)
|
||||
{
|
||||
if (Cast<UOpenPypePublishInstance>(Asset.Get()) != nullptr)
|
||||
{
|
||||
AssetDataExternal.Remove(Asset);
|
||||
return SendNotification("You are not allowed to add publish instances!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
|
||||
class FAyonModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
|
||||
private:
|
||||
void RegisterMenus();
|
||||
void RegisterSettings();
|
||||
bool HandleSettingsSaved();
|
||||
|
||||
void MenuPopup();
|
||||
void MenuDialog();
|
||||
|
||||
private:
|
||||
TSharedPtr<class FUICommandList> PluginCommands;
|
||||
};
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/NoExportTypes.h"
|
||||
#include "Engine/AssetUserData.h"
|
||||
#include "AssetRegistry/AssetData.h"
|
||||
#include "AyonAssetContainer.generated.h"
|
||||
|
||||
UCLASS(Blueprintable)
|
||||
class AYON_API UAyonAssetContainer : public UAssetUserData
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UAyonAssetContainer(const FObjectInitializer& ObjectInitalizer);
|
||||
// ~UAyonAssetContainer();
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Assets")
|
||||
TArray<FString> assets;
|
||||
|
||||
// There seems to be no reflection option to expose array of FAssetData
|
||||
/*
|
||||
UPROPERTY(Transient, BlueprintReadOnly, Category = "Python", meta=(DisplayName="Assets Data"))
|
||||
TArray<FAssetData> assetsData;
|
||||
*/
|
||||
private:
|
||||
TArray<FAssetData> assetsData;
|
||||
void OnAssetAdded(const FAssetData& AssetData);
|
||||
void OnAssetRemoved(const FAssetData& AssetData);
|
||||
void OnAssetRenamed(const FAssetData& AssetData, const FString& str);
|
||||
};
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Factories/Factory.h"
|
||||
#include "AyonAssetContainerFactory.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class AYON_API UAyonAssetContainerFactory : public UFactory
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UAyonAssetContainerFactory(const FObjectInitializer& ObjectInitializer);
|
||||
virtual UObject* FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override;
|
||||
virtual bool ShouldShowInNewMenu() const override;
|
||||
};
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Framework/Commands/Commands.h"
|
||||
#include "AyonStyle.h"
|
||||
|
||||
class FAyonCommands : public TCommands<FAyonCommands>
|
||||
{
|
||||
public:
|
||||
|
||||
FAyonCommands()
|
||||
: TCommands<FAyonCommands>(TEXT("Ayon"), NSLOCTEXT("Contexts", "Ayon", "Ayon Tools"), NAME_None, FAyonStyle::GetStyleSetName())
|
||||
{
|
||||
}
|
||||
|
||||
// TCommands<> interface
|
||||
virtual void RegisterCommands() override;
|
||||
|
||||
public:
|
||||
TSharedPtr< FUICommandInfo > AyonTools;
|
||||
TSharedPtr< FUICommandInfo > AyonToolsDialog;
|
||||
};
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#pragma once
|
||||
|
||||
namespace AyonConstants
|
||||
{
|
||||
const FString Ayon_PluginName = "Ayon";
|
||||
const FString PythonScript_PluginName = "PythonScriptPlugin";
|
||||
const FString SequencerScripting_PluginName = "SequencerScripting";
|
||||
const FString MovieRenderPipeline_PluginName = "MovieRenderPipeline";
|
||||
const FString EditorScriptingUtils_PluginName = "EditorScriptingUtilities";
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#pragma once
|
||||
|
||||
#include "AyonLib.generated.h"
|
||||
|
||||
|
||||
UCLASS(Blueprintable)
|
||||
class AYON_API UAyonLib : public UBlueprintFunctionLibrary
|
||||
{
|
||||
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, Category = Python)
|
||||
static bool SetFolderColor(const FString& FolderPath, const FLinearColor& FolderColor,const bool& bForceAdd);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = Python)
|
||||
static TArray<FString> GetAllProperties(UClass* cls);
|
||||
};
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
// Deprecation warning: this is left here just for backwards compatibility
|
||||
// and will be removed in next versions of Ayon.
|
||||
#pragma once
|
||||
|
||||
#include "AyonPublishInstance.generated.h"
|
||||
|
||||
|
||||
UCLASS(Blueprintable)
|
||||
class AYON_API UAyonPublishInstance : public UPrimaryDataAsset
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
public:
|
||||
/**
|
||||
/**
|
||||
* Retrieves all the assets which are monitored by the Publish Instance (Monitors assets in the directory which is
|
||||
* placed in)
|
||||
*
|
||||
* @return - Set of UObjects. Careful! They are returning raw pointers. Seems like an issue in UE5
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Python")
|
||||
TSet<UObject*> GetInternalAssets() const
|
||||
{
|
||||
//For some reason it can only return Raw Pointers? Seems like an issue which they haven't fixed.
|
||||
TSet<UObject*> ResultSet;
|
||||
|
||||
for (const auto& Asset : AssetDataInternal)
|
||||
ResultSet.Add(Asset.LoadSynchronous());
|
||||
|
||||
return ResultSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all the assets which have been added manually by the Publish Instance
|
||||
*
|
||||
* @return - TSet of assets (UObjects). Careful! They are returning raw pointers. Seems like an issue in UE5
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Python")
|
||||
TSet<UObject*> GetExternalAssets() const
|
||||
{
|
||||
//For some reason it can only return Raw Pointers? Seems like an issue which they haven't fixed.
|
||||
TSet<UObject*> ResultSet;
|
||||
|
||||
for (const auto& Asset : AssetDataExternal)
|
||||
ResultSet.Add(Asset.LoadSynchronous());
|
||||
|
||||
return ResultSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for returning all the assets in the container combined.
|
||||
*
|
||||
* @return Returns all the internal and externally added assets into one set (TSet of UObjects). Careful! They are
|
||||
* returning raw pointers. Seems like an issue in UE5
|
||||
*
|
||||
* @attention If the bAddExternalAssets variable is false, external assets won't be included!
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Python")
|
||||
TSet<UObject*> GetAllAssets() const
|
||||
{
|
||||
const TSet<TSoftObjectPtr<UObject>>& IteratedSet = bAddExternalAssets
|
||||
? AssetDataInternal.Union(AssetDataExternal)
|
||||
: AssetDataInternal;
|
||||
|
||||
//Create a new TSet only with raw pointers.
|
||||
TSet<UObject*> ResultSet;
|
||||
|
||||
for (auto& Asset : IteratedSet)
|
||||
ResultSet.Add(Asset.LoadSynchronous());
|
||||
|
||||
return ResultSet;
|
||||
}
|
||||
|
||||
private:
|
||||
UPROPERTY(VisibleAnywhere, Category="Assets")
|
||||
TSet<TSoftObjectPtr<UObject>> AssetDataInternal;
|
||||
|
||||
/**
|
||||
* This property allows exposing the array to include other assets from any other directory than what it's currently
|
||||
* monitoring. NOTE: that these assets have to be added manually! They are not automatically registered or added!
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, Category = "Assets")
|
||||
bool bAddExternalAssets = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, meta=(EditCondition="bAddExternalAssets"), Category="Assets")
|
||||
TSet<TSoftObjectPtr<UObject>> AssetDataExternal;
|
||||
|
||||
|
||||
void OnAssetCreated(const FAssetData& InAssetData);
|
||||
void OnAssetRemoved(const FAssetData& InAssetData);
|
||||
void OnAssetUpdated(const FAssetData& InAssetData);
|
||||
|
||||
bool IsUnderSameDir(const UObject* InAsset) const;
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
|
||||
void ColorAyonDirs();
|
||||
|
||||
void SendNotification(const FString& Text) const;
|
||||
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
// Deprecation warning: this is left here just for backwards compatibility
|
||||
// and will be removed in next versions of Ayon.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Factories/Factory.h"
|
||||
#include "AyonPublishInstanceFactory.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class AYON_API UAyonPublishInstanceFactory : public UFactory
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UAyonPublishInstanceFactory(const FObjectInitializer& ObjectInitializer);
|
||||
virtual UObject* FactoryCreateNew(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override;
|
||||
virtual bool ShouldShowInNewMenu() const override;
|
||||
};
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#pragma once
|
||||
#include "AyonPythonBridge.generated.h"
|
||||
|
||||
UCLASS(Blueprintable)
|
||||
class UAyonPythonBridge : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, Category = Python)
|
||||
static UAyonPythonBridge* Get();
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = Python)
|
||||
void RunInPython_Popup() const;
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = Python)
|
||||
void RunInPython_Dialog() const;
|
||||
|
||||
};
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "AyonSettings.generated.h"
|
||||
|
||||
#define AYON_SETTINGS_FILEPATH IPluginManager::Get().FindPlugin("Ayon")->GetBaseDir() / TEXT("Config") / TEXT("DefaultAyonSettings.ini")
|
||||
|
||||
UCLASS(Config=AyonSettings, DefaultConfig)
|
||||
class AYON_API UAyonSettings : public UObject
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = Settings)
|
||||
FColor GetFolderFColor() const
|
||||
{
|
||||
return FolderColor;
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = Settings)
|
||||
FLinearColor GetFolderFLinearColor() const
|
||||
{
|
||||
return FLinearColor(FolderColor);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
UPROPERTY(config, EditAnywhere, Category = Folders)
|
||||
FColor FolderColor = FColor(25,45,223);
|
||||
};
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#pragma once
|
||||
#include "CoreMinimal.h"
|
||||
#include "Styling/SlateStyle.h"
|
||||
|
||||
class FAyonStyle
|
||||
{
|
||||
public:
|
||||
static void Initialize();
|
||||
static void Shutdown();
|
||||
static void ReloadTextures();
|
||||
static const ISlateStyle& Get();
|
||||
static FName GetStyleSetName();
|
||||
|
||||
|
||||
private:
|
||||
static TSharedRef< class FSlateStyleSet > Create();
|
||||
static TSharedPtr< class FSlateStyleSet > AyonStyleInstance;
|
||||
};
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "AyonActionResult.generated.h"
|
||||
|
||||
/**
|
||||
* @brief This macro returns error code when is problem or does nothing when there is no problem.
|
||||
* @param ActionResult FAyon_ActionResult structure
|
||||
*/
|
||||
#define EVALUATE_Ayon_ACTION_RESULT(ActionResult) \
|
||||
if(ActionResult.IsProblem()) \
|
||||
return ActionResult.GetStatus();
|
||||
|
||||
/**
|
||||
* @brief This enum values are humanly readable mapping of error codes.
|
||||
* Here should be all error codes to be possible find what went wrong.
|
||||
* TODO: In the future should exists an web document where is mapped error code & what problem occured & how to repair it...
|
||||
*/
|
||||
UENUM()
|
||||
namespace EAyon_ActionResult
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Ok,
|
||||
ProjectNotCreated,
|
||||
ProjectNotLoaded,
|
||||
ProjectNotSaved,
|
||||
//....Here insert another values
|
||||
|
||||
//Do not remove!
|
||||
//Usable for looping through enum values
|
||||
__Last UMETA(Hidden)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief This struct holds action result enum and optionally reason of fail
|
||||
*/
|
||||
USTRUCT()
|
||||
struct FAyon_ActionResult
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/** @brief Default constructor usable when there is no problem */
|
||||
FAyon_ActionResult();
|
||||
|
||||
/**
|
||||
* @brief This constructor initializes variables & attempts to log when is error
|
||||
* @param InEnum Status
|
||||
*/
|
||||
FAyon_ActionResult(const EAyon_ActionResult::Type& InEnum);
|
||||
|
||||
/**
|
||||
* @brief This constructor initializes variables & attempts to log when is error
|
||||
* @param InEnum Status
|
||||
* @param InReason Reason of potential fail
|
||||
*/
|
||||
FAyon_ActionResult(const EAyon_ActionResult::Type& InEnum, const FText& InReason);
|
||||
|
||||
private:
|
||||
/** @brief Action status */
|
||||
EAyon_ActionResult::Type Status;
|
||||
|
||||
/** @brief Optional reason of fail */
|
||||
FText Reason;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Checks if there is problematic state
|
||||
* @return true when status is not equal to EAyon_ActionResult::Ok
|
||||
*/
|
||||
bool IsProblem() const;
|
||||
EAyon_ActionResult::Type& GetStatus();
|
||||
FText& GetReason();
|
||||
|
||||
private:
|
||||
void TryLog() const;
|
||||
};
|
||||
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "GameProjectUtils.h"
|
||||
#include "Commandlets/AyonActionResult.h"
|
||||
#include "ProjectDescriptor.h"
|
||||
#include "Commandlets/Commandlet.h"
|
||||
#include "AyonGenerateProjectCommandlet.generated.h"
|
||||
|
||||
struct FProjectDescriptor;
|
||||
struct FProjectInformation;
|
||||
|
||||
/**
|
||||
* @brief Structure which parses command line parameters and generates FProjectInformation
|
||||
*/
|
||||
USTRUCT()
|
||||
struct FAyonGenerateProjectParams
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
private:
|
||||
FString CommandLineParams;
|
||||
TArray<FString> Tokens;
|
||||
TArray<FString> Switches;
|
||||
|
||||
public:
|
||||
FAyonGenerateProjectParams();
|
||||
FAyonGenerateProjectParams(const FString& CommandLineParams);
|
||||
|
||||
FProjectInformation GenerateUEProjectInformation() const;
|
||||
|
||||
private:
|
||||
FString TryGetToken(const int32 Index) const;
|
||||
FString GetProjectFileName() const;
|
||||
|
||||
bool IsSwitchPresent(const FString& Switch) const;
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
class AYON_API UAyonGenerateProjectCommandlet : public UCommandlet
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
private:
|
||||
FProjectInformation ProjectInformation;
|
||||
FProjectDescriptor ProjectDescriptor;
|
||||
|
||||
public:
|
||||
UAyonGenerateProjectCommandlet();
|
||||
|
||||
virtual int32 Main(const FString& CommandLineParams) override;
|
||||
|
||||
private:
|
||||
FAyonGenerateProjectParams ParseParameters(const FString& Params) const;
|
||||
FAyon_ActionResult TryCreateProject() const;
|
||||
FAyon_ActionResult TryLoadProjectDescriptor();
|
||||
void AttachPluginsToProjectDescriptor();
|
||||
FAyon_ActionResult TrySave();
|
||||
};
|
||||
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#pragma once
|
||||
|
||||
DEFINE_LOG_CATEGORY_STATIC(LogCommandletAyonGenerateProject, Log, All);
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
// Deprecation warning: this is left here just for backwards compatibility
|
||||
// and will be removed in next versions of Ayon.
|
||||
#pragma once
|
||||
|
||||
#include "OpenPypePublishInstance.generated.h"
|
||||
|
||||
|
||||
UCLASS(Blueprintable)
|
||||
class AYON_API UOpenPypePublishInstance : public UPrimaryDataAsset
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
public:
|
||||
/**
|
||||
/**
|
||||
* Retrieves all the assets which are monitored by the Publish Instance (Monitors assets in the directory which is
|
||||
* placed in)
|
||||
*
|
||||
* @return - Set of UObjects. Careful! They are returning raw pointers. Seems like an issue in UE5
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Python")
|
||||
TSet<UObject*> GetInternalAssets() const
|
||||
{
|
||||
//For some reason it can only return Raw Pointers? Seems like an issue which they haven't fixed.
|
||||
TSet<UObject*> ResultSet;
|
||||
|
||||
for (const auto& Asset : AssetDataInternal)
|
||||
ResultSet.Add(Asset.LoadSynchronous());
|
||||
|
||||
return ResultSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all the assets which have been added manually by the Publish Instance
|
||||
*
|
||||
* @return - TSet of assets (UObjects). Careful! They are returning raw pointers. Seems like an issue in UE5
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Python")
|
||||
TSet<UObject*> GetExternalAssets() const
|
||||
{
|
||||
//For some reason it can only return Raw Pointers? Seems like an issue which they haven't fixed.
|
||||
TSet<UObject*> ResultSet;
|
||||
|
||||
for (const auto& Asset : AssetDataExternal)
|
||||
ResultSet.Add(Asset.LoadSynchronous());
|
||||
|
||||
return ResultSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for returning all the assets in the container combined.
|
||||
*
|
||||
* @return Returns all the internal and externally added assets into one set (TSet of UObjects). Careful! They are
|
||||
* returning raw pointers. Seems like an issue in UE5
|
||||
*
|
||||
* @attention If the bAddExternalAssets variable is false, external assets won't be included!
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Python")
|
||||
TSet<UObject*> GetAllAssets() const
|
||||
{
|
||||
const TSet<TSoftObjectPtr<UObject>>& IteratedSet = bAddExternalAssets
|
||||
? AssetDataInternal.Union(AssetDataExternal)
|
||||
: AssetDataInternal;
|
||||
|
||||
//Create a new TSet only with raw pointers.
|
||||
TSet<UObject*> ResultSet;
|
||||
|
||||
for (auto& Asset : IteratedSet)
|
||||
ResultSet.Add(Asset.LoadSynchronous());
|
||||
|
||||
return ResultSet;
|
||||
}
|
||||
|
||||
private:
|
||||
UPROPERTY(VisibleAnywhere, Category="Assets")
|
||||
TSet<TSoftObjectPtr<UObject>> AssetDataInternal;
|
||||
|
||||
/**
|
||||
* This property allows exposing the array to include other assets from any other directory than what it's currently
|
||||
* monitoring. NOTE: that these assets have to be added manually! They are not automatically registered or added!
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, Category = "Assets")
|
||||
bool bAddExternalAssets = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, meta=(EditCondition="bAddExternalAssets"), Category="Assets")
|
||||
TSet<TSoftObjectPtr<UObject>> AssetDataExternal;
|
||||
|
||||
|
||||
void OnAssetCreated(const FAssetData& InAssetData);
|
||||
void OnAssetRemoved(const FAssetData& InAssetData);
|
||||
void OnAssetUpdated(const FAssetData& InAssetData);
|
||||
|
||||
bool IsUnderSameDir(const UObject* InAsset) const;
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
|
||||
void ColorOpenPypeDirs();
|
||||
|
||||
void SendNotification(const FString& Text) const;
|
||||
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
|
@ -1 +0,0 @@
|
|||
"C:\Program Files\Epic Games\UE_5.0\Engine\Build\BatchFiles\RunUAT.bat" BuildPlugin -plugin="D:\OpenPype\openpype\hosts\unreal\integration\UE_5.0\Ayon\Ayon.uplugin" -Package="D:\BuiltPlugins\5.0"
|
||||
|
|
@ -1 +0,0 @@
|
|||
cmd /k "BuildPlugin_5-0.bat"
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
/Saved
|
||||
/DerivedDataCache
|
||||
/Intermediate
|
||||
/Binaries
|
||||
/Content
|
||||
/Config
|
||||
/.idea
|
||||
/.vs
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
{
|
||||
"FileVersion": 3,
|
||||
"EngineAssociation": "5.0",
|
||||
"Category": "",
|
||||
"Description": "",
|
||||
"Plugins": [
|
||||
{
|
||||
"Name": "ModelingToolsEditorMode",
|
||||
"Enabled": true,
|
||||
"TargetAllowList": [
|
||||
"Editor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "Ayon",
|
||||
"Enabled": true,
|
||||
"Type": "Editor"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
/Binaries
|
||||
/Intermediate
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
{
|
||||
"FileVersion": 3,
|
||||
"Version": 1,
|
||||
"VersionName": "1.0",
|
||||
"FriendlyName": "Ayon",
|
||||
"Description": "Ayon Integration",
|
||||
"Category": "Ayon.Integration",
|
||||
"CreatedBy": "Ondrej Samohel",
|
||||
"CreatedByURL": "https://ayon.ynput.io",
|
||||
"DocsURL": "https://ayon.ynput.io/docs/artist_hosts_unreal",
|
||||
"MarketplaceURL": "",
|
||||
"SupportURL": "https://ynput.io/",
|
||||
"CanContainContent": true,
|
||||
"EngineVersion": "5.0",
|
||||
"IsExperimentalVersion": false,
|
||||
"Installed": true,
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "Ayon",
|
||||
"Type": "Editor",
|
||||
"LoadingPhase": "Default"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[/Script/Ayon.AyonSettings]
|
||||
FolderColor=(R=91,G=197,B=220,A=255)
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
[FilterPlugin]
|
||||
; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and
|
||||
; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively.
|
||||
;
|
||||
; Examples:
|
||||
; /README.txt
|
||||
; /Extras/...
|
||||
; /Binaries/ThirdParty/*.dll
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
import unreal
|
||||
|
||||
ayon_detected = True
|
||||
try:
|
||||
from openpype.pipeline import install_host
|
||||
from openpype.hosts.unreal.api import UnrealHost
|
||||
|
||||
ayon_host = UnrealHost()
|
||||
except ImportError as exc:
|
||||
ayon_host = None
|
||||
ayon_detected = False
|
||||
unreal.log_error(f"Ayon: cannot load Ayon integration [ {exc} ]")
|
||||
|
||||
if ayon_detected:
|
||||
install_host(ayon_host)
|
||||
|
||||
|
||||
@unreal.uclass()
|
||||
class AyonIntegration(unreal.AyonPythonBridge):
|
||||
@unreal.ufunction(override=True)
|
||||
def RunInPython_Popup(self):
|
||||
unreal.log_warning("Ayon: showing tools popup")
|
||||
if ayon_detected:
|
||||
ayon_host.show_tools_popup()
|
||||
|
||||
@unreal.ufunction(override=True)
|
||||
def RunInPython_Dialog(self):
|
||||
unreal.log_warning("Ayon: showing tools dialog")
|
||||
if ayon_detected:
|
||||
ayon_host.show_tools_dialog()
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
# Ayon Unreal Integration plugin - UE 5.1
|
||||
|
||||
This is plugin for Unreal Editor, creating menu for [Ayon](https://github.com/ynput/OpenPype) tools to run.
|
||||
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 721 B |
|
Before Width: | Height: | Size: 16 KiB |
|
|
@ -1,65 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class Ayon : ModuleRules
|
||||
{
|
||||
public Ayon(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
DefaultBuildSettings = BuildSettingsVersion.V2;
|
||||
bLegacyPublicIncludePaths = false;
|
||||
ShadowVariableWarningLevel = WarningLevel.Error;
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
//IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_0;
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add public include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add other private include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
"CoreUObject"
|
||||
// ... add other public dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"GameProjectGeneration",
|
||||
"Projects",
|
||||
"InputCore",
|
||||
"EditorFramework",
|
||||
"UnrealEd",
|
||||
"ToolMenus",
|
||||
"LevelEditor",
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
"AssetTools"
|
||||
// ... add private dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
// ... add any modules that your module loads dynamically here ...
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#include "Ayon.h"
|
||||
|
||||
#include "ISettingsContainer.h"
|
||||
#include "ISettingsModule.h"
|
||||
#include "ISettingsSection.h"
|
||||
#include "AyonStyle.h"
|
||||
#include "AyonCommands.h"
|
||||
#include "AyonPythonBridge.h"
|
||||
#include "AyonSettings.h"
|
||||
#include "ToolMenus.h"
|
||||
|
||||
|
||||
static const FName AyonTabName("Ayon");
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FAyonModule"
|
||||
|
||||
// This function is triggered when the plugin is staring up
|
||||
void FAyonModule::StartupModule()
|
||||
{
|
||||
FAyonStyle::Initialize();
|
||||
FAyonStyle::ReloadTextures();
|
||||
FAyonCommands::Register();
|
||||
|
||||
PluginCommands = MakeShareable(new FUICommandList);
|
||||
|
||||
PluginCommands->MapAction(
|
||||
FAyonCommands::Get().AyonTools,
|
||||
FExecuteAction::CreateRaw(this, &FAyonModule::MenuPopup),
|
||||
FCanExecuteAction());
|
||||
PluginCommands->MapAction(
|
||||
FAyonCommands::Get().AyonToolsDialog,
|
||||
FExecuteAction::CreateRaw(this, &FAyonModule::MenuDialog),
|
||||
FCanExecuteAction());
|
||||
|
||||
UToolMenus::RegisterStartupCallback(
|
||||
FSimpleMulticastDelegate::FDelegate::CreateRaw(this, &FAyonModule::RegisterMenus));
|
||||
|
||||
RegisterSettings();
|
||||
}
|
||||
|
||||
void FAyonModule::ShutdownModule()
|
||||
{
|
||||
UToolMenus::UnRegisterStartupCallback(this);
|
||||
|
||||
UToolMenus::UnregisterOwner(this);
|
||||
|
||||
FAyonStyle::Shutdown();
|
||||
|
||||
FAyonCommands::Unregister();
|
||||
}
|
||||
|
||||
|
||||
void FAyonModule::RegisterSettings()
|
||||
{
|
||||
ISettingsModule& SettingsModule = FModuleManager::LoadModuleChecked<ISettingsModule>("Settings");
|
||||
|
||||
// Create the new category
|
||||
// TODO: After the movement of the plugin from the game to editor, it might be necessary to move this!
|
||||
ISettingsContainerPtr SettingsContainer = SettingsModule.GetContainer("Project");
|
||||
|
||||
UAyonSettings* Settings = GetMutableDefault<UAyonSettings>();
|
||||
|
||||
// Register the settings
|
||||
ISettingsSectionPtr SettingsSection = SettingsModule.RegisterSettings("Project", "Ayon", "General",
|
||||
LOCTEXT("RuntimeGeneralSettingsName",
|
||||
"General"),
|
||||
LOCTEXT("RuntimeGeneralSettingsDescription",
|
||||
"Base configuration for Open Pype Module"),
|
||||
Settings
|
||||
);
|
||||
|
||||
// Register the save handler to your settings, you might want to use it to
|
||||
// validate those or just act to settings changes.
|
||||
if (SettingsSection.IsValid())
|
||||
{
|
||||
SettingsSection->OnModified().BindRaw(this, &FAyonModule::HandleSettingsSaved);
|
||||
}
|
||||
}
|
||||
|
||||
bool FAyonModule::HandleSettingsSaved()
|
||||
{
|
||||
UAyonSettings* Settings = GetMutableDefault<UAyonSettings>();
|
||||
bool ResaveSettings = false;
|
||||
|
||||
// You can put any validation code in here and resave the settings in case an invalid
|
||||
// value has been entered
|
||||
|
||||
if (ResaveSettings)
|
||||
{
|
||||
Settings->SaveConfig();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FAyonModule::RegisterMenus()
|
||||
{
|
||||
// Owner will be used for cleanup in call to UToolMenus::UnregisterOwner
|
||||
FToolMenuOwnerScoped OwnerScoped(this);
|
||||
|
||||
{
|
||||
UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.MainMenu.Tools");
|
||||
{
|
||||
// FToolMenuSection& Section = Menu->FindOrAddSection("Ayon");
|
||||
FToolMenuSection& Section = Menu->AddSection(
|
||||
"Ayon",
|
||||
TAttribute<FText>(FText::FromString("Ayon")),
|
||||
FToolMenuInsert("Programming", EToolMenuInsertType::Before)
|
||||
);
|
||||
Section.AddMenuEntryWithCommandList(FAyonCommands::Get().AyonTools, PluginCommands);
|
||||
Section.AddMenuEntryWithCommandList(FAyonCommands::Get().AyonToolsDialog, PluginCommands);
|
||||
}
|
||||
UToolMenu* ToolbarMenu = UToolMenus::Get()->ExtendMenu("LevelEditor.LevelEditorToolBar.PlayToolBar");
|
||||
{
|
||||
FToolMenuSection& Section = ToolbarMenu->FindOrAddSection("PluginTools");
|
||||
{
|
||||
FToolMenuEntry& Entry = Section.AddEntry(
|
||||
FToolMenuEntry::InitToolBarButton(FAyonCommands::Get().AyonTools));
|
||||
Entry.SetCommandList(PluginCommands);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FAyonModule::MenuPopup()
|
||||
{
|
||||
UAyonPythonBridge* bridge = UAyonPythonBridge::Get();
|
||||
bridge->RunInPython_Popup();
|
||||
}
|
||||
|
||||
void FAyonModule::MenuDialog()
|
||||
{
|
||||
UAyonPythonBridge* bridge = UAyonPythonBridge::Get();
|
||||
bridge->RunInPython_Dialog();
|
||||
}
|
||||
|
||||
IMPLEMENT_MODULE(FAyonModule, Ayon)
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#include "AyonAssetContainer.h"
|
||||
#include "AssetRegistry/AssetRegistryModule.h"
|
||||
#include "Misc/PackageName.h"
|
||||
#include "Containers/UnrealString.h"
|
||||
|
||||
UAyonAssetContainer::UAyonAssetContainer(const FObjectInitializer& ObjectInitializer)
|
||||
: UAssetUserData(ObjectInitializer)
|
||||
{
|
||||
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
|
||||
FString path = UAyonAssetContainer::GetPathName();
|
||||
UE_LOG(LogTemp, Warning, TEXT("UAyonAssetContainer %s"), *path);
|
||||
FARFilter Filter;
|
||||
Filter.PackagePaths.Add(FName(*path));
|
||||
|
||||
AssetRegistryModule.Get().OnAssetAdded().AddUObject(this, &UAyonAssetContainer::OnAssetAdded);
|
||||
AssetRegistryModule.Get().OnAssetRemoved().AddUObject(this, &UAyonAssetContainer::OnAssetRemoved);
|
||||
AssetRegistryModule.Get().OnAssetRenamed().AddUObject(this, &UAyonAssetContainer::OnAssetRenamed);
|
||||
}
|
||||
|
||||
void UAyonAssetContainer::OnAssetAdded(const FAssetData& AssetData)
|
||||
{
|
||||
TArray<FString> split;
|
||||
|
||||
// get directory of current container
|
||||
FString selfFullPath = UAyonAssetContainer::GetPathName();
|
||||
FString selfDir = FPackageName::GetLongPackagePath(*selfFullPath);
|
||||
|
||||
// get asset path and class
|
||||
FString assetPath = AssetData.GetFullName();
|
||||
FString assetFName = AssetData.GetObjectPathString();
|
||||
UE_LOG(LogTemp, Log, TEXT("asset name %s"), *assetFName);
|
||||
// split path
|
||||
assetPath.ParseIntoArray(split, TEXT(" "), true);
|
||||
|
||||
FString assetDir = FPackageName::GetLongPackagePath(*split[1]);
|
||||
|
||||
// take interest only in paths starting with path of current container
|
||||
if (assetDir.StartsWith(*selfDir))
|
||||
{
|
||||
// exclude self
|
||||
if (assetFName != "AssetContainer")
|
||||
{
|
||||
assets.Add(assetPath);
|
||||
assetsData.Add(AssetData);
|
||||
UE_LOG(LogTemp, Log, TEXT("%s: asset added to %s"), *selfFullPath, *selfDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UAyonAssetContainer::OnAssetRemoved(const FAssetData& AssetData)
|
||||
{
|
||||
TArray<FString> split;
|
||||
|
||||
// get directory of current container
|
||||
FString selfFullPath = UAyonAssetContainer::GetPathName();
|
||||
FString selfDir = FPackageName::GetLongPackagePath(*selfFullPath);
|
||||
|
||||
// get asset path and class
|
||||
FString assetPath = AssetData.GetFullName();
|
||||
FString assetFName = AssetData.GetObjectPathString();
|
||||
|
||||
// split path
|
||||
assetPath.ParseIntoArray(split, TEXT(" "), true);
|
||||
|
||||
FString assetDir = FPackageName::GetLongPackagePath(*split[1]);
|
||||
|
||||
// take interest only in paths starting with path of current container
|
||||
FString path = UAyonAssetContainer::GetPathName();
|
||||
FString lpp = FPackageName::GetLongPackagePath(*path);
|
||||
|
||||
if (assetDir.StartsWith(*selfDir))
|
||||
{
|
||||
// exclude self
|
||||
if (assetFName != "AssetContainer")
|
||||
{
|
||||
// UE_LOG(LogTemp, Warning, TEXT("%s: asset removed"), *lpp);
|
||||
assets.Remove(assetPath);
|
||||
assetsData.Remove(AssetData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UAyonAssetContainer::OnAssetRenamed(const FAssetData& AssetData, const FString& str)
|
||||
{
|
||||
TArray<FString> split;
|
||||
|
||||
// get directory of current container
|
||||
FString selfFullPath = UAyonAssetContainer::GetPathName();
|
||||
FString selfDir = FPackageName::GetLongPackagePath(*selfFullPath);
|
||||
|
||||
// get asset path and class
|
||||
FString assetPath = AssetData.GetFullName();
|
||||
FString assetFName = AssetData.GetObjectPathString();
|
||||
|
||||
// split path
|
||||
assetPath.ParseIntoArray(split, TEXT(" "), true);
|
||||
|
||||
FString assetDir = FPackageName::GetLongPackagePath(*split[1]);
|
||||
if (assetDir.StartsWith(*selfDir))
|
||||
{
|
||||
// exclude self
|
||||
if (assetFName != "AssetContainer")
|
||||
{
|
||||
|
||||
assets.Remove(str);
|
||||
assets.Add(assetPath);
|
||||
assetsData.Remove(AssetData);
|
||||
// UE_LOG(LogTemp, Warning, TEXT("%s: asset renamed %s"), *lpp, *str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
#include "AyonAssetContainerFactory.h"
|
||||
#include "AyonAssetContainer.h"
|
||||
|
||||
UAyonAssetContainerFactory::UAyonAssetContainerFactory(const FObjectInitializer& ObjectInitializer)
|
||||
: UFactory(ObjectInitializer)
|
||||
{
|
||||
SupportedClass = UAyonAssetContainer::StaticClass();
|
||||
bCreateNew = false;
|
||||
bEditorImport = true;
|
||||
}
|
||||
|
||||
UObject* UAyonAssetContainerFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn)
|
||||
{
|
||||
UAyonAssetContainer* AssetContainer = NewObject<UAyonAssetContainer>(InParent, Class, Name, Flags);
|
||||
return AssetContainer;
|
||||
}
|
||||
|
||||
bool UAyonAssetContainerFactory::ShouldShowInNewMenu() const {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
|
||||
#include "AyonCommands.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FAyonModule"
|
||||
|
||||
void FAyonCommands::RegisterCommands()
|
||||
{
|
||||
UI_COMMAND(AyonTools, "Ayon Tools", "Pipeline tools", EUserInterfaceActionType::Button, FInputChord());
|
||||
UI_COMMAND(AyonToolsDialog, "Ayon Tools Dialog", "Pipeline tools dialog", EUserInterfaceActionType::Button, FInputChord());
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
#include "AyonLib.h"
|
||||
|
||||
#include "AssetViewUtils.h"
|
||||
#include "UObject/UnrealType.h"
|
||||
|
||||
/**
|
||||
* Sets color on folder icon on given path
|
||||
* @param InPath - path to folder
|
||||
* @param InFolderColor - color of the folder
|
||||
* @warning This color will appear only after Editor restart. Is there a better way?
|
||||
*/
|
||||
|
||||
bool UAyonLib::SetFolderColor(const FString& FolderPath, const FLinearColor& FolderColor, const bool& bForceAdd)
|
||||
{
|
||||
if (AssetViewUtils::DoesFolderExist(FolderPath))
|
||||
{
|
||||
const TSharedPtr<FLinearColor> LinearColor = MakeShared<FLinearColor>(FolderColor);
|
||||
|
||||
AssetViewUtils::SaveColor(FolderPath, LinearColor, true);
|
||||
UE_LOG(LogAssetData, Display, TEXT("A color {%s} has been set to folder \"%s\""), *LinearColor->ToString(),
|
||||
*FolderPath)
|
||||
return true;
|
||||
}
|
||||
|
||||
UE_LOG(LogAssetData, Display, TEXT("Setting a color {%s} to folder \"%s\" has failed! Directory doesn't exist!"),
|
||||
*FolderColor.ToString(), *FolderPath)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all poperties on given object
|
||||
* @param cls - class
|
||||
* @return TArray of properties
|
||||
*/
|
||||
TArray<FString> UAyonLib::GetAllProperties(UClass* cls)
|
||||
{
|
||||
TArray<FString> Ret;
|
||||
if (cls != nullptr)
|
||||
{
|
||||
for (TFieldIterator<FProperty> It(cls); It; ++It)
|
||||
{
|
||||
FProperty* Property = *It;
|
||||
if (Property->HasAnyPropertyFlags(EPropertyFlags::CPF_Edit))
|
||||
{
|
||||
Ret.Add(Property->GetName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
|
@ -1,204 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
// Deprecation warning: this is left here just for backwards compatibility
|
||||
// and will be removed in next versions of Ayon.
|
||||
#pragma once
|
||||
|
||||
#include "AyonPublishInstance.h"
|
||||
#include "AssetRegistry/AssetRegistryModule.h"
|
||||
#include "AssetToolsModule.h"
|
||||
#include "Framework/Notifications/NotificationManager.h"
|
||||
#include "AyonLib.h"
|
||||
#include "AyonSettings.h"
|
||||
#include "Widgets/Notifications/SNotificationList.h"
|
||||
|
||||
|
||||
//Moves all the invalid pointers to the end to prepare them for the shrinking
|
||||
#define REMOVE_INVALID_ENTRIES(VAR) VAR.CompactStable(); \
|
||||
VAR.Shrink();
|
||||
|
||||
UAyonPublishInstance::UAyonPublishInstance(const FObjectInitializer& ObjectInitializer)
|
||||
: UPrimaryDataAsset(ObjectInitializer)
|
||||
{
|
||||
const FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<
|
||||
FAssetRegistryModule>("AssetRegistry");
|
||||
|
||||
const FPropertyEditorModule& PropertyEditorModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>(
|
||||
"PropertyEditor");
|
||||
|
||||
FString Left, Right;
|
||||
GetPathName().Split("/" + GetName(), &Left, &Right);
|
||||
|
||||
FARFilter Filter;
|
||||
Filter.PackagePaths.Emplace(FName(Left));
|
||||
|
||||
TArray<FAssetData> FoundAssets;
|
||||
AssetRegistryModule.GetRegistry().GetAssets(Filter, FoundAssets);
|
||||
|
||||
for (const FAssetData& AssetData : FoundAssets)
|
||||
OnAssetCreated(AssetData);
|
||||
|
||||
REMOVE_INVALID_ENTRIES(AssetDataInternal)
|
||||
REMOVE_INVALID_ENTRIES(AssetDataExternal)
|
||||
|
||||
AssetRegistryModule.Get().OnAssetAdded().AddUObject(this, &UAyonPublishInstance::OnAssetCreated);
|
||||
AssetRegistryModule.Get().OnAssetRemoved().AddUObject(this, &UAyonPublishInstance::OnAssetRemoved);
|
||||
AssetRegistryModule.Get().OnAssetUpdated().AddUObject(this, &UAyonPublishInstance::OnAssetUpdated);
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
ColorAyonDirs();
|
||||
#endif
|
||||
}
|
||||
|
||||
void UAyonPublishInstance::OnAssetCreated(const FAssetData& InAssetData)
|
||||
{
|
||||
TArray<FString> split;
|
||||
|
||||
UObject* Asset = InAssetData.GetAsset();
|
||||
|
||||
if (!IsValid(Asset))
|
||||
{
|
||||
UE_LOG(LogAssetData, Warning, TEXT("Asset \"%s\" is not valid! Skipping the addition."),
|
||||
*InAssetData.GetSoftObjectPath().ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
const bool result = IsUnderSameDir(Asset) && Cast<UAyonPublishInstance>(Asset) == nullptr;
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (AssetDataInternal.Emplace(Asset).IsValidId())
|
||||
{
|
||||
UE_LOG(LogTemp, Log, TEXT("Added an Asset to PublishInstance - Publish Instance: %s, Asset %s"),
|
||||
*this->GetName(), *Asset->GetName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UAyonPublishInstance::OnAssetRemoved(const FAssetData& InAssetData)
|
||||
{
|
||||
if (Cast<UAyonPublishInstance>(InAssetData.GetAsset()) == nullptr)
|
||||
{
|
||||
if (AssetDataInternal.Contains(nullptr))
|
||||
{
|
||||
AssetDataInternal.Remove(nullptr);
|
||||
REMOVE_INVALID_ENTRIES(AssetDataInternal)
|
||||
}
|
||||
else
|
||||
{
|
||||
AssetDataExternal.Remove(nullptr);
|
||||
REMOVE_INVALID_ENTRIES(AssetDataExternal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UAyonPublishInstance::OnAssetUpdated(const FAssetData& InAssetData)
|
||||
{
|
||||
REMOVE_INVALID_ENTRIES(AssetDataInternal);
|
||||
REMOVE_INVALID_ENTRIES(AssetDataExternal);
|
||||
}
|
||||
|
||||
bool UAyonPublishInstance::IsUnderSameDir(const UObject* InAsset) const
|
||||
{
|
||||
FString ThisLeft, ThisRight;
|
||||
this->GetPathName().Split(this->GetName(), &ThisLeft, &ThisRight);
|
||||
|
||||
return InAsset->GetPathName().StartsWith(ThisLeft);
|
||||
}
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
|
||||
void UAyonPublishInstance::ColorAyonDirs()
|
||||
{
|
||||
FString PathName = this->GetPathName();
|
||||
|
||||
//Check whether the path contains the defined Ayon folder
|
||||
if (!PathName.Contains(TEXT("Ayon"))) return;
|
||||
|
||||
//Get the base path for open pype
|
||||
FString PathLeft, PathRight;
|
||||
PathName.Split(FString("Ayon"), &PathLeft, &PathRight);
|
||||
|
||||
if (PathLeft.IsEmpty() || PathRight.IsEmpty())
|
||||
{
|
||||
UE_LOG(LogAssetData, Error, TEXT("Failed to retrieve the base Ayon directory!"))
|
||||
return;
|
||||
}
|
||||
|
||||
PathName.RemoveFromEnd(PathRight, ESearchCase::CaseSensitive);
|
||||
|
||||
//Get the current settings
|
||||
const UAyonSettings* Settings = GetMutableDefault<UAyonSettings>();
|
||||
|
||||
//Color the base folder
|
||||
UAyonLib::SetFolderColor(PathName, Settings->GetFolderFColor(), false);
|
||||
|
||||
//Get Sub paths, iterate through them and color them according to the folder color in UAyonSettings
|
||||
const FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(
|
||||
"AssetRegistry");
|
||||
|
||||
TArray<FString> PathList;
|
||||
|
||||
AssetRegistryModule.Get().GetSubPaths(PathName, PathList, true);
|
||||
|
||||
if (PathList.Num() > 0)
|
||||
{
|
||||
for (const FString& Path : PathList)
|
||||
{
|
||||
UAyonLib::SetFolderColor(Path, Settings->GetFolderFColor(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UAyonPublishInstance::SendNotification(const FString& Text) const
|
||||
{
|
||||
FNotificationInfo Info{FText::FromString(Text)};
|
||||
|
||||
Info.bFireAndForget = true;
|
||||
Info.bUseLargeFont = false;
|
||||
Info.bUseThrobber = false;
|
||||
Info.bUseSuccessFailIcons = false;
|
||||
Info.ExpireDuration = 4.f;
|
||||
Info.FadeOutDuration = 2.f;
|
||||
|
||||
FSlateNotificationManager::Get().AddNotification(Info);
|
||||
|
||||
UE_LOG(LogAssetData, Warning,
|
||||
TEXT(
|
||||
"Removed duplicated asset from the AssetsDataExternal in Container \"%s\", Asset is already included in the AssetDataInternal!"
|
||||
), *GetName()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
void UAyonPublishInstance::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
||||
{
|
||||
Super::PostEditChangeProperty(PropertyChangedEvent);
|
||||
|
||||
if (PropertyChangedEvent.ChangeType == EPropertyChangeType::ValueSet &&
|
||||
PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(
|
||||
UAyonPublishInstance, AssetDataExternal))
|
||||
{
|
||||
// Check for duplicated assets
|
||||
for (const auto& Asset : AssetDataInternal)
|
||||
{
|
||||
if (AssetDataExternal.Contains(Asset))
|
||||
{
|
||||
AssetDataExternal.Remove(Asset);
|
||||
return SendNotification(
|
||||
"You are not allowed to add assets into AssetDataExternal which are already included in AssetDataInternal!");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if no UAyonPublishInstance type assets are included
|
||||
for (const auto& Asset : AssetDataExternal)
|
||||
{
|
||||
if (Cast<UAyonPublishInstance>(Asset.Get()) != nullptr)
|
||||
{
|
||||
AssetDataExternal.Remove(Asset);
|
||||
return SendNotification("You are not allowed to add publish instances!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright 2023, Ayon, All rights reserved.
|
||||
// Deprecation warning: this is left here just for backwards compatibility
|
||||
// and will be removed in next versions of Ayon.
|
||||
#include "AyonPublishInstanceFactory.h"
|
||||
#include "AyonPublishInstance.h"
|
||||
|
||||
UAyonPublishInstanceFactory::UAyonPublishInstanceFactory(const FObjectInitializer& ObjectInitializer)
|
||||
: UFactory(ObjectInitializer)
|
||||
{
|
||||
SupportedClass = UAyonPublishInstance::StaticClass();
|
||||
bCreateNew = false;
|
||||
bEditorImport = true;
|
||||
}
|
||||
|
||||
UObject* UAyonPublishInstanceFactory::FactoryCreateNew(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn)
|
||||
{
|
||||
check(InClass->IsChildOf(UAyonPublishInstance::StaticClass()));
|
||||
return NewObject<UAyonPublishInstance>(InParent, InClass, InName, Flags);
|
||||
}
|
||||
|
||||
bool UAyonPublishInstanceFactory::ShouldShowInNewMenu() const {
|
||||
return false;
|
||||
}
|
||||