EditorEngine
EditorEngine
#Overview
name: EditorEngine
The value of this variable can be defined or overridden in .ini config files. 2
.ini config files referencing this setting variable.
It is referenced in 40
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of EditorEngine
is to manage and control the Unreal Engine editor environment. It is a key component of Unreal Engine’s editing and development tools, primarily used in the context of game development within the Unreal Editor.
Here are the key points about EditorEngine
:
-
It is a specialized version of the engine used specifically for editing and development purposes within the Unreal Editor.
-
The
EditorEngine
is part of the Unreal Engine’s editor subsystem and is typically only available in editor builds of the engine. -
It provides functionality for managing editor-specific features such as Play-In-Editor (PIE), viewport manipulation, and editor-specific world contexts.
-
The
EditorEngine
is responsible for managing the transition between editor and play modes, handling editor viewports, and coordinating editor-specific systems. -
It is used across various editor-related plugins and modules, including animation tools, rendering systems, and development utilities.
-
The value of
EditorEngine
is typically set when the engine initializes in editor mode. It’s usually accessed throughGEngine
when in the editor context. -
Developers should be aware that
EditorEngine
functionalities are not available in game runtime builds, so code that relies on it should be properly guarded with preprocessor directives (e.g.,#if WITH_EDITOR
). -
Best practices include:
- Always check if
GIsEditor
is true before accessingEditorEngine
functionality. - Use
Cast<UEditorEngine>(GEngine)
to safely accessEditorEngine
features. - Be cautious when using
EditorEngine
in code that might also run in non-editor builds.
- Always check if
-
EditorEngine
interacts with many other systems, including the PIE system, viewport management, and editor world contexts. -
When developing editor tools or extending editor functionality, understanding and properly utilizing
EditorEngine
is crucial for integrating with Unreal’s existing editor systems.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseEngine.ini:139, section: [/Script/Engine.Engine]
- INI Section:
/Script/Engine.Engine
- Raw value:
/Script/UnrealEd.EditorEngine
- Is Array:
False
Location: <Workspace>/Projects/Lyra/Config/DefaultEngine.ini:24, section: [/Script/Engine.Engine]
- INI Section:
/Script/Engine.Engine
- Raw value:
/Script/LyraEditor.LyraEditorEngine
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Plugins/Animation/GameplayInsights/Source/GameplayInsights/Private/GameplayTimingViewExtender.cpp:102
Scope (from outer to inner):
file
function UWorld* FGameplayTimingViewExtender::GetWorldToVisualize
Source code excerpt:
#if WITH_EDITOR
UEditorEngine* EditorEngine = Cast<UEditorEngine>(GEngine);
if (GIsEditor && EditorEngine != nullptr && World == nullptr)
{
// lets use PlayWorld during PIE/Simulate and regular world from editor otherwise, to draw debug information
World = EditorEngine->PlayWorld != nullptr ? ToRawPtr(EditorEngine->PlayWorld) : EditorEngine->GetEditorWorldContext().World();
}
#endif
if (!GIsEditor && World == nullptr)
{
World = GEngine->GetWorld();
#Loc: <Workspace>/Engine/Plugins/Animation/GameplayInsights/Source/RewindDebugger/Private/RewindDebugger.cpp:654
Scope (from outer to inner):
file
function UWorld* FRewindDebugger::GetWorldToVisualize
Source code excerpt:
#if WITH_EDITOR
UEditorEngine* EditorEngine = Cast<UEditorEngine>(GEngine);
if (GIsEditor && EditorEngine != nullptr && World == nullptr)
{
// lets use PlayWorld during PIE/Simulate and regular world from editor otherwise, to draw debug information
World = EditorEngine->PlayWorld != nullptr ? ToRawPtr(EditorEngine->PlayWorld) : EditorEngine->GetEditorWorldContext().World();
}
#endif
if (!GIsEditor && World == nullptr)
{
World = GEngine->GetWorld();
#Loc: <Workspace>/Engine/Plugins/Animation/GameplayInsights/Source/RewindDebuggerVLog/Private/RewindDebuggerVLog.cpp:204
Scope (from outer to inner):
file
function AVLogRenderingActor* FRewindDebuggerVLog::GetRenderingActor
Source code excerpt:
if (!VLogActor.IsValid())
{
UEditorEngine* EditorEngine = Cast<UEditorEngine>(GEngine);
if (GIsEditor && EditorEngine && EditorEngine->PlayWorld)
{
FActorSpawnParameters SpawnParameters;
SpawnParameters.ObjectFlags |= RF_Transient;
VLogActor = EditorEngine->PlayWorld->SpawnActor<AVLogRenderingActor>(SpawnParameters);
}
}
return VLogActor.Get();
}
void FRewindDebuggerVLog::Update(float DeltaTime, IRewindDebugger* RewindDebugger)
#Loc: <Workspace>/Engine/Plugins/Animation/PoseSearch/Source/Runtime/Private/PoseSearchDatabase.cpp:760
Scope (from outer to inner):
file
function void UPoseSearchDatabase::PostLoad
Source code excerpt:
ERequestAsyncBuildFlag Flag = ERequestAsyncBuildFlag::NewRequest;
#if WITH_ENGINE
// If there isn't an EditorEngine (ex. Standalone Game via -game argument) we WaitForCompletion
if (Cast<UEditorEngine>(GEngine) == nullptr)
{
Flag |= ERequestAsyncBuildFlag::WaitForCompletion;
}
#endif // WITH_ENGINE
#Loc: <Workspace>/Engine/Plugins/Developer/RenderDocPlugin/Source/RenderDocPlugin/Private/RenderDocPluginModule.cpp:523
Scope (from outer to inner):
file
function void FRenderDocPluginModule::Tick
Source code excerpt:
else if(StartPIEDelayFrames == 0)
{
UEditorEngine* EditorEngine = CastChecked<UEditorEngine>(GEngine);
FRequestPlaySessionParams SessionParams;
FLevelEditorModule& LevelEditorModule = FModuleManager::Get().GetModuleChecked<FLevelEditorModule>(TEXT("LevelEditor"));
SessionParams.DestinationSlateViewport = LevelEditorModule.GetFirstActiveViewport();
EditorEngine->RequestPlaySession(SessionParams);
StartPIEDelayFrames = -1;
}
#endif // WITH_EDITOR
if (!bPendingCapture && !bCaptureInProgress)
return;
#Loc: <Workspace>/Engine/Plugins/Experimental/ChaosVehiclesPlugin/Source/ChaosVehiclesEditor/Private/ChaosVehiclesFactory.cpp:3
Scope: file
Source code excerpt:
//
//#include "Editor.h"
//#include "Editor/EditorEngine.h"
//#include "Engine/Selection.h"
//
//#define LOCTEXT_NAMESPACE "ChaosVehicles"
//
///////////////////////////////////////////////////////
//// ChaosVehiclesFactory
#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/NiagaraEditorModule.cpp:1678
Scope (from outer to inner):
file
function void FNiagaraEditorModule::OnPostEngineInit
Source code excerpt:
GEditor->OnExecParticleInvoked().AddRaw(this, &FNiagaraEditorModule::OnExecParticleInvoked);
UEditorEngine* EditorEngine = CastChecked<UEditorEngine>(GEngine);
PreviewPlatformChangedHandle = EditorEngine->OnPreviewPlatformChanged().AddRaw(this, &FNiagaraEditorModule::OnPreviewPlatformChanged);
PreviewFeatureLevelChangedHandle = EditorEngine->OnPreviewFeatureLevelChanged().AddStatic(UNiagaraScript::SetPreviewFeatureLevel);
// Ensure we have the right feature level set as the editor may already be in one before we get here
UNiagaraScript::SetPreviewFeatureLevel(GEditor->DefaultWorldFeatureLevel);
// Handle a re-import for mesh renderers
if (UImportSubsystem* ImportSubsystem = GEditor->GetEditorSubsystem<UImportSubsystem>())
#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/Widgets/SNiagaraSystemViewport.cpp:778
Scope (from outer to inner):
file
function void SNiagaraSystemViewport::Construct
Source code excerpt:
// Register for preview feature level changes
if (UEditorEngine* EditorEngine = Cast<UEditorEngine>(GEngine))
{
OnPreviewFeatureLevelChangedHandle = EditorEngine->OnPreviewFeatureLevelChanged().AddLambda(
[WeakWorld=TWeakObjectPtr<UWorld>(Client->GetWorld())](ERHIFeatureLevel::Type NewFeatureLevel)
{
if (UWorld* World = WeakWorld.Get())
{
World->ChangeFeatureLevel(NewFeatureLevel);
}
#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/Widgets/SNiagaraSystemViewport.cpp:796
Scope (from outer to inner):
file
function SNiagaraSystemViewport::~SNiagaraSystemViewport
Source code excerpt:
if (OnPreviewFeatureLevelChangedHandle.IsValid())
{
if (UEditorEngine* EditorEngine = Cast<UEditorEngine>(GEngine))
{
EditorEngine->OnPreviewFeatureLevelChanged().Remove(OnPreviewFeatureLevelChangedHandle);
}
}
if (SystemViewportClient.IsValid())
{
SystemViewportClient->Viewport = NULL;
#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Import/Private/Scene/InterchangeActorHelper.cpp:65
Scope (from outer to inner):
file
function AActor* UE::Interchange::ActorHelper::SpawnFactoryActor
lambda-function
Source code excerpt:
if (DefaultWorld == nullptr)
{
UEditorEngine* EditorEngine = Cast<UEditorEngine>(GEngine);
if (GIsEditor && EditorEngine != nullptr)
{
DefaultWorld = EditorEngine->GetEditorWorldContext().World();
}
}
#endif
if (DefaultWorld == nullptr && GEngine)
{
DefaultWorld = GEngine->GetWorld();
#Loc: <Workspace>/Engine/Plugins/Media/MediaFrameworkUtilities/Source/MediaFrameworkUtilitiesEditor/Private/CaptureTab/SMediaFrameworkCaptureOutputWidget.cpp:581
Scope (from outer to inner):
file
function void SMediaFrameworkCaptureCurrentViewportWidget::StartOutput
Source code excerpt:
if (Context.WorldType == EWorldType::PIE)
{
UEditorEngine* EditorEngine = CastChecked<UEditorEngine>(GEngine);
FSlatePlayInEditorInfo& Info = EditorEngine->SlatePlayInEditorMap.FindChecked(Context.ContextHandle);
if (Info.SlatePlayInEditorWindowViewport.IsValid())
{
SceneViewport = Info.SlatePlayInEditorWindowViewport;
}
}
}
#Loc: <Workspace>/Engine/Plugins/Media/MediaIOFramework/Source/MediaIOCore/Private/MediaCapture.cpp:1586
Scope (from outer to inner):
file
namespace MediaCaptureDetails
function bool FindSceneViewportAndLevel
Source code excerpt:
if (Context.WorldType == EWorldType::PIE)
{
UEditorEngine* EditorEngine = CastChecked<UEditorEngine>(GEngine);
FSlatePlayInEditorInfo& Info = EditorEngine->SlatePlayInEditorMap.FindChecked(Context.ContextHandle);
// The PIE window has priority over the regular editor window, so we need to break out of the loop if either of these are found
if (TSharedPtr<IAssetViewport> DestinationLevelViewport = Info.DestinationSlateViewport.Pin())
{
OutSceneViewport = DestinationLevelViewport->GetSharedActiveViewport();
break;
#Loc: <Workspace>/Engine/Plugins/Runtime/HairStrands/Source/HairStrandsEditor/Private/HairStrandsEditor.cpp:209
Scope (from outer to inner):
file
function void FGroomEditor::OnPostEngineInit
Source code excerpt:
if (GEditor)
{
UEditorEngine* EditorEngine = CastChecked<UEditorEngine>(GEngine);
PreviewPlatformChangedHandle = EditorEngine->OnPreviewPlatformChanged().AddRaw(this, &FGroomEditor::OnPreviewPlatformChanged);
PreviewFeatureLevelChangedHandle = EditorEngine->OnPreviewFeatureLevelChanged().AddRaw(this, &FGroomEditor::OnPreviewFeatureLevelChanged);
}
}
void FGroomEditor::OnPreExit()
{
if (GEditor)
#Loc: <Workspace>/Engine/Plugins/Runtime/HairStrands/Source/HairStrandsEditor/Private/HairStrandsEditor.cpp:227
Scope (from outer to inner):
file
function void FGroomEditor::OnPreviewPlatformChanged
Source code excerpt:
{
#if WITH_EDITOR
UEditorEngine* EditorEngine = CastChecked<UEditorEngine>(GEngine);
ERHIFeatureLevel::Type ActiveFeatureLevel = EditorEngine->GetDefaultWorldFeatureLevel();
if (EditorEngine->IsFeatureLevelPreviewActive())
{
ActiveFeatureLevel = EditorEngine->GetActiveFeatureLevelPreviewType();
}
for (TObjectIterator<UGroomComponent> It; It; ++It)
{
if (UGroomComponent* Component = *It)
{
#Loc: <Workspace>/Engine/Plugins/Runtime/HairStrands/Source/HairStrandsEditor/Private/HairStrandsEditor.cpp:247
Scope (from outer to inner):
file
function void FGroomEditor::OnPreviewFeatureLevelChanged
Source code excerpt:
{
#if WITH_EDITOR
UEditorEngine* EditorEngine = CastChecked<UEditorEngine>(GEngine);
ERHIFeatureLevel::Type ActiveFeatureLevel = EditorEngine->GetDefaultWorldFeatureLevel();
if (EditorEngine->IsFeatureLevelPreviewActive())
{
ActiveFeatureLevel = EditorEngine->GetActiveFeatureLevelPreviewType();
}
for (TObjectIterator<UGroomComponent> It; It; ++It)
{
if (UGroomComponent* Component = *It)
{
#Loc: <Workspace>/Engine/Plugins/Runtime/OpenXR/Source/OpenXRHMD/Private/OpenXRHMD.cpp:147
Scope (from outer to inner):
file
namespace anonymous
function FSceneViewport* FindSceneViewport
Source code excerpt:
else
{
UEditorEngine* EditorEngine = CastChecked<UEditorEngine>(GEngine);
FSceneViewport* PIEViewport = (FSceneViewport*)EditorEngine->GetPIEViewport();
if (PIEViewport != nullptr && PIEViewport->IsStereoRenderingAllowed())
{
// PIE is setup for stereo rendering
return PIEViewport;
}
else
#Loc: <Workspace>/Engine/Plugins/Runtime/OpenXR/Source/OpenXRHMD/Private/OpenXRHMD.cpp:158
Scope (from outer to inner):
file
namespace anonymous
function FSceneViewport* FindSceneViewport
Source code excerpt:
// Check to see if the active editor viewport is drawing in stereo mode
// @todo vreditor: Should work with even non-active viewport!
FSceneViewport* EditorViewport = (FSceneViewport*)EditorEngine->GetActiveViewport();
if (EditorViewport != nullptr && EditorViewport->IsStereoRenderingAllowed())
{
return EditorViewport;
}
}
}
#Loc: <Workspace>/Engine/Source/Developer/BSPUtils/Private/BSPUtils.cpp:19
Scope: file
Source code excerpt:
#include "GameFramework/Actor.h"
#include "Engine/Brush.h"
//#include "Editor/EditorEngine.h"
//#include "EdMode.h"
//#include "EditorModeManager.h"
#include "SurfaceIterators.h"
//#include "ActorEditorUtils.h"
#include "Misc/FeedbackContext.h"
#include "EngineUtils.h"
#Loc: <Workspace>/Engine/Source/Developer/FunctionalTesting/Private/AutomationBlueprintFunctionLibrary.cpp:376
Scope (from outer to inner):
file
class class FAutomationScreenshotTaker
function FAutomationScreenshotTaker
Source code excerpt:
#if WITH_EDITOR
// In the editor we can only attempt to re-size standalone viewports
UEditorEngine* EditorEngine = Cast<UEditorEngine>(GEngine);
const bool bIsPIEViewport = GameViewport->IsPlayInEditorViewport();
const bool bIsNewViewport = GameViewportClient->GetWorld() && EditorEngine && EditorEngine->WorldIsPIEInNewViewport(GameViewportClient->GetWorld());
if (!bIsPIEViewport || bIsNewViewport)
#endif
{
ViewportRestoreSize = GameViewport->GetSize();
FIntPoint ScreenshotViewportSize = UAutomationBlueprintFunctionLibrary::GetAutomationScreenshotSize(InOptions);
#Loc: <Workspace>/Engine/Source/Developer/FunctionalTesting/Private/ScreenshotFunctionalTestBase.cpp:122
Scope (from outer to inner):
file
function void AScreenshotFunctionalTestBase::PrepareForScreenshot
Source code excerpt:
// In the editor we can only attempt to resize a standalone viewport
UWorld* World = GameViewportClient->GetWorld();
UEditorEngine* EditorEngine = Cast<UEditorEngine>(GEngine);
const bool bIsPIEViewport = GameViewport->IsPlayInEditorViewport();
const bool bIsNewViewport = World && EditorEngine && EditorEngine->WorldIsPIEInNewViewport(World);
bApplyScreenshotSettings = !bIsPIEViewport || bIsNewViewport;
#endif
if (bApplyScreenshotSettings)
{
#Loc: <Workspace>/Engine/Source/Editor/DetailCustomizations/Private/ObjectDetails.cpp:287
Scope (from outer to inner):
file
function FReply FObjectDetails::OnExecuteCallInEditorFunction
Source code excerpt:
FEditorScriptExecutionGuard ScriptGuard;
extern ENGINE_API class UEngine* GEngine;
UEditorEngine* EditorEngine = Cast<UEditorEngine>(GEngine);
UObject* WorldContextObject = EditorEngine->GetEditorWorldContext().World();
TStrongObjectPtr<UObject> CDO(Function->GetOwnerClass()->ClassDefaultObject);
CDO->ProcessEvent(Function, &WorldContextObject);
}
else
{
FEditorScriptExecutionGuard ScriptGuard;
#Loc: <Workspace>/Engine/Source/Editor/Kismet/Private/BlueprintEditor.cpp:4079
Scope (from outer to inner):
file
function void FBlueprintEditor::OnBlueprintCompiled
Source code excerpt:
if( InBlueprint )
{
UUnrealEdEngine* EditorEngine = GUnrealEd;
// GUnrealEd can be nullptr after a hot-reload... this seems like a bigger
// problem worth investigating (that could affect other systems), but
// as I cannot repro it a second time (to see if it gets reset soon after),
// we'll just gaurd here for now and see if we can tie this ensure to any
// future crash reports
if (ensure(EditorEngine != nullptr))
{
// Compiling will invalidate any cached components in the component visualizer, so clear out active components here
EditorEngine->ComponentVisManager.ClearActiveComponentVis();
}
// This could be made more efficient by tracking which nodes change
// their bHasCompilerMessage flag, or immediately updating the error info
// when we assign the flag:
TArray<UEdGraph*> Graphs;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/PlayLevel.cpp:2795
Scope (from outer to inner):
file
function void UEditorEngine::StartPlayInEditorSession
Source code excerpt:
const bool bNeedsServer = bNetModeRequiresSeparateServer || bLaunchExtraServerAnyways;
// If they require a separate server we'll give the EditorEngine a chance to handle any additional prep-work.
if (bNeedsServer)
{
// Allow the engine to cancel the server request if needed.
FGameInstancePIEResult ServerPreCreateResult = PreCreatePIEServerInstance(
ErroredBlueprints.Num() > 0, false /*bStartInSpectorMode*/, PIEStartTime, true, PlayInEditorSessionInfo->NumOutstandingPIELogins);
if (!ServerPreCreateResult.IsSuccess())
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/Engine.h:322
Scope: file
Source code excerpt:
*
* For the GameEngine, there will be one WorldContext until we decide to support multiple simultaneous worlds.
* For the EditorEngine, there may be one WorldContext for the EditorWorld and one for the PIE World.
*
* FWorldContext provides both a way to manage 'the current PIE UWorld*' as well as state that goes along with connecting/travelling to
* new worlds.
*
* FWorldContext should remain internal to the UEngine classes. Outside code should not keep pointers or try to manage FWorldContexts directly.
* Outside code can still deal with UWorld*, and pass UWorld*s into Engine level functions. The Engine code can look up the relevant context
* for a given UWorld*.
*
* For convenience, FWorldContext can maintain outside pointers to UWorld*s. For example, PIE can tie UWorld* UEditorEngine::PlayWorld to the PIE
* world context. If the PIE UWorld changes, the UEditorEngine::PlayWorld pointer will be automatically updated. This is done with AddRef() and
* SetCurrentWorld().
*
*/
USTRUCT()
struct FWorldContext
{
GENERATED_USTRUCT_BODY()
/**************************************************************/
TEnumAsByte<EWorldType::Type> WorldType;
FSeamlessTravelHandler SeamlessTravelHandler;
FName ContextHandle;
/** URL to travel to for pending client connect */
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/Engine.h:2960
Scope: file
Source code excerpt:
ENGINE_API virtual bool UseSound() const;
// This should only ever be called for a EditorEngine
virtual UWorld* CreatePIEWorldByDuplication(FWorldContext &Context, UWorld* InWorld, FString &PlayWorldMapName) { check(false); return nullptr; }
virtual void PostCreatePIEWorld(UWorld* InWorld) { check(false); }
/**
* If this function returns true, the DynamicSourceLevels collection will be duplicated for the given map.
* This is necessary to do outside of the editor when we don't have the original editor world, and it's
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/GameInstance.cpp:280
Scope (from outer to inner):
file
function FGameInstancePIEResult UGameInstance::InitializeForPlayInEditor
Source code excerpt:
FWorldDelegates::OnPIEMapCreated.Broadcast(this);
UEditorEngine* const EditorEngine = CastChecked<UEditorEngine>(GetEngine());
// Look for an existing pie world context, may have been created before
WorldContext = EditorEngine->GetWorldContextFromPIEInstance(PIEInstanceIndex);
if (!WorldContext)
{
// If not, create a new one
WorldContext = &EditorEngine->CreateNewWorldContext(EWorldType::PIE);
WorldContext->PIEInstance = PIEInstanceIndex;
}
WorldContext->PIEWorldFeatureLevel = Params.WorldFeatureLevel;
WorldContext->RunAsDedicated = Params.bRunAsDedicated;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/GameInstance.cpp:300
Scope (from outer to inner):
file
function FGameInstancePIEResult UGameInstance::InitializeForPlayInEditor
Source code excerpt:
WorldContext->OwningGameInstance = this;
UWorld* EditorWorld = EditorEngine->GetEditorWorldContext().World();
const FString WorldPackageName = EditorWorld->GetOutermost()->GetName();
// Establish World Context for PIE World
WorldContext->LastURL.Map = WorldPackageName;
WorldContext->PIEPrefix = WorldContext->PIEInstance != INDEX_NONE ? UWorld::BuildPIEPackagePrefix(WorldContext->PIEInstance) : FString();
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/GameInstance.cpp:316
Scope (from outer to inner):
file
function FGameInstancePIEResult UGameInstance::InitializeForPlayInEditor
Source code excerpt:
{
// We are going to connect, so just load an empty world
NewWorld = EditorEngine->CreatePIEWorldFromEntry(*WorldContext, EditorWorld, PIEMapName);
}
else
{
if (Params.OverrideMapURL.Len() > 0)
{
// Attempt to load the target world asset
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/GameInstance.cpp:328
Scope (from outer to inner):
file
function FGameInstancePIEResult UGameInstance::InitializeForPlayInEditor
Source code excerpt:
{
WorldToDuplicate->ChangeFeatureLevel(EditorWorld->GetFeatureLevel(), false);
NewWorld = EditorEngine->CreatePIEWorldByDuplication(*WorldContext, WorldToDuplicate, PIEMapName);
}
}
else
{
// Standard PIE path: just duplicate the EditorWorld
NewWorld = EditorEngine->CreatePIEWorldByDuplication(*WorldContext, EditorWorld, PIEMapName);
}
// Duplication can result in unreferenced objects, so indicate that we should do a GC pass after initializing the world context
bNeedsGarbageCollection = true;
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/GameInstance.cpp:350
Scope (from outer to inner):
file
function FGameInstancePIEResult UGameInstance::InitializeForPlayInEditor
Source code excerpt:
NewWorld->SetGameInstance(this);
WorldContext->SetCurrentWorld(NewWorld);
WorldContext->AddRef(static_cast<UWorld*&>(EditorEngine->PlayWorld)); // Tie this context to this UEngine::PlayWorld* // @fixme, needed still?
NewWorld->bKismetScriptError = Params.bAnyBlueprintErrors;
// Do a GC pass if necessary to remove any potentially unreferenced objects
if(bNeedsGarbageCollection)
{
CollectGarbage(GARBAGE_COLLECTION_KEEPFLAGS);
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/GameInstance.cpp:364
Scope (from outer to inner):
file
function FGameInstancePIEResult UGameInstance::InitializeForPlayInEditor
Source code excerpt:
// Initialize the world after setting world context and initializing the game instance to be consistent with normal loads.
// This creates the world subsystems and prepares to begin play
EditorEngine->PostCreatePIEWorld(NewWorld);
FWorldDelegates::OnPIEMapReady.Broadcast(this);
// Games can override this to return failure if PIE is not allowed for some reason
return FGameInstancePIEResult::Success();
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/GameInstance.cpp:408
Scope (from outer to inner):
file
function FGameInstancePIEResult UGameInstance::StartPlayInEditorGameInstance
Source code excerpt:
BroadcastOnStart();
UEditorEngine* const EditorEngine = CastChecked<UEditorEngine>(GetEngine());
// for clients, just connect to the server
if (Params.NetMode == PIE_Client)
{
FString Error;
FURL BaseURL = WorldContext->LastURL;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/GameInstance.cpp:431
Scope (from outer to inner):
file
function FGameInstancePIEResult UGameInstance::StartPlayInEditorGameInstance
Source code excerpt:
}
if (EditorEngine->Browse(*WorldContext, FURL(&BaseURL, *URLString, (ETravelType)TRAVEL_Absolute), Error) == EBrowseReturnVal::Pending)
{
EditorEngine->TransitionType = ETransitionType::WaitingToConnect;
}
else
{
return FGameInstancePIEResult::Failure(FText::Format(NSLOCTEXT("UnrealEd", "Error_CouldntLaunchPIEClient", "Couldn't Launch PIE Client: {0}"), FText::FromString(Error)));
}
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/GameInstance.cpp:464
Scope (from outer to inner):
file
function FGameInstancePIEResult UGameInstance::StartPlayInEditorGameInstance
Source code excerpt:
FURL URL;
// If the user wants to start in spectator mode, do not use the custom play world for now
if (EditorEngine->UserEditedPlayWorldURL.Len() > 0 || Params.OverrideMapURL.Len() > 0)
{
FString UserURL = EditorEngine->UserEditedPlayWorldURL.Len() > 0 ? EditorEngine->UserEditedPlayWorldURL : Params.OverrideMapURL;
UserURL += ExtraURLOptions;
// If the user edited the play world url. Verify that the map name is the same as the currently loaded map.
URL = FURL(NULL, *UserURL, TRAVEL_Absolute);
if (URL.Map != PIEMapName)
{
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/GameInstance.cpp:480
Scope (from outer to inner):
file
function FGameInstancePIEResult UGameInstance::StartPlayInEditorGameInstance
Source code excerpt:
{
// The user did not edit the url, just build one from scratch.
URL = FURL(NULL, *EditorEngine->BuildPlayWorldURL(*PIEMapName, Params.bStartInSpectatorMode, ExtraURLOptions), TRAVEL_Absolute);
}
// Save our URL for later map travels
SetPersistentTravelURL(URL);
// If a start location is specified, spawn a temporary PlayerStartPIE actor at the start location and use it as the portal.
AActor* PlayerStart = NULL;
if (!EditorEngine->SpawnPlayFromHereStart(PlayWorld, PlayerStart))
{
// failed to create "play from here" playerstart
return FGameInstancePIEResult::Failure(NSLOCTEXT("UnrealEd", "Error_FailedCreatePlayFromHerePlayerStart", "Failed to create PlayerStart at desired starting location."));
}
if (!PlayWorld->SetGameMode(URL))
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/LevelTick.cpp:1301
Scope (from outer to inner):
file
function void UWorld::Tick
Source code excerpt:
SCOPE_CYCLE_COUNTER(STAT_WorldTickTime);
// @todo vreditor: In the VREditor, this isn't actually wrapping the whole frame. That would have to happen in EditorEngine.cpp's Tick. However, it didn't seem to affect anything when I tried that.
if (GEngine->XRSystem.IsValid())
{
GEngine->XRSystem->OnStartGameFrame( GEngine->GetWorldContextFromWorldChecked( this ) );
}
#if ENABLE_SPAWNACTORTIMER
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/PreviewScene.cpp:47
Scope (from outer to inner):
file
function FPreviewScene::FPreviewScene
Source code excerpt:
FURL URL = FURL();
//URL += TEXT("?SpectatorOnly=1");
//URL = FURL(NULL, *EditorEngine->BuildPlayWorldURL(*PIEMapName, Params.bStartInSpectatorMode, ExtraURLOptions), TRAVEL_Absolute);
if (CVS.OwningGameInstance && PreviewWorld->WorldType == EWorldType::GamePreview)
{
PreviewWorld->SetGameInstance(CVS.OwningGameInstance);
FWorldContext& PreviewWorldContext = GEngine->GetWorldContextFromWorldChecked(PreviewWorld);
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/VisualLogger/VisualLogger.cpp:265
Scope (from outer to inner):
file
function double FVisualLogger::GetTimeStampForObject
Source code excerpt:
#if WITH_EDITOR
// When we're in the Editor, use a Global Engine TimeStamp so that we can synchronize between Client and Server instances.
UEditorEngine* EditorEngine = GIsEditor ? Cast<UEditorEngine>(GEngine) : nullptr;
if (EditorEngine)
{
// We will always have the Editor world to use. This will ensure a consistent clock since it does not reset
// when more clients are added or removed and can exist before a PIE session is started.
WorldForTimeStamp = EditorEngine->GetEditorWorldContext().World();
if (ensureMsgf(WorldForTimeStamp, TEXT("We always expect to have an EditorWorld in Editor")))
{
using namespace UE::VisLog::Private;
if (EditorOnly::EditorBaseTimeStamp <= 0.0)
{
EditorOnly::EditorBaseTimeStamp = WorldForTimeStamp->TimeSeconds;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/VisualLogger/VisualLogger.cpp:818
Scope (from outer to inner):
file
function void FVisualLogger::OnDataReset
Source code excerpt:
#if WITH_EDITOR
UEditorEngine* EditorEngine = GIsEditor ? Cast<UEditorEngine>(GEngine) : nullptr;
if (EditorEngine)
{
const UWorld* EditorWorld = EditorEngine->GetEditorWorldContext().World();
if (EditorWorld)
{
// Reset the base timestamp to zero so the next (aka first) log entry will set this variable to determine the global offset in GetTimeStampForObject
// This ensures that when you start recording, the first entry appears to be at 0.0 (computed as TimeStamp - EditorBaseTimeStamp)
EditorOnly::EditorBaseTimeStamp = 0.0;
}
#Loc: <Workspace>/Engine/Source/Runtime/Launch/Private/LaunchEngineLoop.cpp:4115
Scope (from outer to inner):
file
function int32 FEngineLoop::PreInitPostStartupScreen
Source code excerpt:
{
FString EditorEngineClassName;
GConfig->GetString(TEXT("/Script/Engine.Engine"), TEXT("EditorEngine"), EditorEngineClassName, GEngineIni);
UClass* EditorEngineClass = StaticLoadClass( UEditorEngine::StaticClass(), nullptr, *EditorEngineClassName);
if (EditorEngineClass == nullptr)
{
UE_LOG(LogInit, Fatal, TEXT("Failed to load Editor Engine class '%s'."), *EditorEngineClassName);
}