x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Create custom UE4 editor viewport?

I want to create a custom viewport (to edit UVs). I looked at SStaticMeshEditorViewport and FStaticMeshEditorViewportClient. I made a Viewport which inherits from SEditorViewport, and a ViewportClient which inherits from FEditorViewportClient.

When I create the viewport, I add some meshes to its PreviewScene with PreviewScene.AddComponent(Component, Transform);. The problem is that they do not appear on the viewport. Why?

Here is my code:

STextureViewport.h:

 // [...] #includes
 
 class STextureViewport : public SEditorViewport, public FGCObject, public ICommonEditorViewportToolbarInfoProvider
 {
 public:
     SLATE_BEGIN_ARGS(STextureViewport){}
     SLATE_END_ARGS()
 
     void Construct(const FArguments& InArgs);
     ~STextureViewport();
 
     virtual void AddReferencedObjects( FReferenceCollector& Collector ) override;
     void RefreshViewport();
     void SetPreviewMesh();
 
     /** @return The editor viewport client */
     class FEditorViewportClient& GetViewportClient();
 
     /** Set the parent tab of the viewport for determining visibility */
     void SetParentTab( TSharedRef<SDockTab> InParentTab ) { ParentTab = InParentTab; }
 
     // ICommonEditorViewportToolbarInfoProvider interface
     virtual TSharedRef<class SEditorViewport> GetViewportWidget() override;
     virtual TSharedPtr<FExtender> GetExtenders() const override;
     virtual void OnFloatingButtonClicked() override;
     // End of ICommonEditorViewportToolbarInfoProvider interface
 
 protected:
     /** SEditorViewport interface */
     virtual TSharedRef<FEditorViewportClient> MakeEditorViewportClient() override;
     virtual EVisibility OnGetViewportContentVisibility() const override;
     virtual void BindCommands() override;
     virtual void OnFocusViewportToSelection() override;
     virtual TSharedPtr<SWidget> MakeViewportToolbar() override;
 
 private:
 //    /** Callback for updating preview socket meshes if the static mesh or socket has been modified. */
     void OnObjectPropertyChanged(UObject* ObjectBeingModified, FPropertyChangedEvent& PropertyChangedEvent);
 private:
     
     /** The parent tab where this viewport resides */
     TWeakPtr<SDockTab> ParentTab;
 
     /** The scene for this viewport. */
     FPreviewScene PreviewScene;
 
     /** Editor viewport client */
     TSharedPtr<class FTextureViewportClient> TextureViewportClient;
 
     /** Pointer to the vertical box into which the overlay text items are added */
     TSharedPtr<SVerticalBox> OverlayTextVerticalBox;
 };


STextureViewport.cpp:

// [...] #includes

 // In-viewport toolbar widget used in the static mesh editor
 class STextureViewportToolbar : public SCommonEditorViewportToolbarBase
 {
 public:
     SLATE_BEGIN_ARGS(STextureViewportToolbar) {}
     SLATE_END_ARGS()
 
     void Construct(const FArguments& InArgs, TSharedPtr<class ICommonEditorViewportToolbarInfoProvider> InInfoProvider)
     {
         SCommonEditorViewportToolbarBase::Construct(SCommonEditorViewportToolbarBase::FArguments(), InInfoProvider);
     }
 
     // SCommonEditorViewportToolbarBase interface
     virtual TSharedRef<SWidget> GenerateShowMenu() const override
     {
         GetInfoProvider().OnFloatingButtonClicked();
 
         TSharedRef<SEditorViewport> ViewportRef = GetInfoProvider().GetViewportWidget();
 
         const bool bInShouldCloseWindowAfterMenuSelection = true;
         FMenuBuilder ShowMenuBuilder(bInShouldCloseWindowAfterMenuSelection, ViewportRef->GetCommandList());
         return ShowMenuBuilder.MakeWidget();
     }
     // End of SCommonEditorViewportToolbarBase
 };
 
 void STextureViewport::Construct(const FArguments& InArgs)
 {
 
     SEditorViewport::Construct( SEditorViewport::FArguments() );
 
     SetPreviewMesh();
 
     ViewportOverlay->AddSlot()
         .VAlign(VAlign_Top)
         .HAlign(HAlign_Left)
         .Padding(FMargin(10.0f, 40.0f, 10.0f, 10.0f))
         [
             SAssignNew(OverlayTextVerticalBox, SVerticalBox)
         ];
 }
 
 STextureViewport::~STextureViewport()
 {
     FCoreUObjectDelegates::OnObjectPropertyChanged.RemoveAll(this);
     if (TextureViewportClient.IsValid())
     {
         TextureViewportClient->Viewport = NULL;
     }
 }
 
 TSharedRef<class SEditorViewport> STextureViewport::GetViewportWidget()
 {
     return SharedThis(this);
 }
 
 TSharedPtr<FExtender> STextureViewport::GetExtenders() const
 {
     TSharedPtr<FExtender> Result(MakeShareable(new FExtender));
     return Result;
 }
 
 void STextureViewport::OnFloatingButtonClicked()
 {
 }
 
 void STextureViewport::AddReferencedObjects( FReferenceCollector& Collector )
 {
 }
 
 void STextureViewport::RefreshViewport()
 {
     // Invalidate the viewport's display.
     SceneViewport->Invalidate();
 }
 
 void STextureViewport::SetPreviewMesh(/*UStaticMesh* InStaticMesh*/)
 {
     FTransform Transform = FTransform::Identity;
     for(TActorIterator<AActor> ActorItr(ProBuilder::World.Get()); ActorItr; ++ActorItr)
     {
         for(UActorComponent* Component:ActorItr->GetComponents())
         {
             FComponentReregisterContext ReregisterContext( Component);
             PreviewScene.AddComponent(Component, Transform);
         }
     }
 }
 
 FEditorViewportClient& STextureViewport::GetViewportClient()
 {
     return *TextureViewportClient;
 }
 
 
 TSharedRef<FEditorViewportClient> STextureViewport::MakeEditorViewportClient()
 {
     TextureViewportClient = MakeShareable(new FTextureViewportClient(SharedThis(this), PreviewScene));
 
     TextureViewportClient->bSetListenerPosition = false;
 
     TextureViewportClient->SetRealtime( false );
     TextureViewportClient->VisibilityDelegate.BindSP( this, &STextureViewport::IsVisible );
 
     return TextureViewportClient.ToSharedRef();
 }
 
 TSharedPtr<SWidget> STextureViewport::MakeViewportToolbar()
 {
     return SNew(STextureViewportToolbar, SharedThis(this));
 }
 
 EVisibility STextureViewport::OnGetViewportContentVisibility() const
 {
     return IsVisible() ? EVisibility::Visible : EVisibility::Collapsed;
 }
 
 void STextureViewport::BindCommands()
 {
     SEditorViewport::BindCommands();
 }
 
 void STextureViewport::OnFocusViewportToSelection()
 {
 }

TextureViewportClient.h:

 class STextureViewport;
 
 /** Viewport Client for the preview viewport */
 class FTextureViewportClient : public FEditorViewportClient, public TSharedFromThis<FTextureViewportClient>
 {
 public:
         FTextureViewportClient(const TSharedRef<STextureViewport>& InTextureViewport, FPreviewScene& InPreviewScene);
 
     virtual void Tick(float DeltaSeconds) override;
     virtual void Draw(const FSceneView* View,FPrimitiveDrawInterface* PDI) override;
     virtual void DrawCanvas( FViewport& InViewport, FSceneView& View, FCanvas& Canvas ) override;
     virtual FSceneView* CalcSceneView(FSceneViewFamily* ViewFamily) override;
     TWeakPtr<STextureViewport> TextureViewportPtr;
 };


TextureViewportClient.cpp:

 namespace {
     static const float AutoViewportOrbitCameraTranslate = 256.0f;
     static float AmbientCubemapIntensity = 0.4f;
 }
 
 FTextureViewportClient::FTextureViewportClient(const TSharedRef<STextureViewport>& InTextureViewport, FPreviewScene& InPreviewScene)
     : FEditorViewportClient(nullptr, &InPreviewScene, StaticCastSharedRef<SEditorViewport>(InTextureViewport))
 
 {
     SetViewMode(VMI_Lit);
 
     EngineShowFlags.DisableAdvancedFeatures();
     EngineShowFlags.SetSnap(0);
     EngineShowFlags.CompositeEditorPrimitives = true;
     OverrideNearClipPlane(1.0f);
     bUsingOrbitCamera = true;
 }
 
 void FTextureViewportClient::Tick(float DeltaSeconds)
 {
     FEditorViewportClient::Tick(DeltaSeconds);
 
     // Tick the preview scene world.
     if (!GIntraFrameDebuggingGameThread)
     {
         PreviewScene->GetWorld()->Tick(LEVELTICK_All, DeltaSeconds);
     }
 }
 
 void FTextureViewportClient::Draw(const FSceneView* View,FPrimitiveDrawInterface* PDI)
 {
     FEditorViewportClient::Draw(View, PDI);
 }
 
 void FTextureViewportClient::DrawCanvas( FViewport& InViewport, FSceneView& View, FCanvas& Canvas )
 {
 
     auto TextureViewport = TextureViewportPtr.Pin();
     if (!TextureViewport.IsValid())
     {
         return;
     }
 }
 
 FSceneView* FTextureViewportClient::CalcSceneView(FSceneViewFamily* ViewFamily)
 {
     FSceneView* SceneView = FEditorViewportClient::CalcSceneView(ViewFamily);
     FFinalPostProcessSettings::FCubemapEntry& CubemapEntry = *new(SceneView->FinalPostProcessSettings.ContributingCubemaps) FFinalPostProcessSettings::FCubemapEntry;
     CubemapEntry.AmbientCubemap = GUnrealEd->GetThumbnailManager()->AmbientCubemap;
     CubemapEntry.AmbientCubemapTintMulScaleValue = FLinearColor::White * AmbientCubemapIntensity;
     return SceneView;
 }

Product Version: UE 4.10
Tags:
more ▼

asked Mar 08 '16 at 10:45 AM in C++ Programming

avatar image

Arthur Masson
289 36 42 60

avatar image Penanito May 14 '16 at 05:22 AM

Sorry for a comment kind of unrelated to your question, just wondering if you ever got issues with the identifier 'ECoordSystem' coming from SEditorViewport. I'm trying to get a simpler viewport up and running, after looking through your source and looking through all the source in SStaticMeshEditorViewport and StaticMeshEditorViewportClient, I had what I thought were the proper #include files on all the files (to get your code working), no errors come from the files themselves, but always from engine files and always related to not recognizing the ECoordSystem specifier.

avatar image Arthur Masson May 14 '16 at 07:45 AM

No I didn't solve this issue, sorry : /

Here are the includes of STextureViewport.h:

 #include "UnrealEd.h"
 #include "PreviewScene.h"
 #include "SEditorViewport.h"
 #include "PBEdModeToolkit.h"
 #include "TextureActions.h"
 #include "TextureViewportClient.h"
 #include "Editor/UnrealEd/Public/SCommonEditorViewportToolbarBase.h"

Sometimes, including files in the PCH helps, because the order of the includes seem to matter...

avatar image Penanito May 14 '16 at 06:25 PM

Ah got it working, yeah the order of includes definitely matters I guess. Thanks for the help!

avatar image Propogand Sep 14 '16 at 01:56 PM

Athrur Masson, You solve this problem? "The problem is that they do not appear on the viewport. Why?"

avatar image Arthur Masson Sep 14 '16 at 01:59 PM

No I still didn't solve the problem, but now I use Unreal.js, it has a nice JavascriptEditorViewport implementation

avatar image Propogand Sep 15 '16 at 12:13 AM

Okey, thank you very much.

avatar image Propogand Sep 15 '16 at 04:39 AM

Arthur Masson, I solved this problem, that code is working:

     USkeletalMesh* SkeletalMesh = bAssetData->GetSkeleton()->GetPreviewMesh();
 
     FTransform Transform = FTransform::Identity;
 
     MeshComponent = NewObject<USkeletalMeshComponent>(GetTransientPackage());
     MeshComponent->SetSkeletalMesh(SkeletalMesh);
     MeshComponent->RegisterComponentWithWorld(PreviewScene.GetWorld());
 
     FComponentReregisterContext ContextMeshComponent(MeshComponent);
 
     FRotator NewRotation = FRotator(0.0f, 180.0f, 0.0f);
 
     FVector NewPosition = FVector(SkeletalMesh->GetImportedBounds().SphereRadius * 1.5f);
 
     ViewportClient->SetViewLocation(NewPosition); // Set up new position of camera
     ViewportClient->SetViewRotation(NewRotation);
 
     PreviewScene.AddComponent(MeshComponent, Transform);

All that is needed is to register a component used world scene preview:

           MeshComponent->RegisterComponentWithWorld(PreviewScene.GetWorld());

I hope, this helps somebody, Thank you for code-viewport!

(comments are locked)
10|2000 characters needed characters left

0 answers: sort voted first
Be the first one to answer this question
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question