Announcement

Collapse
No announcement yet.

Having trouble with a custom asset editor.

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Having trouble with a custom asset editor.

    hi, I'm trying to create a simple custom asset editor but I'm having problems with the creation of the new window for the editor.
    I already created a new custom asset, its factory and a new class that inherits FAssetTypeActions_Base and support my new asset.
    I also created a new class that inherit FAssetEditorToolkit. One told me to create a simple widget and to register it within RegisterTabSpawners() function. Problem is, the engine crashes when it reach SNew(SGraphEditor) in my CreateViewportEditor() function and I don't know what to do.
    I tried commenting the line and return an empty pointer but it crashes anyway so I don't really know what I'm doing wrong.
    here's the code if it can help:
    .h
    Code:
    #pragma once
    
    #include "CoreMinimal.h"
    #include "AssetEditorToolkit.h"
    #include "NotifyHook.h"
    #include "GCObject.h"
    #include "GraphEditor.h"
    #include "PropertyEditorModule.h"
    #include "ModuleManager.h"
    
    /**
     * 
     */
    class NOTANOTHERGRAPHASSISTANT_API AssetEditorGenericGraph:public FAssetEditorToolkit, public FNotifyHook, public FGCObject
    {
    public:
        AssetEditorGenericGraph();
        ~AssetEditorGenericGraph();
    
        // Inherited via FAssetEditorToolkit
        virtual FName GetToolkitFName() const override;
        virtual FText GetBaseToolkitName() const override;
        virtual FText GetToolkitName() const override;
        virtual FText GetToolkitToolTipText() const override;
        virtual FLinearColor GetWorldCentricTabColorScale() const override;
        virtual FString GetWorldCentricTabPrefix() const override;
        virtual FString GetDocumentationLink() const override;
        virtual void SaveAsset_Execute() override;
    
        // IToolkit interface
        virtual void RegisterTabSpawners(const TSharedRef<FTabManager>& TabManager) override;
        virtual void UnregisterTabSpawners(const TSharedRef<FTabManager>& TabManager) override;
    
        // Inherited via FGCObject
        virtual void AddReferencedObjects(FReferenceCollector & Collector) override;
    
    private:
    
        TSharedPtr<SGraphEditor>ViewportEditor;
        TSharedPtr<class IDetailsView> PropertyWidget;
        TSharedPtr<class IDetailsView> EditorSettingsWidget;
    
        TSharedPtr<SGraphEditor>CreateViewportEditor();
    
        TSharedRef<SDockTab> SpawnTab_Viewport(const FSpawnTabArgs & Args);
    
    };
    .cpp
    Code:
    #include "AssetEditorGenericGraph.h"
    
    #define LOCTEXT_NAMESPACE "AssetEditorGenericGraph"
    
    AssetEditorGenericGraph::AssetEditorGenericGraph()
    {
        UE_LOG(LogTemp, Warning, TEXT("Asset editor costructor"));
        CreateViewportEditor();
    }
    
    AssetEditorGenericGraph::~AssetEditorGenericGraph()
    {
    }
    
    FName AssetEditorGenericGraph::GetToolkitFName() const
    {
        UE_LOG(LogTemp, Warning, TEXT("Asset editor GetToolkitFName"));
        return FName();
    }
    
    FText AssetEditorGenericGraph::GetBaseToolkitName() const
    {
        UE_LOG(LogTemp, Warning, TEXT("Asset editor GetBaseToolkitName"));
        return FText();
    }
    
    FText AssetEditorGenericGraph::GetToolkitName() const
    {
        UE_LOG(LogTemp, Warning, TEXT("Asset editor GetToolkitName"));
        return FText();
    }
    
    FText AssetEditorGenericGraph::GetToolkitToolTipText() const
    {
        UE_LOG(LogTemp, Warning, TEXT("Asset editor GetToolkitToolTipText"));
        return FText();
    }
    
    FLinearColor AssetEditorGenericGraph::GetWorldCentricTabColorScale() const
    {
        UE_LOG(LogTemp, Warning, TEXT("Asset editor GetWorldCentricTabColorScale"));
        return FLinearColor();
    }
    
    FString AssetEditorGenericGraph::GetWorldCentricTabPrefix() const
    {
        UE_LOG(LogTemp, Warning, TEXT("Asset editor GetWorldCentricTabPrefix"));
        return FString();
    }
    
    FString AssetEditorGenericGraph::GetDocumentationLink() const
    {
        UE_LOG(LogTemp, Warning, TEXT("Asset editor GetDocumentationLink"));
        return FString();
    }
    
    void AssetEditorGenericGraph::SaveAsset_Execute()
    {
        UE_LOG(LogTemp, Warning, TEXT("Asset editor SaveAsset_Execute"));
    }
    
    void AssetEditorGenericGraph::RegisterTabSpawners(const TSharedRef<FTabManager>& TabManager)
    {
        UE_LOG(LogTemp, Warning, TEXT("Asset editor RegisterTabSpawners"));
    
        WorkspaceMenuCategory = TabManager->AddLocalWorkspaceMenuCategory(LOCTEXT("WorkspaceMenuAssetEditorGenericGraph", "Generic Graph Editor"));
        auto WorkspaceMenuCategoryRef = WorkspaceMenuCategory.ToSharedRef();
    
        FAssetEditorToolkit::RegisterTabSpawners(TabManager);
        TabManager->RegisterTabSpawner(TEXT("TABID"), FOnSpawnTab::CreateSP(this, &AssetEditorGenericGraph::SpawnTab_Viewport)).SetDisplayName(LOCTEXT("GraphCanvasTab", "Viewport"));
    
    }
    
    void AssetEditorGenericGraph::UnregisterTabSpawners(const TSharedRef<FTabManager>& TabManager)
    {
        UE_LOG(LogTemp, Warning, TEXT("Asset editor UnregisterTabSpawners"));
    }
    
    void AssetEditorGenericGraph::AddReferencedObjects(FReferenceCollector & Collector)
    {
        UE_LOG(LogTemp, Warning, TEXT("Asset editor AddReferencedObjects"));
    }
    
    TSharedPtr<SGraphEditor> AssetEditorGenericGraph::CreateViewportEditor()
    {
        UE_LOG(LogTemp, Warning, TEXT("Asset editor START CreateViewportEditor"));
    
        FGraphAppearanceInfo AppearanceInfo;
        AppearanceInfo.CornerText = LOCTEXT("AppearanceCornerTextAssetEditorGenericGraph", "Generic Graph");
    
        ViewportEditor = SNew(SGraphEditor);
    
    
        FDetailsViewArgs Args;
        Args.bHideSelectionTip = true;
        Args.NotifyHook = this;
    
        FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
        PropertyWidget = PropertyModule.CreateDetailView(Args);
        EditorSettingsWidget = PropertyModule.CreateDetailView(Args);
    
        return ViewportEditor;
    }
    TSharedRef<SDockTab> AssetEditorGenericGraph::SpawnTab_Viewport(const FSpawnTabArgs& Args)
    {
    
        TSharedRef<SDockTab> SpawnedTab = SNew(SDockTab).Label(LOCTEXT("ViewportTab_Title", "Viewport"));
    
        if (ViewportEditor.IsValid())
        {
            SpawnedTab->SetContent(ViewportEditor.ToSharedRef());
        }
    
        return SpawnedTab;
    }
    I also need a bit of help understanding what I need to implement in order to achieve a simple graph editor, i tried looking for documentation but I found almost nothing.

    #2
    So I think I found the problems. I rewrote the class removing everything I could and I found that I wasn't creating properly the slate interface.
    With this new AssetEditorToolkit

    .h
    Code:
    #pragma once
    
    #include "CoreMinimal.h"
    #include "AssetEditorToolkit.h"
    #include "GenericGraph.h"
    #include "GraphEditor.h"
    #include "SDockTab.h"
    
    /**
     * 
     */
    class FGenericGraphEditorToolkit : public FAssetEditorToolkit, public FGCObject
    {
    public:
        FGenericGraphEditorToolkit();
        ~FGenericGraphEditorToolkit();
    
        UGenericGraph* Graph;
    
        TSharedRef<SDockTab> HandleTabManagerSpawnTab(const FSpawnTabArgs& Args, FName TabIdentifier);
    
        // Inherited via FAssetEditorToolkit
        virtual FLinearColor GetWorldCentricTabColorScale() const override;
        virtual FName GetToolkitFName() const override;
        virtual FText GetBaseToolkitName() const override;
        virtual FString GetWorldCentricTabPrefix() const override;
        virtual void RegisterTabSpawners(const TSharedRef<FTabManager>& TabManager) override;
        virtual void UnregisterTabSpawners(const TSharedRef<FTabManager>& TabManager) override;
        virtual void InitAssetEditor(const EToolkitMode::Type InMode, const TSharedPtr<class IToolkitHost>& InToolkitHost, UGenericGraph* InGraph);
    
    
        // Inherited via FGCObject
        virtual void AddReferencedObjects(FReferenceCollector & Collector) override;
    
    
    };
    .cpp
    Code:
    #include "GenericGraphEditorToolkit.h"
    
    #define LOCTEXT_NAMESPACE "AssetEditorToolkit"
    
    FGenericGraphEditorToolkit::FGenericGraphEditorToolkit()
    {
    }
    
    FGenericGraphEditorToolkit::~FGenericGraphEditorToolkit()
    {
    }
    
    TSharedRef<SDockTab> FGenericGraphEditorToolkit::HandleTabManagerSpawnTab(const FSpawnTabArgs & Args, FName TabIdentifier)
    {
        TSharedPtr<SWidget>Tab = SNullWidget::NullWidget;
        if (TabIdentifier== FName("GraphEditorId"))
        {
            //Tab = SNew(SGraphEditor);
        }
        return SNew(SDockTab)
            .TabRole(ETabRole::PanelTab)
            [
                Tab.ToSharedRef()
            ];
    }
    
    FLinearColor FGenericGraphEditorToolkit::GetWorldCentricTabColorScale() const
    {
        return FLinearColor::Blue;
    }
    
    FName FGenericGraphEditorToolkit::GetToolkitFName() const
    {
        return FName("Generic Graph Editor");
    }
    
    FText FGenericGraphEditorToolkit::GetBaseToolkitName() const
    {
        return LOCTEXT("AppLabel", "Generic graph Editor");
    }
    
    FString FGenericGraphEditorToolkit::GetWorldCentricTabPrefix() const
    {
        return LOCTEXT("WorldCentricTabPrefix", "Generic Graph ").ToString();
    }
    
    void FGenericGraphEditorToolkit::InitAssetEditor(const EToolkitMode::Type InMode, const TSharedPtr<class IToolkitHost>& InToolkitHost, UGenericGraph * InGraph)
    {
        Graph = InGraph;
        TSharedRef<FTabManager::FLayout>Layout = FTabManager::NewLayout("Layout")
            ->AddArea
            (
                FTabManager::NewPrimaryArea()
                ->SetOrientation(Orient_Vertical)
                ->Split
                (
                    FTabManager::NewSplitter()
                    ->SetOrientation(Orient_Vertical)
                    ->SetSizeCoefficient(0.66f)
                    ->Split
                    (
                        FTabManager::NewStack()
                        ->AddTab(GetToolbarTabId(), ETabState::OpenedTab)
                        ->SetHideTabWell(true)
                        ->SetSizeCoefficient(0.1f)
                    )
                    ->Split
                    (
                        FTabManager::NewStack()
                        ->AddTab(FName("GraphEditorId"), ETabState::OpenedTab)
                        ->SetHideTabWell(true)
                        ->SetSizeCoefficient(0.9f)
                    )
                )
            );
        FAssetEditorToolkit::InitAssetEditor(InMode, InToolkitHost, FName("GraphEditorIdentifier"), Layout, true, true, Graph);
    }
    
    void FGenericGraphEditorToolkit::RegisterTabSpawners(const TSharedRef<FTabManager>& TabManager)
    {
        WorkspaceMenuCategory = TabManager->AddLocalWorkspaceMenuCategory(LOCTEXT("GenericGraphToolkitWorkspaceMenu", "Graph Editor"));
        auto WorkspaceMenuCategoryRef = WorkspaceMenuCategory.ToSharedRef();
        FAssetEditorToolkit::RegisterTabSpawners(TabManager);
    
        TabManager->RegisterTabSpawner(FName("GraphEditorId"), FOnSpawnTab::CreateSP(this,&FGenericGraphEditorToolkit::HandleTabManagerSpawnTab, FName("GraphEditorId")))
            .SetDisplayName(LOCTEXT("GraphEditorTabName", "Graph Editor"))
            .SetGroup(WorkspaceMenuCategoryRef);
    }
    
    void FGenericGraphEditorToolkit::UnregisterTabSpawners(const TSharedRef<FTabManager>& TabManager)
    {
    }
    
    void FGenericGraphEditorToolkit::AddReferencedObjects(FReferenceCollector & Collector)
    {
    }
    
    #undef LOCTEXT_NAMESPACE
    the window opens properly
    Click image for larger version

Name:	Screenshot.jpeg
Views:	71
Size:	400.3 KB
ID:	1504240


    But only as long as I don't try to create a SGraphEditor widget.
    Code:
    TSharedRef<SDockTab> FGenericGraphEditorToolkit::HandleTabManagerSpawnTab(const FSpawnTabArgs & Args, FName TabIdentifier)
    {
        TSharedPtr<SWidget>Tab = SNullWidget::NullWidget;
        if (TabIdentifier== FName("GraphEditorId"))
        {
            //Tab = SNew(SGraphEditor);
        }
        return SNew(SDockTab)
            .TabRole(ETabRole::PanelTab)
            [
                Tab.ToSharedRef()
            ];
    }
    So I think I'm using wrong that specific widget. The API page doesn't tell me anything about the proper use of SGraphEditor, I was expecting an empty blueprint graph window, so I don't know how I misused it.
    Does anyone know how to use it properly?

    Comment


      #3
      So it turns out that you need to give him an EdGraph otherwise the slate widget won't load and will stop the creation of the window.
      Using FBlueprintEditorUtils::CreateNewGraph you will also need a EdGraphSchema. Both classes (EdGraph and EdGraphSchema) are the bare minimum, can be inherited and left empty and the slate widget should load properly.

      Code:
      TSharedRef<SDockTab> FGenericGraphEditorToolkit::HandleTabManagerSpawnTabGraphTabId(const FSpawnTabArgs & Args, FName TabIdentifier)
      {
          TSharedPtr<SWidget>Tab = SNullWidget::NullWidget;
          if (TabIdentifier == GraphTabId)
          {
             GraphAsset->EdGraph = CastChecked<UGenericGraphEdGraph>(FBlueprintEditorUtils::CreateNewGraph(GraphAsset, NAME_None, UGenericGraphEdGraph::StaticClass(), UGenericGraphEdGraphSchema::StaticClass()));
              Tab = SNew(SGraphEditor).GraphToEdit(GraphAsset->EdGraph);
          }
          return SNew(SDockTab)
              .TabRole(ETabRole::PanelTab)
              [
                  Tab.ToSharedRef()
              ];
      }

      Comment


        #4
        Good job!! I also have the same problem.Think you for help me..

        Keep it!

        Comment

        Working...
        X