├── .github └── FUNDING.yml ├── .gitignore ├── Resources └── Icon128.png ├── Config └── FilterPlugin.ini ├── Source └── EditorCameraPosition │ ├── Public │ ├── EditorCameraPositionCommands.h │ ├── Widgets │ │ ├── SEditorCopyPasteBoxWidget.h │ │ ├── SEditorCameraPositionViewportToolBar.h │ │ ├── SEditorCameraRotationViewportToolBar.h │ │ └── SEditorCameraViewportToolBar.h │ ├── EditorCameraPositionUtils.h │ ├── EditorCameraPositionTypes.h │ ├── EditorCameraPositionSettings.h │ └── EditorCameraPositionModule.h │ ├── Private │ ├── Widgets │ │ ├── SEditorCameraPositionViewportToolBar.cpp │ │ ├── SEditorCameraRotationViewportToolBar.cpp │ │ ├── SEditorCameraViewportToolBar.cpp │ │ └── SEditorCopyPasteBoxWidget.cpp │ ├── EditorCameraPositionCommands.cpp │ ├── EditorCameraPositionSettings.cpp │ ├── EditorCameraPositionUtils.cpp │ └── EditorCameraPositionModule.cpp │ └── EditorCameraPosition.Build.cs ├── EditorCameraPosition.uplugin ├── LICENSE ├── Changelog.txt └── README.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: zompi2 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Binaries 2 | Intermediate -------------------------------------------------------------------------------- /Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zompi2/EditorCameraPositionUE4/HEAD/Resources/Icon128.png -------------------------------------------------------------------------------- /Config/FilterPlugin.ini: -------------------------------------------------------------------------------- 1 | ; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and 2 | ; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively. 3 | 4 | [FilterPlugin] 5 | /README.md 6 | /Changelog.txt -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Public/EditorCameraPositionCommands.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Framework/Commands/Commands.h" 7 | 8 | class EDITORCAMERAPOSITION_API FEditorCameraPositionCommands : public TCommands 9 | { 10 | public: 11 | 12 | FEditorCameraPositionCommands(); 13 | void RegisterCommands() override; 14 | 15 | public: 16 | 17 | TSharedPtr ToggleShowCameraPosWidget; 18 | TSharedPtr ToggleShowCameraRotWidget; 19 | }; 20 | -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Public/Widgets/SEditorCopyPasteBoxWidget.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #pragma once 4 | 5 | #include "Widgets/Layout/SBox.h" 6 | #include "EditorCameraPositionTypes.h" 7 | 8 | class EDITORCAMERAPOSITION_API SEditorCopyPasteBoxWidget : public SBox 9 | { 10 | 11 | public: 12 | 13 | FOnCameraPosOrRotCopyPasteEvent OnCopy; 14 | FOnCameraPosOrRotCopyPasteEvent OnPaste; 15 | 16 | protected: 17 | FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; 18 | 19 | private: 20 | void CreateContextMenu(const FVector2D& mousePosition); 21 | }; 22 | -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Private/Widgets/SEditorCameraPositionViewportToolBar.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #include "Widgets/SEditorCameraPositionViewportToolBar.h" 4 | 5 | void SEditorCameraPositionViewportToolBar::Construct(const FArguments& Args) 6 | { 7 | OnCopy = Args._OnCopy; 8 | OnPaste = Args._OnPaste; 9 | 10 | ChildSlot 11 | [ 12 | SNew(VectorInputBoxType) 13 | .bColorAxisLabels(true) 14 | #if (ENGINE_MAJOR_VERSION == 4) 15 | .AllowResponsiveLayout(true) 16 | #endif 17 | .AllowSpin(true) 18 | .SpinDelta(1) 19 | .X(Args._X) 20 | .Y(Args._Y) 21 | .Z(Args._Z) 22 | .OnXChanged(Args._OnXChanged) 23 | .OnYChanged(Args._OnYChanged) 24 | .OnZChanged(Args._OnZChanged) 25 | ]; 26 | } 27 | -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Private/Widgets/SEditorCameraRotationViewportToolBar.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #include "Widgets/SEditorCameraRotationViewportToolBar.h" 4 | 5 | void SEditorCameraRotationViewportToolBar::Construct(const FArguments& Args) 6 | { 7 | OnCopy = Args._OnCopy; 8 | OnPaste = Args._OnPaste; 9 | 10 | ChildSlot 11 | [ 12 | SNew(RotatorInputBoxType) 13 | .bColorAxisLabels(true) 14 | #if (ENGINE_MAJOR_VERSION == 4) 15 | .AllowResponsiveLayout(true) 16 | #endif 17 | .AllowSpin(true) 18 | #if (ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 4) 19 | .SpinDelta(1.f) 20 | #endif 21 | .Roll(Args._Roll) 22 | .Pitch(Args._Pitch) 23 | .Yaw(Args._Yaw) 24 | .OnRollChanged(Args._OnRollChanged) 25 | .OnPitchChanged(Args._OnPitchChanged) 26 | .OnYawChanged(Args._OnYawChanged) 27 | ]; 28 | } 29 | -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Public/Widgets/SEditorCameraPositionViewportToolBar.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #pragma once 4 | 5 | #include "SEditorCopyPasteBoxWidget.h" 6 | 7 | class EDITORCAMERAPOSITION_API SEditorCameraPositionViewportToolBar : public SEditorCopyPasteBoxWidget 8 | { 9 | 10 | public: 11 | SLATE_BEGIN_ARGS(SEditorCameraPositionViewportToolBar) {} 12 | SLATE_ATTRIBUTE(TOptional, X) 13 | SLATE_ATTRIBUTE(TOptional, Y) 14 | SLATE_ATTRIBUTE(TOptional, Z) 15 | SLATE_EVENT(OnVectorValueChangedDelegateType, OnXChanged) 16 | SLATE_EVENT(OnVectorValueChangedDelegateType, OnYChanged) 17 | SLATE_EVENT(OnVectorValueChangedDelegateType, OnZChanged) 18 | SLATE_EVENT(FOnCameraPosOrRotCopyPasteEvent, OnCopy) 19 | SLATE_EVENT(FOnCameraPosOrRotCopyPasteEvent, OnPaste) 20 | SLATE_END_ARGS() 21 | 22 | void Construct(const FArguments& Args); 23 | }; 24 | -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Public/EditorCameraPositionUtils.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "UObject/Object.h" 7 | #include "EditorCameraPositionUtils.generated.h" 8 | 9 | UCLASS() 10 | class EDITORCAMERAPOSITION_API UEditorCameraPositionUtils : public UObject 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | 16 | UFUNCTION(BlueprintPure, Category = "Editor Camera Position") 17 | static FVector GetEditorCameraPosition(); 18 | 19 | UFUNCTION(BlueprintCallable, Category = "Editor Camera Position") 20 | static void SetEditorCameraPosition(const FVector& NewEditorCameraPosition); 21 | 22 | UFUNCTION(BlueprintPure, Category = "Editor Camera Position") 23 | static FRotator GetEditorCameraRotation(); 24 | 25 | UFUNCTION(BlueprintCallable, Category = "Editor Camera Position") 26 | static void SetEditorCameraRotation(const FRotator& NewEditorCameraRotation); 27 | }; 28 | -------------------------------------------------------------------------------- /Source/EditorCameraPosition/EditorCameraPosition.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class EditorCameraPosition : ModuleRules 6 | { 7 | public EditorCameraPosition(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PrivateIncludePaths.Add("EditorCameraPosition/Private"); 12 | 13 | PublicDependencyModuleNames.AddRange( 14 | new string[] 15 | { 16 | "Core", 17 | "InputCore" 18 | } 19 | ); 20 | 21 | PrivateDependencyModuleNames.AddRange( 22 | new string[] 23 | { 24 | "Engine", 25 | "CoreUObject", 26 | "Slate", 27 | "SlateCore", 28 | "UnrealEd", 29 | "EditorStyle", 30 | "Projects", 31 | "LevelEditor", 32 | "ApplicationCore", 33 | "ToolMenus", 34 | "DeveloperSettings" 35 | } 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Public/Widgets/SEditorCameraRotationViewportToolBar.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #pragma once 4 | 5 | #include "SEditorCopyPasteBoxWidget.h" 6 | 7 | class EDITORCAMERAPOSITION_API SEditorCameraRotationViewportToolBar : public SEditorCopyPasteBoxWidget 8 | { 9 | 10 | public: 11 | SLATE_BEGIN_ARGS(SEditorCameraRotationViewportToolBar) {} 12 | SLATE_ATTRIBUTE(TOptional, Roll) 13 | SLATE_ATTRIBUTE(TOptional, Pitch) 14 | SLATE_ATTRIBUTE(TOptional, Yaw) 15 | SLATE_EVENT(OnRotatorValueChangedDelegateType, OnRollChanged) 16 | SLATE_EVENT(OnRotatorValueChangedDelegateType, OnPitchChanged) 17 | SLATE_EVENT(OnRotatorValueChangedDelegateType, OnYawChanged) 18 | SLATE_EVENT(FOnCameraPosOrRotCopyPasteEvent, OnCopy) 19 | SLATE_EVENT(FOnCameraPosOrRotCopyPasteEvent, OnPaste) 20 | SLATE_END_ARGS() 21 | 22 | void Construct(const FArguments& Args); 23 | }; 24 | -------------------------------------------------------------------------------- /EditorCameraPosition.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 1, 4 | "VersionName": "1.1.3", 5 | "FriendlyName": "EditorCameraPosition", 6 | "Description": "Simple tool that displays and sets camera position in editor viewport", 7 | "Category": "Cameras", 8 | "CreatedBy": "Damian Nowakowski", 9 | "CreatedByURL": "https://zompidev.blogspot.com", 10 | "DocsURL": "https://github.com/zompi2/EditorCameraPositionUE4", 11 | "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/9864b623739f4fbab30f4d877b137fc9", 12 | "FabURL": "com.epicgames.launcher://ue/Fab/product/d18dfdcf-ef99-4751-bde8-1f652ce2b986", 13 | "SupportURL": "mailto:zompi2@gmail.com", 14 | "CanContainContent": false, 15 | "IsBetaVersion": false, 16 | "IsExperimentalVersion": false, 17 | "Installed": true, 18 | "Modules": [ 19 | { 20 | "Name": "EditorCameraPosition", 21 | "Type": "Editor", 22 | "LoadingPhase": "PostEngineInit", 23 | "PlatformAllowList": [ 24 | "Win64" 25 | ] 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Damian Nowakowski 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Changelog.txt: -------------------------------------------------------------------------------- 1 | ###### 1.1.3 2 | * Fixes required for Unreal Engine 5.6 3 | 4 | ###### 1.1.2 5 | * Fixed module LoadingPhase 6 | 7 | ###### 1.1.1 8 | * Updated uplugin to support FAB 9 | 10 | ###### 1.1.0 11 | * Added option to show/modify/copy/paste the editor camera rotation as well. 12 | * Added settings in Editor Preferences for enabling/disabling editor camera position/rotation functions 13 | and for changing the way the values are truncated. 14 | * GetEditorCameraRotation and SetEditorCameraRotation Blueprint functions for Editor Utility Blueprints added. 15 | 16 | ###### 1.0.6 17 | * GetEditorCameraPosition and SetEditorCameraPosition Blueprint functions for Editor Utility Blueprints added. 18 | 19 | ###### 1.0.5 20 | * Fixed setting up coordinates when piloting camera. 21 | 22 | ###### 1.0.4 23 | * Added support for large world coordinates. 24 | 25 | ###### 1.0.3 26 | * Moved editor config to the default ini file. The project based ini file edition doesn't work for UE5.4. 27 | * Truncate camera position in the camera position box. 28 | 29 | ###### 1.0.2 30 | * Fixed the keyboard shortcut to toggle camera position box. 31 | 32 | ###### 1.0.1 33 | * Fixes for UE5. -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Private/EditorCameraPositionCommands.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #include "EditorCameraPositionCommands.h" 4 | 5 | #define LOCTEXT_NAMESPACE "EditorCameraPosition" 6 | 7 | FEditorCameraPositionCommands::FEditorCameraPositionCommands() 8 | : TCommands( 9 | TEXT("Editor Camera Position Tool Commands"), 10 | FText::FromString(TEXT("Commands to control Editor Camera Position Tool")), 11 | NAME_None, 12 | #if ((ENGINE_MAJOR_VERSION == 5) && (ENGINE_MINOR_VERSION >= 1)) 13 | FAppStyle::GetAppStyleSetName() 14 | #else 15 | FEditorStyle::GetStyleSetName() 16 | #endif 17 | ) 18 | {} 19 | 20 | void FEditorCameraPositionCommands::RegisterCommands() 21 | { 22 | UI_COMMAND(ToggleShowCameraPosWidget, "Toggle Camera Position", "Toggles if to show the camera position get/set toolbar in viewport.", EUserInterfaceActionType::ToggleButton, FInputChord(EModifierKey::Shift | EModifierKey::Alt, EKeys::C)); 23 | UI_COMMAND(ToggleShowCameraRotWidget, "Toggle Camera Rotation", "Toggles if to show the camera rotation get/set toolbar in viewport.", EUserInterfaceActionType::ToggleButton, FInputChord(EModifierKey::Shift | EModifierKey::Alt, EKeys::X)); 24 | } 25 | 26 | #undef LOCTEXT_NAMESPACE 27 | -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Public/EditorCameraPositionTypes.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Runtime/Launch/Resources/Version.h" 7 | #include "Widgets/Input/SVectorInputBox.h" 8 | #include "Widgets/Input/SRotatorInputBox.h" 9 | #include "EditorCameraPositionTypes.generated.h" 10 | 11 | UENUM() 12 | enum class EEditorCameraPositionTruncType 13 | { 14 | NoTrunc, 15 | TwoDecimals, 16 | ZeroDecimals 17 | }; 18 | 19 | DECLARE_DELEGATE(FOnCameraPosOrRotCopyPasteEvent); 20 | 21 | #if (ENGINE_MAJOR_VERSION == 5) 22 | using VectorValueType = FVector::FReal; 23 | using VectorInputBoxType = SNumericVectorInputBox; 24 | using OnVectorValueChangedDelegateType = SNumericVectorInputBox::FOnNumericValueChanged; 25 | 26 | using RotatorValueType = FRotator::FReal; 27 | using RotatorInputBoxType = SNumericRotatorInputBox; 28 | using OnRotatorValueChangedDelegateType = SNumericRotatorInputBox::FOnNumericValueChanged; 29 | #else 30 | using VectorValueType = float; 31 | using VectorInputBoxType = SVectorInputBox; 32 | using OnVectorValueChangedDelegateType = FOnFloatValueChanged; 33 | 34 | using RotatorValueType = float; 35 | using RotatorInputBoxType = SRotatorInputBox; 36 | using OnRotatorValueChangedDelegateType = FOnFloatValueChanged; 37 | #endif -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Private/Widgets/SEditorCameraViewportToolBar.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #include "Widgets/SEditorCameraViewportToolBar.h" 4 | #include "Widgets/SEditorCameraPositionViewportToolBar.h" 5 | #include "Widgets/SEditorCameraRotationViewportToolBar.h" 6 | 7 | void SEditorCameraViewportToolBar::Construct(const FArguments& Args) 8 | { 9 | ChildSlot 10 | [ 11 | SNew(SBox) 12 | .WidthOverride(256) 13 | .HeightOverride(0) 14 | .VAlign(VAlign_Top) 15 | #if (ENGINE_MAJOR_VERSION == 4) 16 | .Padding(FMargin(0.f, -24.f, 0.f, 0.f)) 17 | #endif 18 | [ 19 | SNew(SVerticalBox) 20 | +SVerticalBox::Slot() 21 | .AutoHeight() 22 | [ 23 | SNew(SEditorCameraPositionViewportToolBar) 24 | .Visibility(Args._CameraPositionVisibility) 25 | .X(Args._X) 26 | .Y(Args._Y) 27 | .Z(Args._Z) 28 | .OnXChanged(Args._OnXChanged) 29 | .OnYChanged(Args._OnYChanged) 30 | .OnZChanged(Args._OnZChanged) 31 | .OnCopy(Args._OnLocationCopy) 32 | .OnPaste(Args._OnLocationPaste) 33 | ] 34 | +SVerticalBox::Slot() 35 | .AutoHeight() 36 | [ 37 | SNew(SEditorCameraRotationViewportToolBar) 38 | .Visibility(Args._CameraRotationVisibility) 39 | .Roll(Args._Roll) 40 | .Pitch(Args._Pitch) 41 | .Yaw(Args._Yaw) 42 | .OnRollChanged(Args._OnRollChanged) 43 | .OnPitchChanged(Args._OnPitchChanged) 44 | .OnYawChanged(Args._OnYawChanged) 45 | .OnCopy(Args._OnRotationCopy) 46 | .OnPaste(Args._OnRotationPaste) 47 | ] 48 | ] 49 | ]; 50 | } 51 | -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Public/Widgets/SEditorCameraViewportToolBar.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #pragma once 4 | 5 | #include "Editor/UnrealEd/Public/SViewportToolBar.h" 6 | #include "EditorCameraPositionTypes.h" 7 | 8 | class EDITORCAMERAPOSITION_API SEditorCameraViewportToolBar : public SViewportToolBar 9 | { 10 | 11 | public: 12 | SLATE_BEGIN_ARGS(SEditorCameraViewportToolBar) {} 13 | SLATE_ATTRIBUTE(EVisibility, CameraPositionVisibility) 14 | SLATE_ATTRIBUTE(TOptional, X) 15 | SLATE_ATTRIBUTE(TOptional, Y) 16 | SLATE_ATTRIBUTE(TOptional, Z) 17 | SLATE_ATTRIBUTE(EVisibility, CameraRotationVisibility) 18 | SLATE_ATTRIBUTE(TOptional, Roll) 19 | SLATE_ATTRIBUTE(TOptional, Pitch) 20 | SLATE_ATTRIBUTE(TOptional, Yaw) 21 | SLATE_EVENT(OnVectorValueChangedDelegateType, OnXChanged) 22 | SLATE_EVENT(OnVectorValueChangedDelegateType, OnYChanged) 23 | SLATE_EVENT(OnVectorValueChangedDelegateType, OnZChanged) 24 | SLATE_EVENT(OnRotatorValueChangedDelegateType, OnRollChanged) 25 | SLATE_EVENT(OnRotatorValueChangedDelegateType, OnPitchChanged) 26 | SLATE_EVENT(OnRotatorValueChangedDelegateType, OnYawChanged) 27 | SLATE_EVENT(FOnCameraPosOrRotCopyPasteEvent, OnLocationCopy) 28 | SLATE_EVENT(FOnCameraPosOrRotCopyPasteEvent, OnLocationPaste) 29 | SLATE_EVENT(FOnCameraPosOrRotCopyPasteEvent, OnRotationCopy) 30 | SLATE_EVENT(FOnCameraPosOrRotCopyPasteEvent, OnRotationPaste) 31 | SLATE_END_ARGS() 32 | 33 | void Construct(const FArguments& Args); 34 | }; 35 | -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Private/Widgets/SEditorCopyPasteBoxWidget.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #include "Widgets/SEditorCopyPasteBoxWidget.h" 4 | 5 | FReply SEditorCopyPasteBoxWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) 6 | { 7 | if (MouseEvent.GetEffectingButton() == EKeys::RightMouseButton) 8 | { 9 | CreateContextMenu(MouseEvent.GetScreenSpacePosition()); 10 | return FReply::Handled(); 11 | } 12 | return FReply::Unhandled(); 13 | } 14 | 15 | void SEditorCopyPasteBoxWidget::CreateContextMenu(const FVector2D& MousePosition) 16 | { 17 | FUIAction CopyAction = FUIAction(FExecuteAction::CreateLambda([this]() 18 | { 19 | OnCopy.ExecuteIfBound(); 20 | })); 21 | 22 | FUIAction PasteAction = FUIAction(FExecuteAction::CreateLambda([this]() 23 | { 24 | OnPaste.ExecuteIfBound(); 25 | })); 26 | 27 | FMenuBuilder MenuBuilder(true, nullptr); 28 | 29 | MenuBuilder.AddMenuEntry( 30 | NSLOCTEXT("PropertyView", "CopyProperty", "Copy"), 31 | NSLOCTEXT("PropertyView", "CopyProperty_ToolTip", "Copy this property value"), 32 | FSlateIcon(FCoreStyle::Get().GetStyleSetName(), "GenericCommands.Copy"), 33 | CopyAction); 34 | 35 | MenuBuilder.AddMenuEntry( 36 | NSLOCTEXT("PropertyView", "PasteProperty", "Paste"), 37 | NSLOCTEXT("PropertyView", "PasteProperty_ToolTip", "Paste the copied value here"), 38 | FSlateIcon(FCoreStyle::Get().GetStyleSetName(), "GenericCommands.Paste"), 39 | PasteAction); 40 | 41 | FSlateApplication::Get().PushMenu( 42 | SharedThis(this), 43 | FWidgetPath(), 44 | MenuBuilder.MakeWidget(), 45 | MousePosition, 46 | FPopupTransitionEffect(FPopupTransitionEffect::ContextMenu)); 47 | } 48 | -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Public/EditorCameraPositionSettings.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Engine/DeveloperSettings.h" 7 | #include "EditorCameraPositionTypes.h" 8 | #include "EditorCameraPositionSettings.generated.h" 9 | 10 | /** 11 | * Storing settings in DefaultEditor.ini file. 12 | */ 13 | 14 | UCLASS(config = Editor, defaultconfig) 15 | class EDITORCAMERAPOSITION_API UEditorCameraPositionSettings : public UDeveloperSettings 16 | { 17 | GENERATED_BODY() 18 | 19 | public: 20 | 21 | static const UEditorCameraPositionSettings* Get(); 22 | 23 | static bool GetIsCameraPositionToolBarEnabled(); 24 | static void SetIsCameraPositionToolBarEnabled(bool bInIsVisible); 25 | 26 | static bool GetIsCameraRotationToolBarEnabled(); 27 | static void SetIsCameraRotationToolBarEnabled(bool bInIsVisible); 28 | 29 | // UDeveloperSettings implementation 30 | FName GetContainerName() const override; 31 | FName GetCategoryName() const override; 32 | FName GetSectionName() const override; 33 | FText GetSectionText() const override; 34 | FText GetSectionDescription() const override; 35 | // UDeveloperSettings implementation 36 | 37 | UPROPERTY(config, EditAnywhere, Category = "Editor Camera Position") 38 | bool bEnableEditorCameraPosition = true; 39 | 40 | UPROPERTY(config, EditAnywhere, Category = "Editor Camera Position") 41 | bool bEnableEditorCameraRotation = true; 42 | 43 | UPROPERTY(config, EditAnywhere, Category = "Editor Camera Position") 44 | EEditorCameraPositionTruncType CameraPositionTrunc = EEditorCameraPositionTruncType::TwoDecimals; 45 | 46 | UPROPERTY(config, EditAnywhere, Category = "Editor Camera Position") 47 | EEditorCameraPositionTruncType CameraRotationTrunc = EEditorCameraPositionTruncType::TwoDecimals; 48 | 49 | private: 50 | 51 | UPROPERTY(config) 52 | bool bIsCameraPositionToolBarEnabled = false; 53 | 54 | UPROPERTY(config) 55 | bool bIsCameraRotationToolBarEnabled = false; 56 | }; 57 | -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Private/EditorCameraPositionSettings.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #pragma once 4 | 5 | #include "EditorCameraPositionSettings.h" 6 | #include "Runtime/Launch/Resources/Version.h" 7 | 8 | const UEditorCameraPositionSettings* UEditorCameraPositionSettings::Get() 9 | { 10 | return GetDefault(); 11 | } 12 | 13 | bool UEditorCameraPositionSettings::GetIsCameraPositionToolBarEnabled() 14 | { 15 | return Get()->bIsCameraPositionToolBarEnabled; 16 | } 17 | 18 | void UEditorCameraPositionSettings::SetIsCameraPositionToolBarEnabled(bool bInIsVisible) 19 | { 20 | UEditorCameraPositionSettings* Settings = GetMutableDefault(); 21 | Settings->bIsCameraPositionToolBarEnabled = bInIsVisible; 22 | 23 | #if (ENGINE_MAJOR_VERSION == 5) 24 | Settings->TryUpdateDefaultConfigFile(); 25 | #else 26 | Settings->UpdateDefaultConfigFile(); 27 | #endif 28 | } 29 | 30 | bool UEditorCameraPositionSettings::GetIsCameraRotationToolBarEnabled() 31 | { 32 | return Get()->bIsCameraRotationToolBarEnabled; 33 | } 34 | 35 | void UEditorCameraPositionSettings::SetIsCameraRotationToolBarEnabled(bool bInIsVisible) 36 | { 37 | UEditorCameraPositionSettings* Settings = GetMutableDefault(); 38 | Settings->bIsCameraRotationToolBarEnabled = bInIsVisible; 39 | 40 | #if (ENGINE_MAJOR_VERSION == 5) 41 | Settings->TryUpdateDefaultConfigFile(); 42 | #else 43 | Settings->UpdateDefaultConfigFile(); 44 | #endif 45 | } 46 | 47 | FName UEditorCameraPositionSettings::GetContainerName() const 48 | { 49 | return FName("Editor"); 50 | } 51 | 52 | FName UEditorCameraPositionSettings::GetCategoryName() const 53 | { 54 | return FName("Plugins"); 55 | } 56 | FName UEditorCameraPositionSettings::GetSectionName() const 57 | { 58 | return FName("EditorCameraPosition"); 59 | } 60 | 61 | FText UEditorCameraPositionSettings::GetSectionText() const 62 | { 63 | return INVTEXT("Editor Camera Position"); 64 | } 65 | 66 | FText UEditorCameraPositionSettings::GetSectionDescription() const 67 | { 68 | return INVTEXT("Configure the Editor Camera Position Plugin"); 69 | } -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Private/EditorCameraPositionUtils.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #include "EditorCameraPositionUtils.h" 4 | #include "Editor.h" 5 | #include "LevelEditor.h" 6 | #include "LevelEditorViewport.h" 7 | 8 | FVector UEditorCameraPositionUtils::GetEditorCameraPosition() 9 | { 10 | if (GCurrentLevelEditingViewportClient) 11 | { 12 | const FViewportCameraTransform& ViewTransform = GCurrentLevelEditingViewportClient->GetViewTransform(); 13 | return ViewTransform.GetLocation(); 14 | } 15 | return FVector::ZeroVector; 16 | } 17 | 18 | void UEditorCameraPositionUtils::SetEditorCameraPosition(const FVector& NewEditorCameraPosition) 19 | { 20 | if (GCurrentLevelEditingViewportClient) 21 | { 22 | FViewportCameraTransform& ViewTransform = GCurrentLevelEditingViewportClient->GetViewTransform(); 23 | 24 | UCameraComponent* CamComp = GCurrentLevelEditingViewportClient->GetCameraComponentForView(); 25 | AActor* CamOwner = CamComp ? CamComp->GetOwner() : nullptr; 26 | if (CamOwner) 27 | { 28 | const FVector NewOwnerPos = NewEditorCameraPosition - (ViewTransform.GetLocation() - CamOwner->GetActorLocation()); 29 | ViewTransform.SetLocation(NewEditorCameraPosition); 30 | CamOwner->SetActorLocation(NewOwnerPos); 31 | } 32 | else 33 | { 34 | ViewTransform.SetLocation(NewEditorCameraPosition); 35 | } 36 | } 37 | } 38 | 39 | FRotator UEditorCameraPositionUtils::GetEditorCameraRotation() 40 | { 41 | if (GCurrentLevelEditingViewportClient) 42 | { 43 | const FViewportCameraTransform& ViewTransform = GCurrentLevelEditingViewportClient->GetViewTransform(); 44 | return ViewTransform.GetRotation(); 45 | } 46 | return FRotator::ZeroRotator; 47 | } 48 | 49 | void UEditorCameraPositionUtils::SetEditorCameraRotation(const FRotator& NewEditorCameraRotation) 50 | { 51 | if (GCurrentLevelEditingViewportClient) 52 | { 53 | FViewportCameraTransform& ViewTransform = GCurrentLevelEditingViewportClient->GetViewTransform(); 54 | 55 | UCameraComponent* CamComp = GCurrentLevelEditingViewportClient->GetCameraComponentForView(); 56 | AActor* CamOwner = CamComp ? CamComp->GetOwner() : nullptr; 57 | if (CamOwner) 58 | { 59 | const FRotator NewOwnerRot = NewEditorCameraRotation - (ViewTransform.GetRotation() - CamOwner->GetActorRotation()); 60 | ViewTransform.SetRotation(NewEditorCameraRotation); 61 | CamOwner->SetActorRotation(NewOwnerRot); 62 | } 63 | else 64 | { 65 | ViewTransform.SetRotation(NewEditorCameraRotation); 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Public/EditorCameraPositionModule.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Modules/ModuleManager.h" 7 | #include "EditorCameraPositionTypes.h" 8 | 9 | class EDITORCAMERAPOSITION_API FEditorCameraPositionModule : public IModuleInterface 10 | { 11 | 12 | protected: 13 | 14 | void StartupModule() override; 15 | void ShutdownModule() override; 16 | 17 | void AddViewportToolBarExtension(); 18 | void AddViewportCameraPositionOptionExtension(); 19 | void AddViewportCameraRotationOptionExtension(); 20 | 21 | TOptional GetLocationX() const; 22 | TOptional GetLocationY() const; 23 | TOptional GetLocationZ() const; 24 | 25 | void SetLocationX(VectorValueType Value); 26 | void SetLocationY(VectorValueType Value); 27 | void SetLocationZ(VectorValueType Value); 28 | 29 | void OnLocationCopy(); 30 | void OnLocationPaste(); 31 | 32 | TOptional GetRotationRoll() const; 33 | TOptional GetRotationPitch() const; 34 | TOptional GetRotationYaw() const; 35 | 36 | void SetRotationRoll(RotatorValueType Value); 37 | void SetRotationPitch(RotatorValueType Value); 38 | void SetRotationYaw(RotatorValueType Value); 39 | 40 | void OnRotationCopy(); 41 | void OnRotationPaste(); 42 | 43 | void SetIsCameraPositionToolBarEnabled(bool bNewIsVisible); 44 | bool GetIsCameraPositionToolBarEnabled() const; 45 | void ToggleCameraPositionToolbarEnabled(); 46 | EVisibility GetCameraPositionToolBarVisibility() const; 47 | 48 | void SetIsCameraRotationToolBarEnabled(bool bNewIsVisible); 49 | bool GetIsCameraRotationToolBarEnabled() const; 50 | void ToggleCameraRotationToolbarEnabled(); 51 | EVisibility GetCameraRotationToolBarVisibility() const; 52 | 53 | EVisibility GetToolbarVisibility() const; 54 | 55 | private: 56 | 57 | bool Tick(float DeltaTime); 58 | void RefreshViewportLocation(); 59 | void RefreshViewportRotation(); 60 | void RefreshToolbarVisibility(); 61 | TOptional TruncPosition(VectorValueType InValue) const; 62 | TOptional TruncRotation(RotatorValueType InValue) const; 63 | TSharedRef GetWidget(); 64 | 65 | FVector CamPos; 66 | FRotator CamRot; 67 | bool bIsCamPosToolbarVisible = true; 68 | bool bIsCamRotToolbarVisible = true; 69 | 70 | #if (ENGINE_MAJOR_VERSION == 5) 71 | FTSTicker::FDelegateHandle TickerHandle; 72 | #else 73 | FDelegateHandle TickerHandle; 74 | #endif 75 | }; 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Editor Camera Position for Unreal Engine 2 | 3 | This is a simple plugin for Unreal Engine that displays the camera position in the editor's viewport. It can also set and copy-paste the camera position. 4 | The plugin works on Unreal Engine: 4.27, 5.2-5.7. 5 | 6 | https://github.com/zompi2/EditorCameraPositionUE4/assets/7863125/f9744a1c-215a-43fc-a26f-2b529380d420 7 | 8 | > **Since UE 5.6 the "Toggle Camera Position/Rotation" checkboxes are under the "Perspective button"** 9 | > newcampos 10 | 11 | ## Plugin prebuilt binaries 12 | 13 | If you don't want to build the plugin from the source you can get the prebuilt binaries: 14 | 15 | | UE version | Plugin version | Link | 16 | | :--------- | :------------- | :--- | 17 | | 4.27 | 1.1.3 | [Zip](https://github.com/zompi2/EditorCameraPositionUE4/raw/packs/Packs/EditorCameraPosition-1.1.3-4.27-Prebuild.zip) | 18 | | 5.2 | 1.1.1 | [Fab](https://www.fab.com/listings/13d27c05-5c95-46f2-a123-06891956049e) | 19 | | 5.3 | 1.1.3 | [Fab](https://www.fab.com/listings/13d27c05-5c95-46f2-a123-06891956049e) | 20 | | 5.4 | 1.1.3 | [Fab](https://www.fab.com/listings/13d27c05-5c95-46f2-a123-06891956049e) | 21 | | 5.5 | 1.1.3 | [Fab](https://www.fab.com/listings/13d27c05-5c95-46f2-a123-06891956049e) | 22 | | 5.6 | 1.1.3 | [Fab](https://www.fab.com/listings/13d27c05-5c95-46f2-a123-06891956049e) | 23 | | 5.7 | 1.1.3 | [Fab](https://www.fab.com/listings/13d27c05-5c95-46f2-a123-06891956049e) | 24 | 25 | ## Why is it useful? 26 | 27 | It is useful when a QA team reports you a bug in specific location. Finding this place in the editor on a huge map with only coordinates is tricky. With this tool you can simply copy-paste this location and go directly to a place where the problem occurs. 28 | 29 | It is also useful if you want to share a specific world coordinates to a teammate without getting coordinates of a specific object. 30 | 31 | ## Rotation 32 | 33 | The plugin can also display and modify the camera rotation. 34 | 35 | ![camrot1](https://github.com/user-attachments/assets/ad91016f-5d2b-4e0c-81bb-8af2a901efc4) 36 | ![camrot2](https://github.com/user-attachments/assets/96603b3b-da49-4e28-b7c1-0c36293dd601) 37 | 38 | ## Blueprint nodes 39 | 40 | If you need a position or rotation of the editor viewport's camera in your Blueprint Utility Widget there are Blueprint nodes that can help you with it: 41 | 42 | #### Get Editor Camera Position 43 | ![geteditorcameraposbp](https://github.com/user-attachments/assets/c94d94f3-14aa-4780-8ec3-5cf5c0594ae7) 44 | 45 | #### Set Editor Camera Position 46 | ![seteditorcameraposition](https://github.com/user-attachments/assets/2ab1834e-f33c-4133-acc1-8db642d17110) 47 | 48 | #### Get Editor Camera Rotation 49 | ![camrot3](https://github.com/user-attachments/assets/0480b7db-88cd-4904-991b-b6c4429a9812) 50 | 51 | #### Set Editor Camera Rotation 52 | ![camrot4](https://github.com/user-attachments/assets/089c591c-3c6b-4f98-abe4-f4a40a21dcb3) 53 | 54 | ## Settings 55 | 56 | You can find few settings inside the `Edit -> Editor Preferences -> Plugins -> Editor Camera Position` section. 57 | 58 | ![camcam](https://github.com/user-attachments/assets/b6d7befa-1909-453f-ab99-ea956c175086) 59 | 60 | * Enable Editor Camera Position/Rotation - should the option to show camera position or rotation in the editor be even possible? 61 | * Camera Position/Rotation Trunc - describes how to truncate the values of camera position and rotation when moving the camera in the editor. Possible values: 62 | * `No Trunc` - the values will not be truncated 63 | * `Two Decimals` - the values will be truncated to two decimal places 64 | * `Zero Decimals` - the values will be truncated to the total integer values 65 | 66 | ## FAQ 67 | 68 | **But you can save your fav camera positions using Ctrl+Numer** 69 | This plugin is not for saving your favourite camera positions. It's for a situation when you have to quickly jump to a specific coordinates, given to you by someone else (usually the QA). 70 | 71 | **But you can just spawn cube, set it's location to the desired location, press F and delete that cube** 72 | Yeah... I know... but for me it was annoying to do it every time I needed that simple functionality. It saves you that few seconds every time :) 73 | 74 | **Does it work for camera position and rotation when piloting actors?** 75 | Yes it does! 76 | 77 | ## Anything else? 78 | 79 | Just hoping you can find it useful. 80 | Cheers! 81 | <3 82 | 83 | 84 | -------------------------------------------------------------------------------- /Source/EditorCameraPosition/Private/EditorCameraPositionModule.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Damian Nowakowski. All rights reserved. 2 | 3 | #include "EditorCameraPositionModule.h" 4 | #include "EditorCameraPositionCommands.h" 5 | #include "EditorCameraPositionSettings.h" 6 | #include "EditorCameraPositionUtils.h" 7 | #include "EditorCameraPositionTypes.h" 8 | #include "Widgets/SEditorCameraViewportToolBar.h" 9 | 10 | #include "Editor.h" 11 | #include "LevelEditor.h" 12 | #include "LevelEditorViewport.h" 13 | #include "Containers/Ticker.h" 14 | #include "HAL/PlatformApplicationMisc.h" 15 | #include "ToolMenus.h" 16 | 17 | IMPLEMENT_MODULE(FEditorCameraPositionModule, EditorCameraPosition) 18 | 19 | void FEditorCameraPositionModule::StartupModule() 20 | { 21 | FEditorCameraPositionCommands::Register(); 22 | 23 | if ((IsRunningCommandlet() == false) && (IsRunningGame() == false) && FSlateApplication::IsInitialized()) 24 | { 25 | RefreshToolbarVisibility(); 26 | AddViewportToolBarExtension(); 27 | AddViewportCameraPositionOptionExtension(); 28 | AddViewportCameraRotationOptionExtension(); 29 | } 30 | 31 | #if (ENGINE_MAJOR_VERSION == 5) 32 | TickerHandle = FTSTicker::GetCoreTicker().AddTicker(FTickerDelegate::CreateRaw(this, &FEditorCameraPositionModule::Tick), 0.0f); 33 | #else 34 | TickerHandle = FTicker::GetCoreTicker().AddTicker(FTickerDelegate::CreateRaw(this, &FEditorCameraPositionModule::Tick), 0.0f); 35 | #endif 36 | } 37 | 38 | void FEditorCameraPositionModule::ShutdownModule() 39 | { 40 | #if (ENGINE_MAJOR_VERSION == 5) 41 | FTSTicker::GetCoreTicker().RemoveTicker(TickerHandle); 42 | #else 43 | FTicker::GetCoreTicker().RemoveTicker(TickerHandle); 44 | #endif 45 | FEditorCameraPositionCommands::Unregister(); 46 | } 47 | 48 | void FEditorCameraPositionModule::AddViewportToolBarExtension() 49 | { 50 | if (FLevelEditorModule* LevelEditor = FModuleManager::LoadModulePtr(TEXT("LevelEditor"))) 51 | { 52 | TSharedPtr Commands = MakeShareable(new FUICommandList()); 53 | TSharedPtr ToolbarExtender = MakeShareable(new FExtender); 54 | ToolbarExtender->AddToolBarExtension( 55 | "CameraSpeed", 56 | EExtensionHook::After, 57 | Commands, 58 | FToolBarExtensionDelegate::CreateLambda([this](FToolBarBuilder& ToolbarBuilder) 59 | { 60 | ToolbarBuilder.AddSeparator(); 61 | ToolbarBuilder.BeginSection("CameraPosition"); 62 | ToolbarBuilder.AddWidget(GetWidget()); 63 | ToolbarBuilder.EndSection(); 64 | }) 65 | ); 66 | LevelEditor->GetToolBarExtensibilityManager()->AddExtender(ToolbarExtender); 67 | } 68 | } 69 | 70 | void FEditorCameraPositionModule::AddViewportCameraPositionOptionExtension() 71 | { 72 | TSharedPtr Command = FEditorCameraPositionCommands::Get().ToggleShowCameraPosWidget; 73 | #if ((ENGINE_MAJOR_VERSION == 5) && (ENGINE_MINOR_VERSION >= 6)) 74 | UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.ViewportToolbar.Camera"); 75 | #else 76 | UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.LevelViewportToolBar.Options"); 77 | #endif 78 | if (Menu) 79 | { 80 | FUIAction Action; 81 | Action.ExecuteAction.BindLambda([this]() 82 | { 83 | ToggleCameraPositionToolbarEnabled(); 84 | }); 85 | Action.GetActionCheckState.BindLambda([this]() -> ECheckBoxState 86 | { 87 | return GetIsCameraPositionToolBarEnabled() ? ECheckBoxState::Checked : ECheckBoxState::Unchecked; 88 | }); 89 | Action.CanExecuteAction.BindLambda([this]() -> bool 90 | { 91 | return UEditorCameraPositionSettings::Get()->bEnableEditorCameraPosition; 92 | }); 93 | Action.IsActionVisibleDelegate.BindLambda([this]() -> bool 94 | { 95 | return UEditorCameraPositionSettings::Get()->bEnableEditorCameraPosition; 96 | }); 97 | 98 | #if ((ENGINE_MAJOR_VERSION == 5) && (ENGINE_MINOR_VERSION >= 6)) 99 | FToolMenuSection& Section = Menu->FindOrAddSection("CameraOptions"); 100 | #else 101 | FToolMenuSection& Section = Menu->FindOrAddSection("LevelViewportViewportOptions2"); 102 | #endif 103 | Section.AddMenuEntry(Command); 104 | 105 | if (FLevelEditorModule* LevelEditor = FModuleManager::LoadModulePtr(TEXT("LevelEditor"))) 106 | { 107 | TSharedRef GlobalLevelEditorActions = LevelEditor->GetGlobalLevelEditorActions(); 108 | GlobalLevelEditorActions->MapAction(Command, Action); 109 | } 110 | } 111 | } 112 | 113 | void FEditorCameraPositionModule::AddViewportCameraRotationOptionExtension() 114 | { 115 | TSharedPtr Command = FEditorCameraPositionCommands::Get().ToggleShowCameraRotWidget; 116 | #if ((ENGINE_MAJOR_VERSION == 5) && (ENGINE_MINOR_VERSION >= 6)) 117 | UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.ViewportToolbar.Camera"); 118 | #else 119 | UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.LevelViewportToolBar.Options"); 120 | #endif 121 | if (Menu) 122 | { 123 | FUIAction Action; 124 | Action.ExecuteAction.BindLambda([this]() 125 | { 126 | ToggleCameraRotationToolbarEnabled(); 127 | }); 128 | Action.GetActionCheckState.BindLambda([this]() -> ECheckBoxState 129 | { 130 | return GetIsCameraRotationToolBarEnabled() ? ECheckBoxState::Checked : ECheckBoxState::Unchecked; 131 | }); 132 | Action.CanExecuteAction.BindLambda([this]() -> bool 133 | { 134 | return UEditorCameraPositionSettings::Get()->bEnableEditorCameraRotation; 135 | }); 136 | Action.IsActionVisibleDelegate.BindLambda([this]() -> bool 137 | { 138 | return UEditorCameraPositionSettings::Get()->bEnableEditorCameraRotation; 139 | }); 140 | 141 | #if ((ENGINE_MAJOR_VERSION == 5) && (ENGINE_MINOR_VERSION >= 6)) 142 | FToolMenuSection& Section = Menu->FindOrAddSection("CameraOptions"); 143 | #else 144 | FToolMenuSection& Section = Menu->FindOrAddSection("LevelViewportViewportOptions2"); 145 | #endif 146 | Section.AddMenuEntry(Command); 147 | 148 | if (FLevelEditorModule* LevelEditor = FModuleManager::LoadModulePtr(TEXT("LevelEditor"))) 149 | { 150 | TSharedRef GlobalLevelEditorActions = LevelEditor->GetGlobalLevelEditorActions(); 151 | GlobalLevelEditorActions->MapAction(Command, Action); 152 | } 153 | } 154 | } 155 | 156 | TOptional FEditorCameraPositionModule::GetLocationX() const 157 | { 158 | return TruncPosition(CamPos.X); 159 | } 160 | 161 | TOptional FEditorCameraPositionModule::GetLocationY() const 162 | { 163 | return TruncPosition(CamPos.Y); 164 | } 165 | 166 | TOptional FEditorCameraPositionModule::GetLocationZ() const 167 | { 168 | return TruncPosition(CamPos.Z); 169 | } 170 | 171 | void FEditorCameraPositionModule::SetLocationX(VectorValueType Value) 172 | { 173 | CamPos.X = Value; 174 | RefreshViewportLocation(); 175 | } 176 | 177 | void FEditorCameraPositionModule::SetLocationY(VectorValueType Value) 178 | { 179 | CamPos.Y = Value; 180 | RefreshViewportLocation(); 181 | } 182 | 183 | void FEditorCameraPositionModule::SetLocationZ(VectorValueType Value) 184 | { 185 | CamPos.Z = Value; 186 | RefreshViewportLocation(); 187 | } 188 | 189 | void FEditorCameraPositionModule::OnLocationCopy() 190 | { 191 | const FString CopyStr = FString::Printf(TEXT("(%s)"), *CamPos.ToString()); 192 | if (CopyStr.IsEmpty() == false) 193 | { 194 | FPlatformApplicationMisc::ClipboardCopy(*CopyStr); 195 | } 196 | } 197 | 198 | void FEditorCameraPositionModule::OnLocationPaste() 199 | { 200 | FString PastedText; 201 | FPlatformApplicationMisc::ClipboardPaste(PastedText); 202 | if (CamPos.InitFromString(PastedText)) 203 | { 204 | RefreshViewportLocation(); 205 | } 206 | } 207 | 208 | TOptional FEditorCameraPositionModule::GetRotationRoll() const 209 | { 210 | return TruncRotation(CamRot.Roll); 211 | } 212 | 213 | TOptional FEditorCameraPositionModule::GetRotationPitch() const 214 | { 215 | return TruncRotation(CamRot.Pitch); 216 | } 217 | 218 | TOptional FEditorCameraPositionModule::GetRotationYaw() const 219 | { 220 | return TruncRotation(CamRot.Yaw); 221 | } 222 | 223 | void FEditorCameraPositionModule::SetRotationRoll(RotatorValueType Value) 224 | { 225 | CamRot.Roll = Value; 226 | RefreshViewportRotation(); 227 | } 228 | 229 | void FEditorCameraPositionModule::SetRotationPitch(RotatorValueType Value) 230 | { 231 | CamRot.Pitch = Value; 232 | RefreshViewportRotation(); 233 | } 234 | 235 | void FEditorCameraPositionModule::SetRotationYaw(RotatorValueType Value) 236 | { 237 | CamRot.Yaw = Value; 238 | RefreshViewportRotation(); 239 | } 240 | 241 | void FEditorCameraPositionModule::OnRotationCopy() 242 | { 243 | const FString CopyStr = FString::Printf(TEXT("(%s)"), *CamRot.ToString()); 244 | if (CopyStr.IsEmpty() == false) 245 | { 246 | FPlatformApplicationMisc::ClipboardCopy(*CopyStr); 247 | } 248 | } 249 | 250 | void FEditorCameraPositionModule::OnRotationPaste() 251 | { 252 | FString PastedText; 253 | FPlatformApplicationMisc::ClipboardPaste(PastedText); 254 | if (CamRot.InitFromString(PastedText)) 255 | { 256 | RefreshViewportRotation(); 257 | } 258 | } 259 | 260 | void FEditorCameraPositionModule::SetIsCameraPositionToolBarEnabled(bool bNewIsVisible) 261 | { 262 | UEditorCameraPositionSettings::SetIsCameraPositionToolBarEnabled(bNewIsVisible); 263 | } 264 | 265 | bool FEditorCameraPositionModule::GetIsCameraPositionToolBarEnabled() const 266 | { 267 | return bIsCamPosToolbarVisible; 268 | } 269 | 270 | void FEditorCameraPositionModule::ToggleCameraPositionToolbarEnabled() 271 | { 272 | SetIsCameraPositionToolBarEnabled(!GetIsCameraPositionToolBarEnabled()); 273 | } 274 | 275 | EVisibility FEditorCameraPositionModule::GetCameraPositionToolBarVisibility() const 276 | { 277 | return (bIsCamPosToolbarVisible && UEditorCameraPositionSettings::Get()->bEnableEditorCameraPosition) ? EVisibility::Visible : EVisibility::Collapsed; 278 | } 279 | 280 | void FEditorCameraPositionModule::SetIsCameraRotationToolBarEnabled(bool bNewIsVisible) 281 | { 282 | UEditorCameraPositionSettings::SetIsCameraRotationToolBarEnabled(bNewIsVisible); 283 | } 284 | 285 | bool FEditorCameraPositionModule::GetIsCameraRotationToolBarEnabled() const 286 | { 287 | return bIsCamRotToolbarVisible; 288 | } 289 | 290 | void FEditorCameraPositionModule::ToggleCameraRotationToolbarEnabled() 291 | { 292 | SetIsCameraRotationToolBarEnabled(!GetIsCameraRotationToolBarEnabled()); 293 | } 294 | 295 | EVisibility FEditorCameraPositionModule::GetCameraRotationToolBarVisibility() const 296 | { 297 | return (bIsCamRotToolbarVisible && UEditorCameraPositionSettings::Get()->bEnableEditorCameraRotation) ? EVisibility::Visible : EVisibility::Collapsed; 298 | } 299 | 300 | EVisibility FEditorCameraPositionModule::GetToolbarVisibility() const 301 | { 302 | return ((GetCameraPositionToolBarVisibility() == EVisibility::Visible) || (GetCameraRotationToolBarVisibility() == EVisibility::Visible)) ? EVisibility::Visible : EVisibility::Collapsed; 303 | } 304 | 305 | bool FEditorCameraPositionModule::Tick(float DeltaTime) 306 | { 307 | RefreshToolbarVisibility(); 308 | CamPos = UEditorCameraPositionUtils::GetEditorCameraPosition(); 309 | CamRot = UEditorCameraPositionUtils::GetEditorCameraRotation(); 310 | return true; 311 | } 312 | 313 | void FEditorCameraPositionModule::RefreshViewportLocation() 314 | { 315 | UEditorCameraPositionUtils::SetEditorCameraPosition(CamPos); 316 | } 317 | 318 | void FEditorCameraPositionModule::RefreshViewportRotation() 319 | { 320 | UEditorCameraPositionUtils::SetEditorCameraRotation(CamRot); 321 | } 322 | 323 | void FEditorCameraPositionModule::RefreshToolbarVisibility() 324 | { 325 | bIsCamPosToolbarVisible = UEditorCameraPositionSettings::GetIsCameraPositionToolBarEnabled() && UEditorCameraPositionSettings::Get()->bEnableEditorCameraPosition; 326 | bIsCamRotToolbarVisible = UEditorCameraPositionSettings::GetIsCameraRotationToolBarEnabled() && UEditorCameraPositionSettings::Get()->bEnableEditorCameraRotation; 327 | } 328 | 329 | TOptional FEditorCameraPositionModule::TruncPosition(VectorValueType InValue) const 330 | { 331 | if (UEditorCameraPositionSettings::Get()->CameraPositionTrunc == EEditorCameraPositionTruncType::NoTrunc) 332 | { 333 | return InValue; 334 | } 335 | else if (UEditorCameraPositionSettings::Get()->CameraPositionTrunc == EEditorCameraPositionTruncType::TwoDecimals) 336 | { 337 | return FMath::TruncToFloat(InValue * 100) / 100; 338 | } 339 | else if (UEditorCameraPositionSettings::Get()->CameraPositionTrunc == EEditorCameraPositionTruncType::ZeroDecimals) 340 | { 341 | return FMath::TruncToFloat(InValue); 342 | } 343 | return InValue; 344 | } 345 | 346 | TOptional FEditorCameraPositionModule::TruncRotation(RotatorValueType InValue) const 347 | { 348 | if (UEditorCameraPositionSettings::Get()->CameraRotationTrunc == EEditorCameraPositionTruncType::NoTrunc) 349 | { 350 | return InValue; 351 | } 352 | else if (UEditorCameraPositionSettings::Get()->CameraRotationTrunc == EEditorCameraPositionTruncType::TwoDecimals) 353 | { 354 | return FMath::TruncToFloat(InValue * 100) / 100; 355 | } 356 | else if (UEditorCameraPositionSettings::Get()->CameraRotationTrunc == EEditorCameraPositionTruncType::ZeroDecimals) 357 | { 358 | return FMath::TruncToFloat(InValue); 359 | } 360 | return InValue; 361 | } 362 | 363 | TSharedRef FEditorCameraPositionModule::GetWidget() 364 | { 365 | return SNew(SEditorCameraViewportToolBar) 366 | .Visibility_Raw(this, &FEditorCameraPositionModule::GetToolbarVisibility) 367 | .CameraPositionVisibility_Raw(this, &FEditorCameraPositionModule::GetCameraPositionToolBarVisibility) 368 | .X_Raw(this, &FEditorCameraPositionModule::GetLocationX) 369 | .Y_Raw(this, &FEditorCameraPositionModule::GetLocationY) 370 | .Z_Raw(this, &FEditorCameraPositionModule::GetLocationZ) 371 | .CameraRotationVisibility_Raw(this, &FEditorCameraPositionModule::GetCameraRotationToolBarVisibility) 372 | .Roll_Raw(this, &FEditorCameraPositionModule::GetRotationRoll) 373 | .Pitch_Raw(this, &FEditorCameraPositionModule::GetRotationPitch) 374 | .Yaw_Raw(this, &FEditorCameraPositionModule::GetRotationYaw) 375 | .OnXChanged_Raw(this, &FEditorCameraPositionModule::SetLocationX) 376 | .OnYChanged_Raw(this, &FEditorCameraPositionModule::SetLocationY) 377 | .OnZChanged_Raw(this, &FEditorCameraPositionModule::SetLocationZ) 378 | .OnRollChanged_Raw(this, &FEditorCameraPositionModule::SetRotationRoll) 379 | .OnPitchChanged_Raw(this, &FEditorCameraPositionModule::SetRotationPitch) 380 | .OnYawChanged_Raw(this, &FEditorCameraPositionModule::SetRotationYaw) 381 | .OnLocationCopy_Raw(this, &FEditorCameraPositionModule::OnLocationCopy) 382 | .OnLocationPaste_Raw(this, &FEditorCameraPositionModule::OnLocationPaste) 383 | .OnRotationCopy_Raw(this, &FEditorCameraPositionModule::OnRotationCopy) 384 | .OnRotationPaste_Raw(this, &FEditorCameraPositionModule::OnRotationPaste); 385 | } 386 | --------------------------------------------------------------------------------