You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#lockdown nick.penwarden #rb none ========================== MAJOR FEATURES + CHANGES ========================== Change 3437481 on 2017/05/12 by Brian.Zaugg@Brian.Zaugg_A4140_WexDevMain #wex - Put the change to sort the CookedAssetRegistry back in. #jira WEX-5841 Back out changelist 3437412 Change 3437412 on 2017/05/12 by Brian.Zaugg@brian.zaugg_8402_WexDevMain #wex - Back out change to CookedAssetRegistry, which turned out to be unnecessary. #jira WEX-5841 Back out changelist 3437372 Change 3437372 on 2017/05/12 by Brian.Zaugg@brian.zaugg_8402_WexDevMain #wex - Sort the cooked asset registry on save to fix nondeterministic cook. #jira WEX-5841 Change 3435902 on 2017/05/11 by Brian.Zaugg@brian.zaugg_8402_WexDevMain #wex - Removed UpgradeTrackRows from MovieScenes. It was no longer needed and was causing nondeterministic cooks. #jira WEX-5841 Change 3435900 on 2017/05/11 by Brian.Zaugg@brian.zaugg_8402_WexDevMain #wex - Merge in fix for nondeterministic script compilation from Dev-General. #jira WEX-5841 Merging //Orion/Dev-General/Engine/Source/Runtime/MovieScene/Private/MovieSceneSignedObject.cpp to //WEX/Main/Engine/Source/Runtime/MovieScene/Private/MovieSceneSignedObject.cpp Change 3435897 on 2017/05/11 by Brian.Zaugg@brian.zaugg_8402_WexDevMain #wex - Merge in fix for nondeterministic blueprint cook from Dev-Editor #jira WEX-5841 Merging //UE4/Dev-Editor/Engine/Source/Runtime/MovieScene/... to //WEX/Main/Engine/Source/Runtime/MovieScene/... Change 3435896 on 2017/05/11 by Brian.Zaugg@brian.zaugg_8402_WexDevMain #wex - Merge in fix for nondeterministic script compilation from Dev-Framework. #jira WEX-5841 Merging //UE4/Dev-Framework/Engine/Source/Editor/... to //WEX/Main/Engine/Source/Editor/... Change 3435387 on 2017/05/11 by Chris.Babcock@Chris.Babcock_Z2433_WEX Upload Crashlytics symbols after succesful build by build machine #jira none Change 3433935 on 2017/05/10 by Brian.Zaugg@brian.zaugg_8402_WexDevMain #wex - Resaved more assets to fix nondeterministic cooks. #jira WEX-5841 Change 3433707 on 2017/05/10 by robomerge@ROBOMERGE_WEX_Main fix for thinking Android is always on WiFi even when it is on LTE #jira none Change 3433634 on 2017/05/10 by peter.sauerbrei@peter.sauerbrei_WEX fix for loading a null object when the object is just pending kill not happy with this fix, but it works #jira WEX-6265 Change 3432228 on 2017/05/10 by Dmitriy.Dyomin@dmitriy.dyomin-wex Added LoadTimes.Reset console command to reset accumulated data reported by LoadTimes.DumpReport #jira WEX-6319 Change 3431341 on 2017/05/09 by Chris.Babcock@Chris.Babcock_Z2433_WEX Make sure file handle is valid for flush #jira none Change 3431036 on 2017/05/09 by Chris.Babcock@Chris.Babcock_Z2433_WEX Capture UE_LOG for Crashlytics (can be disabled by setting ENABLE_CRASHLYTICS_LOGGING to 0 in CrashlyticsModule.cpp) - Added IFileHandle::Flush() to get the full pre-init log #jira WEX-6311 Change 3429394 on 2017/05/08 by robomerge@ROBOMERGE_WEX_Main fix for missing logs when crashing in crash reporter #jira none Change 3428450 on 2017/05/08 by Josh.May@WEX-Main-JMAY #WEX #JIRA: WEX-6248, WEX-6285 - Converted the MonsterPit hero list over to using the new UListView-based WExpHexGrid. - Generalized some of the item selection logic from B_HexGrid_Heroes. - Removed a bunch of MonsterPit-specific cruft from the HeroIcons. Change 3428177 on 2017/05/08 by robomerge@ROBOMERGE_WEX_Main fix for no symbols on the crashreport site #jira none Change 3428110 on 2017/05/08 by Chris.Babcock@Chris.Babcock_Z2433_WEX Enable CL as store version for Android #jira WEX-5432 #ue4 #android Change 3427082 on 2017/05/05 by Chris.Babcock@Chris.Babcock_Z2433_WEX Crashlytics for Android - also adds support for CL used as StoreVersion (requires bUseChangleListAsStoreVersion=true and environment variable IsBuildMachine=1), but not enabled yet #jira WEX-5785 Change 3426577 on 2017/05/05 by robomerge@ROBOMERGE_WEX_Main another pass at deprecation warnings #jira none Change 3426360 on 2017/05/05 by robomerge@ROBOMERGE_WEX_Main write out the UUID for the dSYM when generating the debug symbols #jira none Change 3426356 on 2017/05/05 by robomerge@ROBOMERGE_WEX_Main fix for deprecation warnings on IOS #jira none Change 3424160 on 2017/05/04 by robomerge@ROBOMERGE_WEX_Main fix for resetting the load status when attempting a second load of an asset #jira WEX-6226 Change 3423174 on 2017/05/04 by robomerge@ROBOMERGE_WEX_Main made an extra change I didn't need #jira none Change 3423173 on 2017/05/04 by robomerge@ROBOMERGE_WEX_Main fix for crash reports from build machine builds not symbolicating #jira none Change 3422009 on 2017/05/03 by Josh.May@WEX-Main-JMAY #WEX #JIRA: None - Added generic widget pooling support. Among other things, this allows us to reuse the same pool of HeroIcon widgets between all HeroLists. Change 3421747 on 2017/05/03 by robomerge@ROBOMERGE_WEX_Main [NULL MERGE] make it so we are back to 100MB temporary fix until I can either download the symbol file or symbolicate on the server #jira WEX-6142 Change 3420916 on 2017/05/03 by Brian.Zaugg@brian.zaugg_8402_WexDevMain #wex - Resaved Entry.umap to fix nondeterministic cooks. #jira WEX-5841 Change 3420757 on 2017/05/03 by robomerge@ROBOMERGE_WEX_Main fix for debug symbols not showing up in the ipa #jira none Change 3420620 on 2017/05/03 by robomerge@ROBOMERGE_WEX_Main fix for some more warnings #jira none Change 3420069 on 2017/05/02 by robomerge@ROBOMERGE_WEX_Main fix for build warning #JIRA none Change 3419305 on 2017/05/02 by robomerge@ROBOMERGE_WEX_Main crashreporter part 2, now sending reports to the database on successive run #jira WEX-5531 Change 3419050 on 2017/05/02 by Josh.May@WEX-Main-JMAY #WEX #JIRA: WEX-6037 - Added support for alert-less local notifications on iOS. Change 3418171 on 2017/05/02 by David.Nikdel@david.nikdel_WEX #WEX: Merging 3385512 by Aaron.McLeran minus 2 XBOX specific merge conflicts in XBoxOneTargetPlatform.cpp and libOpus.build.cs #JIRA: WEX-5829 Change 3412179 on 2017/04/27 by robomerge@ROBOMERGE_WEX_Main fix for new warnings from CrashDebugHelper in IOS #jira none Change 3411573 on 2017/04/27 by robomerge@ROBOMERGE_WEX_Main initial crash reporter changes (pt. 1) * client side to generate the crash report * inclusion of the debug symbols in the ipa #jira WEX-5531 Change 3410200 on 2017/04/26 by robomerge@ROBOMERGE_WEX_Main update to the dSymExporter to handle IOS #jira none Change 3409679 on 2017/04/26 by Rob.Cannaday@rob.cannaday_wex OpenSSL 1.0.2g updates from //UE4/Main Fixes prompt asking user to insert a disk on a removable drive #jira WEX-6136 Change 3408188 on 2017/04/25 by robomerge@ROBOMERGE_WEX_Main update to the chunk data to allow characters to have some duplicate data in their chunks this increases the installed size only slightly #jira WEX-6118 #jira WEX-5996 Change 3405129 on 2017/04/23 by Dmitriy.Dyomin@dmitriy.dyomin-wex Removed ZOrder manipulations for world map region widgets and restored caching in B_MenuBars #jira WEX-6071 Change 3404674 on 2017/04/21 by Chris.Babcock@Chris.Babcock_Z2433_WEX Better Android web browser closing #jira WEX-5871 #ue4 #android Change 3404003 on 2017/04/21 by robomerge@ROBOMERGE_WEX_Main revert out the lock free list change, was bleed over from a memory test #jira WEX-6077 Change 3403125 on 2017/04/21 by robomerge@ROBOMERGE_WEX_Main #WEX #JIRA: WEX-5669 - Exposed binadable OnRowReleased delegate for UListView. - Added UListView widget resuse for the FriendsList. As is, each FriendsList instance now uses at most 16 FriendWidget's apiece. Change 3402992 on 2017/04/20 by josh.may@WEX-Main-JMAY #WEX #JIRA: WEX-5669 - Refactored the FriendsList to use a UListView. Instead of handling UWExpFriendWidgets directly, the UListView tracks an array of UWExpFriendProxy objects and sets up the widgets based on what's visible. - Exposed a few STableViewBase functions to UListView's blueprint interface (scroll to start/end, list refreshing). Change 3402970 on 2017/04/20 by Chris.Babcock@Chris.Babcock_Z2433_WEX Fix copy-paste bug #jira WEX-5871 Change 3402914 on 2017/04/20 by Chris.Babcock@Chris.Babcock_Z2433_WEX Better behavior for Android LaunchURL #jira WEX-5871 #ue4 #android Change 3401897 on 2017/04/20 by robomerge@ROBOMERGE_WEX_Main Xcode 8.3 compiler fixes #jira none Change 3397963 on 2017/04/18 by robomerge@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: josh.may #WEX #JIRA: WEX-5966 - Added safer SAndroidWebBrowserWidget lookups. Rather than using the GetNativePtr result directly, we treat it as a key to lookup a WeakPtr to the corresponding SAndroidWebBrowserWidget. For the future, we may want to convert the key type to an FName to make this relationship more clear. Change 3397360 on 2017/04/18 by robomerge@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: michael.noland UMG - Fixing widget alignment in the viewport when using the widget component with screen space, with an aspect ratio lock on the player's camera. The widgets should now show up in the right locations. #reimplementing CL# 3371590 from Dev-Editor #jira None Change 3387613 on 2017/04/10 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - moving Android Facebook SDK to NFL directory #jira OGS-636 Change 3383489 on 2017/04/06 by Peter.Sauerbrei@peter.sauerbrei_WEX use pngs for iconbs in the plist properly copy icon pngs #jira none Change 3375079 on 2017/03/31 by Chris.Babcock@Chris.Babcock_Z2433_WEX Add missing keycodes for Android keyboard #jira WEX-5777 #android Change 3369953 on 2017/03/29 by David.Nikdel@david.nikdel_WEX #Android: (from ChrisB) - Workaround to not having GET_ACCOUNTS permission but calling GoogleAuthUtil.getToken anyway (causes a crash) - We don't need this token anyway so band-aiding it out #JIRA: WEX-5730 Change 3369826 on 2017/03/29 by Daniel.Vogel@battle_breakers trimmed include to only include what is needed #jira none Change3369563on 2017/03/29 by Allan.Bentham@allan.bentham_WEX Fix Android build error. fallout from 3358094 #jira WEX-5193 #rb none Change 3368945 on 2017/03/28 by Josh.May@WEX-Main-JMAY #WEX #JIRA: WEX-5675 - Ensure the local scope ScreenRect passed into OnVirtualKeyboardShown in AndroidJNI is captured by value instead of by reference. - Moved ShowVirtualKeyboardInput's bKeyboardShowing early-out checks into the UI thread task. This allows the keyboard to continue showing when changing focus between multiple EditableTextBox widgets. Change 3368793 on 2017/03/28 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - java toolchain changes for OnlineSubsystemGoogle - update google auth to 9.8.0 - update required sdk to 25 #jira none Change 3366529 on 2017/03/27 by Daniel.Vogel@battle_breakers added CSV output w/ class type skip /Script/ dependencies #jira n/a Change 3366478 on 2017/03/27 by Chris.Babcock@Chris.Babcock_Z2433_WEX Updated Android newkeyboard support * AndroidRuntimeSetting bEnableNewKeyboard instead of commandline to enable * Calculating the area covered by the virtual keyboard * Calling OnVirtualKeyboardShown and OnVirtualKeyboardHidden events * Passing the Rect of the area covered by the virtual keyboard OnVirtualKeyboardShown event #jira WEX-5675 Change 3364155 on 2017/03/24 by Josh.May@WEX-Main-JMAY #WEX #JIRA: WEX-5538 - Removed FPlatformMisc::IsPluggedIn() and migrated the iOS/Android implementations over to FPlatformMisc::IsRunningOnBattery(). - Fixed EBatteryState enumeration ordering in FAndroidMisc. According to Google's documentation, BATTERY_STATUS_CHARGING=2, BATTERY_STATUS_DISCHARGING=3, BATTERY_STATUS_FULL=5, BATTERY_STATUS_NOT_CHARGING=4, BATTERY_STATUS_UNKNOWN=1. Change 3363599 on 2017/03/24 by Josh.May@WEX-Main-JMAY #WEX #JIRA: WEX-5538 - Added FPlatformMisc::IsPluggedIn(). - Block battery drainage tracking when the device is plugged in. Change 3363498 on 2017/03/24 by robomerge@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei fix for archives having truncated directory names #jira none Change 3363297 on 2017/03/24 by Chris.Babcock@Chris.Babcock_Z2433_WEX Fix Android password hiding #jira WEX-5159 #ue4 #android #rb Peter.Sauerbrei Change 3362117 on 2017/03/23 by Josh.May@WEX-Main-JMAY #WEX #JIRA: WEX-5538, WEX-5591 - Added FPlatformMisc::GetBatteryLevel(). - Added battery usage tracking to the PerformanceTrackingManger. This is tracked per SecondaryContext and accumulated whenever the SecondaryContext changes. - Added BatteryTimeSpent and BatteryDelta attributes to the Perf_Menu analytics events. - Added OnEnterForeground and OnEnterBackground handling for performance analytics tracking. FWExpAnalytics now maintains it's own multicast delegates for both scenarios to avoid delegate registration ordering issues (i.e. OnEnterBackground informs subscribers prior to flushing it's AnalyticsProvider). Unfortunately, events sent during these transitions need to use the AnalyticsProvider directly to get around IsInGameThread() checks in FWExpAnalytics. I've added notes in FWExpAnalytics explaining this. - Added DevicePerfBucket to the FWExpAnalytics::StartSessionAttrs(). Change 3359313 on 2017/03/22 by David.Nikdel@david.nikdel_WEX #WidgetComponent - Create a simple box proxy for cases where the widget wouldn't otherwise be visible in the editor. #JIRA: none Change 3359294 on 2017/03/22 by David.Nikdel@david.nikdel_WEX #Engine #ActorComponents: Pasting components - Try to respect the pasted component's name if possible. - Disable tree updates while pasting (pasting 100 components generated O(100^2) node updates) - Scroll into view after pasting #JIRA: none Change 3359262 on 2017/03/22 by Josh.May@WEX-Main-JMAY #WEX #JIRA: WEX-5286 - Added an ActionMapping for toggling a 4th ParticleLODBias preset (VeryLow). - Added editor hotkeys for switching between specific LODLevels in Cascade. As is, the hotkeys are CTRL+M for LOD0, CTRL+Comma for LOD1, CTRL +Period for LOD3, and CTRL+Slash for LOD4. - Remapped the in-game ParticleLODBias hotkeys to match the hotkeys in Cascade. Change 3358952 on 2017/03/22 by Josh.May@WEX-Main-JMAY #WEX #JIRA: None Reverted my change that reversed Cascade's LOD ordering. Change 3358816 on 2017/03/22 by robomerge@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei some changes to track down this rare streaming crash #jira WEX-5631 Change 3358544 on 2017/03/22 by robomerge@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei fix for IOS 8 crash when trying to link Facebook addition of IOSVersionCompare to FIOSPlatformMisc #jira WEX-5613 Change 3358099 on 2017/03/22 by Allan.Bentham@allan.bentham_WEX Add 'bBuildWithHiddenSymbolVisibility' to AndroidPlatform.HasDefaultBuildConfig() bBuildWithHiddenSymbolVisibility defaults to false in BaseEngine.ini #jira WEX-5193 Change 3358094 on 2017/03/22 by Allan.Bentham@allan.bentham_WEX Added Android option to enable builds with hidden symbol visbility by default. (bBuildWithHiddenSymbolVisibility) Android links with -gc-sections to remove unused code/data Add JNI_METHOD for java accessible native functions, fix up existing JNI functions to use macro. Add support to generate a map file with android. #rb chris.babcock #jira WEX-5193 Change 3357775 on 2017/03/21 by Josh.May@WEX-Main-JMAY #WEX #JIRA: WEX-5286 - Promoted r.ParticleLODBias to a full-blown scalability setting. - Ensure DirectSet particle systems don't set their initial LODLevel based on LOD distances. - Ensure ParticleSystems get their initial LODLevel set on activation relative to the LODBias. - Reversed the Cascade's LOD ordering to be consistent with other systems. Change3352516on 2017/03/17 by David.Nikdel@david.nikdel_WEX #WEX: perforce is the devil #JIRA: none Change 3352404 on 2017/03/17 by David.Nikdel@david.nikdel_WEX #WEX: Moving LocalMCP into the WEX folder so UGS will sync it along with everything else #JIRA: none Change 3352291 on 2017/03/17 by David.Nikdel@david.nikdel_WEX #WEX: Fix for a bug in run-local-mcp-main.bat #JIRA: none Change 3352242 on 2017/03/17 by David.Nikdel@david.nikdel_WEX #WEX: Change build.gradle to pull from the EPIC_BUILD_CREDENTIALS_NEXUS_* env vars and hardcode repo url for now #JIRA: none Change 3352046 on 2017/03/17 by David.Nikdel@david.nikdel_WEX #WEX: Get the stream name from P4 in the run-local-mcp-main.bat script - removed wex's run-release.bat (won't be necessary) - removed the product_version param (going off stream name now) #JIRA: none Change 3351635 on 2017/03/17 by David.Nikdel@david.nikdel_WEX #WEX: LocalMCP changes to support release branch MCP download (still need maven to support RELEASE in addition to LATEST) #JIRA: none Change 3351165 on 2017/03/16 by robomerge@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei compile fix #jira none Change 3351162 on 2017/03/16 by robomerge@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei pull chunk 1 back out #jira WEX-4037 Change 3351075 on 2017/03/16 by robomerge@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei put all of the onboarding data in the apk, iinitial windows install, IOS is still too large for now #jira WEX-4037 Change 3351059 on 2017/03/16 by Josh.May@WEX-Main-JMAY #WEX #JIRA: WEX-5526 - Added analytics events for map load times (on Chance's behalf). No info about chunk downloading yet, though. Change 3350595 on 2017/03/16 by robomerge@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei move some of the onboarding data in to the IPA #jira WEX-4037 Change 3349934 on 2017/03/16 by robomerge@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei fix for splash screen disappearing on iPhone 5s and iPod Touch #jira none Change 3348093 on 2017/03/15 by robomerge@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei fix for iPod Touch 6 splash screen #jira WEX-5482 Change 3346183 on 2017/03/14 by robomerge@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei fix for portrait only not being respected #jira WEX-5517 Change 3344276 on 2017/03/13 by Chris.Babcock@Chris.Babcock_Z2433_WEX Fix target value 1.5 obsolete warning #android #jira: none Change 3344177 on 2017/03/13 by Chris.Babcock@Chris.Babcock_Z2433_WEX Add new notification icons #jira WEX-5173 #ue4 #android Change 3343706 on 2017/03/13 by Chris.Babcock@Chris.Babcock_Z2433_WEX Update script version for CarefullyRedist (need to use jdk1.8) #jira: none #android Change 3342571 on 2017/03/11 by David.Nikdel@david.nikdel_WEX #GooglePlay #Android #IAP: compile fix #JIRA: WEX-5479 Change 3342524 on 2017/03/11 by David.Nikdel@david.nikdel_WEX #IAP #GooglePlay #Engine: Fix for possible integer overflow getting price_amount_micros out of JSON. Really we should be returning this value (unadjusted) to C++ as a long to avoid precision loss, but converting to double until after removing micros is probably fine for all practical currency prices. #JIRA: WEX-5479 Change 3340549 on 2017/03/09 by Chris.Babcock@Chris.Babcock_Z2433_WEX Update handling of device and advertiser IDs for Android - remove GetUniqueDeviceId() - deprecated - add GetLoginId() - uses GUID approach - remove fallback from GetUnqiueAdvertisingId() - changed CreateUserId - don't send Attribution and UniqueDeviceId from USERLOGIN #jira WEX-5461 #ue4 #android #rb Wes.Hunt Change 3339488 on 2017/03/09 by David.Nikdel@david.nikdel_WEX #Engine #JSON - Expose FJsonObjectConverter::GetTextFromObject conversion method so this can be used elsewhere as appropriate #JIRA: none Change 3338332 on 2017/03/08 by Josh.May@WEX-Main-JMAY #WEX #JIRA: WEX-5367 - Added background transparency support for AndroidWebBrowserWidget. Change 3338176 on 2017/03/08 by Chris.Babcock@Chris.Babcock_Z2433_WEX Support large OBB files in APK - moved over since it also reduces process space used because OBB previously was mmapped #jira: none Change 3336630 on 2017/03/07 by Josh.May@WEX-Main-JMAY #WEX #JIRA: WEX-5367 - Ensure pending HTML content and URL are properly retained for IOSWebViewWrapper instances. This was a fix I added in CL 3214410 that got clobbered by the most recent engine merge. After repro'ing the crash again consistently on older devices, I figured I should readd it. - Added background transparency support for IOSWebViewWrapper. Change 3331981 on 2017/03/03 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - Online Subsystem consistency cleanup - all OSS classes use the instance name passed into the CreateFactory function - nothing should be using the default constructor - OnlineSubsystemImpl requires two params now (OSS name, Instance name) - added GetSubsystemName to return OSS name from OnlineSubsystemNames.h #JIRA none Change 3331955 on 2017/03/03 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - Google sign-in first pass - discovery service query - user consent screen - token exchange for access/refresh token - retrieve user profile - logout #JIRA WEX-5103 Change 3331947 on 2017/03/03 by Daniel.Vogel@battle_breakers added GDF export support #JIRA n/a Change 3331709 on 2017/03/03 by Daniel.Vogel@battle_breakers Added ExportDependencies to UnrealPak. It spits out a JSON of the game's package dependencies joined with size information from the PAK file. The format of the Json is array<Packages> InclusiveSize ExclusiveSize Name array<string> DirectlyReferencing array<string> DirectlyReferencedBy array<string> AllReferences allowing easy graph building and digestion of data. Usage example C:\Development\BB\WEX\Saved\StagedBuilds\WindowsNoEditor\WorldExplorers\Content\Paks\WorldExplorers-WindowsNoEditor.pak WorldExplorers WEX - exportdependencies=c:\dvtemp\output.json -debug -NoAssetRegistryCache -ForceDependsGathering #JIRA n/a Change 3329259 on 2017/03/02 by Peter.Sauerbrei@peter.sauerbrei_WEX switch to using jpgs for icons and splash screens Change 3329240 on 2017/03/02 by Peter.Sauerbrei@peter.sauerbrei_WEX remove all duplicate data from the paks Change 3328658 on 2017/03/01 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for low resolution on iPad Pro #jira WEX-5157 Change 3326751 on 2017/03/01 by Josh.May@WEX-Main-JMAY #WEX #JIRA: WEX-5278 - Reenable the system idle timer after FinalizeLevel has completed, as per David's feedback. - Added hooks for enabling/disabling the idle timer based on auto-battle being "paused" (i.e. having he options menu open). - Reworked the idle timer enable/disable logic for iOS to get around a silly platform limitation. As it turns out, re-enabling the system idle timer won't reset the system-recorded idle time, meaning the idle timeout can kick-in immediately after re-enabling the idle timer after long periods of inactivity (i.e. finishing a level with auto-battle enabled). Change 3323981 on 2017/02/27 by Josh.May@WEX-Main-MacBookPro #WEX - Fixed a iOS startup crash. It looks like the splash image path-string was getting released prematurely in cases where the JPG splash image doesn't exist. Change 3323478 on 2017/02/27 by Peter.Sauerbrei@peter.sauerbrei_WEX check for png and then jpg for splash screens Change 3320989 on 2017/02/24 by Chris.Babcock@Home_WEX Ignore AAR/JAR dependencies with scope "test" #android Change 3319897 on 2017/02/23 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - Last of the facebook cleanup - moved profile fields to common - added facebook profile picture to profile and friends structures - moved FacebookError to OnlineSubsystemFacebookTypes.h Change 3318425 on 2017/02/22 by Chris.Babcock@Chris.Babcock_Z2433_WEX Remove eglSwapInterval causing S6 to freeze #jira WEX-5147 #android Change 3317974 on 2017/02/22 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - Java toolchain fix for Facebook SDK - hack per ChrisB @codereview Chris.Babcock Change 3317968 on 2017/02/22 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - Facebook SDK for Android enabled Change 3317216 on 2017/02/22 by David.Nikdel@david.nikdel_WEX #Engine: Break out cursor building from settings into UGameViewportClient::RebuildCursors so that game code can call this method after RemoveAllViewportWidgets if we don't want to lose cursor settings. Change 3315560 on 2017/02/21 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - Facebook TPS files for iOS and Android latest SDKs Change 3315541 on 2017/02/21 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #WEX - Fixes for Facebook SDK changes - Fix for comment in DefaultPlatformService ini entry Change 3315529 on 2017/02/21 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - Android toolchain changes Change 3315492 on 2017/02/21 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - Facebook IOS Change 3315490 on 2017/02/21 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - Facebook Common Change 3315283 on 2017/02/21 by Colin.Pyle@Colin.Pyle_WEX_Main #WEX #JIRA: WEX-5114, WEX-5116 - Buttons now only respond to first finger touch events. Change 3315045 on 2017/02/21 by Peter.Sauerbrei@peter.sauerbrei_WEX enable compile for size on iOS Change 3310519 on 2017/02/17 by Chris.Babcock@Chris.Babcock_Z2433_WEX Implement GetUniqueDeviceId for Android - this doesn't identify the device uniquely if reinstalled; it will show as a new device since it uses GUID stored to local file #android Change 3310043 on 2017/02/17 by Chris.Babcock@Chris.Babcock_Z2433_WEX Fix bad merge related to UPL configuration variable (needed for Adjust on Android to use correct server) Change 3310024 on 2017/02/17 by David.Nikdel@david.nikdel_WEX #Android #AdvertisingId Merging shelf CL 3195079 for Chris.Babcock Change 3309580 on 2017/02/17 by Josh.May@WEX-Main-JMAY #WEX - Moved SOURCE_IN_LINEAR_SPACE shader #define to SlateShaderCommon. Change 3308653 on 2017/02/17 by Dmitriy.Dyomin@dmitriy.dyomin-wex ShaderCache will use up to 16 samplers #rb jack.porter Change 3307584 on 2017/02/16 by Josh.May@WEX-Main-MacBookPro #WEX #JIRA: WEX-5019 - Fixed "washed out" UMG widget coloring on iOS. Change 3305699 on 2017/02/16 by Dmitriy.Dyomin@dmitriy.dyomin-wex Clear for viewport instead of drawing quad on top, when scene rendering is disabled #rb Jack.Porter Change 3305662 on 2017/02/16 by Dmitriy.Dyomin@dmitriy.dyomin-wex Update invalidation panel to account for a new LayoutToRenderTransform Change 3305615 on 2017/02/16 by Dmitriy.Dyomin@dmitriy.dyomin-wex Invalidation panel fixes. Moved geometry checks and caching from Tick to OnPaint to account for Window resize transforms. Updating scissor rect inside cached elements. Change 3305019 on 2017/02/15 by Peter.Sauerbrei@peter.sauerbrei_WEX Merging using WEX_Main_to_UE4_WEX_Staging Change 3301188 on 2017/02/14 by Jack.Porter@Jack.Porter_WEX_Stream Added support for runtime change of the Android GT and RT affinity masks at the console. eg "android.DefaultThreadAffinity GT 0x1 RT 0x2". args are bitmasks for core(s) to run on, 0=all #rb Dmitriy.Dyomin Change 3300968 on 2017/02/13 by Dmitriy.Dyomin@dmitriy.dyomin-wex Option for invalidation panel to cache just drawable elements instead of render data (slate.CacheRenderData=0) Iinvalidation panel fixes #rb nick.darnell Change 3300554 on 2017/02/13 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: david.nikdel #WEX: serialize ClientVersion as a number instead of a string of the form "CL_####" Change 3300114 on 2017/02/13 by Peter.Sauerbrei@peter.sauerbrei_MacWEX fix for iOS build failure Change 3300059 on 2017/02/13 by Peter.Sauerbrei@peter.sauerbrei_WEX turn on PLCrashReporter for iOS Change 3300057 on 2017/02/13 by Peter.Sauerbrei@peter.sauerbrei_MacWEX built PLCrashReporter for IOS Change 3298338 on 2017/02/10 by Chris.Babcock@Chris.Babcock_Z2433_WEX Updated Java files that look like were missed in merge #rb none Change 3295755 on 2017/02/09 by Aaron.McLeran@Wex2 UE-41567 Fixes for duplicating sound assets Change 3295429 on 2017/02/09 by Peter.Sauerbrei@peter.sauerbrei_MacWEX re-enable pak pre-cache Change 3294463 on 2017/02/09 by Allan.Bentham@allan.bentham_WEX Bump shader version, hopefully will make WEX-4517 go away... #rb none Change 3294229 on 2017/02/09 by Allan.Bentham@allan.bentham_WEX Prevent UI materials producing encoded results. #jira WEX-4975 #rb Jack.Porter Change 3293759 on 2017/02/08 by Chris.Babcock@Chris.Babcock_Z2433_WEX Don't enqueue TickVideo since it is causing a hang (movies not used in WEX) DO NOT MOVE BACK #jira WEX-5046 #rb Max.Preussner Change 3291872 on 2017/02/08 by Allan.Bentham@allan.bentham_WEX add RGBA8 mode to mobile HDR 32bpp encoding methods. (render directly to RGBA8 scene colour target) r.MobileHDR32bppMode == 3 to override devices encoding mode with RGBA enabled in WEX for android low end devices. add mosaic state to android window's resolution cache conditions. #jira WEX-4927 #rb chris.babcock, jack.porter Change 3289698 on 2017/02/07 by Dmitriy.Dyomin@dmitriy.dyomin-wex Enabled bExplicitCanvasChildZOrder by default (saves more than 100 drawcalls in Heroes tab) Fixed ordering of CommanderBar image in B_HeroIcon Removed unique ZOrder for world map region widgets (saves more than 100 drawcalls in WorldMap) Change 3289082 on 2017/02/06 by Josh.Markiewicz@JMARKIEWICZ_WEX_MACPRO #UE4 - cleaned up some dev garbage in Facebook module file Change 3288589 on 2017/02/06 by Chris.Babcock@Chris.Babcock_Z2433_WEX Temporarily limit GMaxTextureSamples to 16 for Android #jira WEX-5051 #rb Peter.Sauerbrei Change 3286181 on 2017/02/03 by Tyler.Cole@tyler.cole-Z6140-stream-wex [Engine] LocalMcp run script: - Remove quotes from output. - Display progress bar when downloading artifact. - Output MongoDB data directory. Change 3286118 on 2017/02/03 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei [NULL MERGE] turn off logging in test builds in release stream Change 3286106 on 2017/02/03 by Kevin.Abbott@WEX2017 #LocalMCP: Fix for BAT file terribleness (the whole if command is evailuated at once so an internal SET doesn't take effect until outside the block) Change 3285065 on 2017/02/03 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei better fix for the app name in the archive Change 3285060 on 2017/02/03 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei fix for archive failure Change 3284408 on 2017/02/02 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei properly naming the dSYM for uploading #rb none Change 3284022 on 2017/02/02 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - Facebook changes to get Windows/iOS up to date - Facebook user data structure gets information from proper URL request with valid public fields, stores consistently on both platforms -- store values in generic key value pairs - RequestElevatedPermissions feature that goes through external ui to grant more permissions (Windows) - Reorder shutdown so that sharing interface can properly register/unregister from LoginStatusChanged events Change 3283978 on 2017/02/02 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei [NULL MERGE] potential fix for dSYM not uploading properly #rb none Change 3283672 on 2017/02/02 by Chris.Babcock@Chris.Babcock_Z2433_WEX Fix for web browser crash on Android distribution (from 4.15) #jira WEX-4947 #rb none Change 3283329 on 2017/02/02 by Tyler.Cole@tyler.cole-Z6140-stream-wex [Engine] Add support for uberjar MCPs in LocalMcp scripts. [WEX] Use uberjar when launching local MCP. Change 3283030 on 2017/02/02 by Allan.Bentham@allan.bentham_WEX Fix for tangents not being avaliable in ES2 pixel shader when transformvector/transformposition nodes are used. #jira WEX-4517. #rb jack.porter Change 3281190 on 2017/02/01 by Peter.Sauerbrei@peter.sauerbrei_MacWEX pull over the metal state rasterizer fix from main #jira WEX-4855 Change 3280541 on 2017/01/31 by Chris.Babcock@Chris.Babcock_Z2433_WEX More GCM work - platform=ANDROID for registration URL (case-sensitive) - hooked up registration through FPlatformMisc like iOS - removed old retrigger for delegates (not needed) - stubbed in unregister for later - added notification generation on message (disabled for now) Change 3280255 on 2017/01/31 by Michael.Noland@mnoland_T2801_WEX_Main Canvas: Fixed a bug where UCanvas::K2_DrawMaterial did not respect the currently active canvas draw color Upgrade Notes: This does change the behavior, so K2_DrawMaterial calls with a non-white color set will now be affected by the color *if* they use a vertex color node. Impact is expected to be minimal because most of the materials people used with it were unlikely to include the vertex color node. Change 3280150 on 2017/01/31 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for double add to manifests Change 3279807 on 2017/01/31 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for iOS build failure Change 3279583 on 2017/01/31 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for animation crash #jira WEX-4906 Change 3279310 on 2017/01/31 by Peter.Sauerbrei@peter.sauerbrei_WEX reduce the parallelism of the packaging step to alleviate strain on Mac Change 3278827 on 2017/01/31 by Dmitriy.Dyomin@dmitriy.dyomin-wex Fixed: Multiple UI assets appear too dark when accessed (replicated CL#3278637, 3278802 from 4.15) #jira WEX-4862 Change3278558on 2017/01/30 by Chance.Lyon@Chance.Lyon_WEX_Dev-Main #WEX #JIRA: WEX-4634 - Attempt to re-hide the navigation bar when we detect a few different events Change 3277376 on 2017/01/30 by Peter.Sauerbrei@peter.sauerbrei_WEX disable pak precaching as it seems to be causing crashes Change 3276469 on 2017/01/28 by Chris.Babcock@Chris.Babcock_Z2433_WEX Fixes for GoogleCloudMessaging - moved registration later to correct issues with engine not ready - save registration status message and token for later retrigger - UWExpMcpProfile::Initialize uses retrigger after binding to delegate so it gets the earlier success/fail - send correct platform in OnRegisteredForRemoteNotifications (Android or IOS) Change 3276308 on 2017/01/27 by Michael.Noland@mnoland_T2801_WEX_Main UBT: Improved the error message when the wrong header is first in an engine file to include the wrong file name Change 3275574 on 2017/01/27 by David.Nikdel@david.nikdel_WEX #WEX: performance tracking analytics tags - make FPerformanceTrackingChart::DumpChartToAnalyticsParams const-correct - Broke out the event firing code into their own functions and added scraper documentation (unsure if 100% correct, Michael please review) - changed #if to regular if so inner code gets compiled in all cases #JIRA: WEX-4838 Change 3275275 on 2017/01/27 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for missing virtual keyboard #jira WEX-4859 Change 3275266 on 2017/01/27 by Josh.Markiewicz@JMARKIEWICZ_WEX_MACPRO #UE4 - Facebook iOS upgrade to 4.18 IdentityInterface should be using proper in app dialogs now Change 3275263 on 2017/01/27 by Josh.Markiewicz@JMARKIEWICZ_WEX_MACPRO Facebook SDK 4.18 Change 3274408 on 2017/01/26 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for tower collision Change 3273928 on 2017/01/26 by Peter.Sauerbrei@peter.sauerbrei_WEX Merging //UE4/Release-4.15/Engine/Source/Runtime/... to //WEX/Main/Engine/Source/Runtime/... Change 3273907 on 2017/01/26 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - moved parsing of LogCategory verbosity slightly sooner to occur before plugins are loaded - fixes plugins not printing proper log levels if initialized too early #rb gil.gribb Change 3272834 on 2017/01/25 by Chris.Babcock@Chris.Babcock_Z2433_WEX Add GoogleCloudMessaging plugin for Android Change 3272124 on 2017/01/25 by Jamie.Dale@JamieDale_BHX-WD-7636_WEX Updated the GatherText commandlet to no longer hold a ConfigFile pointer while it runs This pointer is internal to GConfig, and may be updated (or invalidated) when other config files are loaded (as can happen via game code while gathering text). #rb Peter.Sauerbrei Change 3272044 on 2017/01/25 by David.Nikdel@david.nikdel_WEX #Json: Adding MapProperty support to JsonObjectConverter - Only TMaps with FString keys are allowed (to match JSON spec) - ScheduledEvents module is dependent on this commit (at runtime, compile is ok) Change 3272035 on 2017/01/25 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for crash when trying to pre-cache a pak file smaller than the cache granularity Change 3271618 on 2017/01/25 by Allan.Bentham@allan.bentham_WEX Avoid unneeded stencil clear in mobile renderer. #rb jack.porter Change 3271536 on 2017/01/25 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for non-unity compile failures Change 3270865 on 2017/01/24 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for another warning Change 3270781 on 2017/01/24 by Peter.Sauerbrei@peter.sauerbrei_WEX some warning fixes Change 3270395 on 2017/01/24 by Nick.Darnell@Nick.Darnell_BattleBreakers UMG - Adding a way to config the default option for how Scaleboxes should perform layout, single or double. #rb none Change 3270051 on 2017/01/24 by Peter.Sauerbrei@peter.sauerbrei_WEX Merging using WEX_Main_to_UE4_WEX_Staging #rb none Change 3268999 on 2017/01/23 by Colin.Pyle@Colin.Pyle_WEX_Main #WEX #JIRA: WEX-4685 - Scale boxes now default to single pass Change 3263481 on 2017/01/19 by Dmitriy.Dyomin@dmitriy.dyomin-wex Enabled shader cache on Android Also added recorded shader cache from my play session (need to record more complete cache later) #rb jack.porter #jira WEX-4691 Change 3258935 on 2017/01/16 by David.Nikdel@david.nikdel_WEX #WebBrowser: Fix field initialization order warning. Change 3258614 on 2017/01/16 by David.Nikdel@david.nikdel_WEX #Engine #WebBrowser: - LoadString literally didn't work on strings with line breaks in them due to our forwarding of the request content via the headers (wut?). Cef barfed trying to parse header values with newlines in them. - Changed locally generated requests to use PostData instead. - Added a way to specify the mime type by appending a hash to the dummy url (the BP params for this are all kinds of weird, but I don't want to change the signature) - Default mime type to text/html to support the old behavior Change 3257030 on 2017/01/13 by Peter.Sauerbrei@peter.sauerbrei_WEX turn on test logging DO NOT SUBMIT THIS TO UE4/MAIN #rb none Change 3256835 on 2017/01/13 by Nick.Darnell@Nick.Darnell_BattleBreakers Slate - Fixing the size of Paper2D sprites when used as box brushes in Slate. #rb none Change 3256813 on 2017/01/13 by Nick.Darnell@Nick.Darnell_BattleBreakers Slate/UMG - The ScaleBox now supports a SingleLayoutPass mode. This mode is not the default, but it can save a considerable amount of time in the right situation. Generally when wrapped around a large UI, where the outer bounds of the scalebox are constant. #rb none Change 3256777 on 2017/01/13 by Nick.Darnell@Nick.Darnell_BattleBreakers UMG - Adding a way to access the absolute size of a piece of Geometry in blueprints. #rb none Change 3256774 on 2017/01/13 by Nick.Darnell@Nick.Darnell_BattleBreakers UMG - Adding a way to access the absolute size of a piece of Geometry in blueprints. #rb none Change 3256656 on 2017/01/13 by Dmitriy.Dyomin@dmitriy.dyomin-wex Slate pixel shaders will use half precision where possible on mobile #rb jack.porter Change 3256586 on 2017/01/13 by Dmitriy.Dyomin@dmitriy.dyomin-wex Fixed redundant blend state changes in opengl #rb jack.porter Change 3256584 on 2017/01/13 by Dmitriy.Dyomin@dmitriy.dyomin-wex Reduced state setup for slate draw calls (saves about 4ms RT time on mobile) #rb jack.porter Change 3256380 on 2017/01/12 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei properly set the file extension for the dSYM for the manifest #rb none Change 3256260 on 2017/01/12 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei trying to track down why the dSYM isn't working #rb none Change 3255825 on 2017/01/12 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei return the zip version for now #rb none Change 3255652 on 2017/01/12 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei add dSYM.zip to the output produced if we want the dSYMBundle utilize that if it exists to populate the xcarchive #rb none Change 3254552 on 2017/01/11 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei fix for build error #rb none Change 3254462 on 2017/01/11 by Chris.Babcock@Chris.Babcock_Z2433_WEX C string is not null terminated in FCurlHttpRequest::DebugCallback #jira WEX-4610 Change 3254448 on 2017/01/11 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei make it so xcarchives can be archived to a directory on build machines make it so the build machine puts the CL in as the CFBundleVersion make it so we generated an XCArchive and a dSYM #rb none Change 3251055 on 2017/01/09 by Nick.Darnell@Nick.Darnell_BattleBreakers Platform - Adding the degree symbol to the log statement for android's temperature update, and noting that it's celsius. #rb none Change 3250488 on 2017/01/08 by Dmitriy.Dyomin@dmitriy.dyomin-wex Fixed: Device output log partial lines #rb jack.porter Change 3249072 on 2017/01/06 by Dmitriy.Dyomin@dmitriy.dyomin-wex Disable java console cmd receiver only in shipping builds #rb jack.porter Change 3248990 on 2017/01/06 by Jack.Porter@Jack.Porter_WEX_Stream Support Dynamic r.MobileContentScaleFactor change on Android #rb Dmitriy.Dyomin Change 3248989 on 2017/01/06 by Jack.Porter@Jack.Porter_WEX_Stream Integrating Mobile Support for r.ScreenPercentage #rb Dmitriy.Dyomin Change 3248156 on 2017/01/05 by Chris.Babcock@Chris.Babcock_Z2433_WEX Added trackSubsessionStart to iOS Adjust plugin (for real) #ios Change 3248131 on 2017/01/05 by Chris.Babcock@Chris.Babcock_Z2433_WEX Added trackSubsessionStart to iOS Adjust plugin #ios Change 3245184 on 2017/01/03 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - FB OSS for PC - login flow implemented using web based LoginFlow module - implemented ShowLoginUI for external UI interface - added Login function with existing access token - fixed GetAuthType function - added reference to main online subsystem to Friend/Identity interfaces Change 3243067 on 2016/12/22 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - used more prpoer shared pointer cast Change 3241011 on 2016/12/20 by Chance.Lyon@Chance.Lyon_WEX_Dev-Main #WEX #JIRA WEX-4557 - An engine change that separates serializing the actor from file operations - Serialize the saved level on the main thread, save it to a slot during the async task Change 3240508 on 2016/12/19 by Michael.Noland@mnoland_T2801_WEX_Main Engine: Added GetGameInstance<T> and GetGameInstanceChecked<T> wrappers to UWorld that automatically Cast/CastChecked to the specified subclass of UGameInstance Change 3240366 on 2016/12/19 by Josh.May@josh.may-WEX-MacBookPro-DevMain #WEX #JIRA: WEX-4475 - Block UIWebView closure from granting keyboard focus to the parent IOSView. This was causing the keyboard to show when closing the UIWebView after interacting with it in any way. Change 3239026 on 2016/12/16 by Nick.Darnell@Nick.Darnell_BattleBreakers Slate - Removing a crashing check that turned out to not be nessesary. Change 3238569 on 2016/12/16 by Nick.Darnell@Nick.Darnell_BattleBreakers Slate - Disabling the deferred desired size optimization. Change 3237052 on 2016/12/15 by David.Nikdel@david.nikdel_WEX #PlatformMisc: GetUniqueAdvertisingId should return empty string unless one is defined by the platform (no fallback to GetUniqueDeviceId) Change 3237024 on 2016/12/15 by Nick.Darnell@Nick.Darnell_BattleBreakers Slate - Core Refactor. Found a way to save about 2ms on mobile for an average screen. It involves deferring when slate computes the desired size of a widget, from during prepass, to instead doing it on demand, and only invalidating it during Prepass. It saves time because not every widget cares what the desired size of their children is. I'm enabling it with the code define SLATE_DEFERRED_DESIRED_SIZE. I've added an ensure prints the message, "The layout is cyclically dependent. A child widget can not ask the desired size of a parent while the parent is asking the desired size of its children." Change 3236593 on 2016/12/15 by Nick.Darnell@Nick.Darnell_BattleBreakers Slate - Optimizing some usage of FWidgetPath and other reduction on copies on the stack/heap. Change 3236579 on 2016/12/15 by Nick.Darnell@Nick.Darnell_BattleBreakers Slate - You can now visualize batching by doing Slate.ShowBatching 1. Change 3236453 on 2016/12/15 by Nick.Darnell@Nick.Darnell_BattleBreakers Slate - Further refactoring how the scrollbox manages when and how to perform scrolling when dealing with touch input. Feels really tight to me now and this change should resolve the problem where it sometimes doesn't respond to input, or where it over-responds to touch and amplifies movement by the user, not able to reproduce those conditions now. Change 3236435 on 2016/12/15 by Nick.Darnell@Nick.Darnell_BattleBreakers Core - Fixing some bugs with FrameValue, making it a bit simpler by just being composed of a TOptional and a uint64. Change 3236410 on 2016/12/15 by Nick.Darnell@Nick.Darnell_BattleBreakers Engine - Fixing a crash in the game viewport client if no debug canvas is provded. Change 3236405 on 2016/12/15 by Nick.Darnell@Nick.Darnell_BattleBreakers Android - Fixing the code that sends remote commands to android. Change 3233400 on 2016/12/13 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for console entry #jira WEX-4488 Change 3233247 on 2016/12/13 by Nick.Darnell@Nick.Darnell_BattleBreakers Slate - Adding some scoped performance counters for more rendering infromation in slate. Change 3233242 on 2016/12/13 by Nick.Darnell@Nick.Darnell_BattleBreakers UMG - Making a few calls more efficent for mobile, by caching values for a frame that end up getting called a lot if you have several widget components. Change 3233236 on 2016/12/13 by Nick.Darnell@Nick.Darnell_BattleBreakers Core - Adding a frame cached value struct that keeps a value as valid for one GFrameCounter, which is incremented once an engine tick. Change 3233229 on 2016/12/13 by Nick.Darnell@Nick.Darnell_BattleBreakers UMG - Don't layout components if they're not marked as visible in the world widget screen layer for widget componets. Change 3233219 on 2016/12/13 by Nick.Darnell@Nick.Darnell_BattleBreakers Blueprints - Making the array K2 Nodes not self referencial in doing layout logic, that causes really strange behavior. Change 3233209 on 2016/12/13 by Nick.Darnell@Nick.Darnell_BattleBreakers Slate - You can now show overdraw in slate by doing Slate.ShowOverdraw 1, or 0 to disable. Change 3233202 on 2016/12/13 by Nick.Darnell@Nick.Darnell_BattleBreakers Slate - We now have a scope counter for text layout now, to let people determine when their text is a massive performance drain usually due to scaleboxes. Change 3233012 on 2016/12/13 by Michael.Noland@mnoland_T2801_WEX_Main Sound: Added SoundClassObject to the asset registry searchable data for sound assets, to make it easier to track down volume/muting bugs when assets have the wrong sound class set - Note: Assets will need to be resaved before this data will show up for unloaded assets (loaded assets should work immediately) Change 3230757 on 2016/12/12 by Andrew.Brown@Andrew.Brown_G5751_WEX_Main LauncherCheck module no longer has a dependancy on the DesktopPlatform module #jira OPP-6491 : LauncherCheck module is dependent on a DeveloperModule #branch WEX_Dev-Main #change Removed all the Launcher specific calls that the LauncherCheck module makes out of DesktopPlatform and into a new runtime module called LauncherPlatform (and fixed up all the associated calls). #change Also removed DesktopPlatform header/module usage from files if it's no longer needed. Change 3229399 on 2016/12/09 by Josh.May@josh.may-WEX-MacBookPro-DevMain #WEX #JIRA: WEX-3793 - Added config support for enabling/disabling the iOS integrated keyboard implementation. - Switched over to using the iOS integrated keyboard implementation. - Ensure the character code, rather than the key code, is passed in to IOSInputInterface's calls to OnKeyChar. This caused the backspace key to not function as intended... - Expanded the iOS integrated keyboard implementation to support different keyboard types and keyboard deactivation when text field widget focus is lost. Change 3228702 on 2016/12/09 by Nick.Darnell@Nick.Darnell_BattleBreakers Widget Compiler - Improving the error message for multiple widget trees. Change 3228369 on 2016/12/08 by Nick.Darnell@Nick.Darnell_BattleBreakers Engine - Adding an OnStart to UGameInstance that is called for both StartPIEGameInstance and StartGameInstance. Change 3228267 on 2016/12/08 by Nick.Darnell@Nick.Darnell_BattleBreakers Windows - Adding code to catch remote desktop cases where no mouse was detected, but it's a remote session, which sometimes doesn't list a mouse, which affects how the engine handles input. Change 3226374 on 2016/12/07 by Nick.Darnell@Nick.Darnell_BattleBreakers UMG - Exposing a way to dynamically set the touch/click method on buttons. Change 3226320 on 2016/12/07 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei fix for get-task-allow being true when distribution is enabled Change 3226103 on 2016/12/07 by Nick.Darnell@Nick.Darnell_BattleBreakers Editor - Adding PPI/DPI to the unit conversion tables. Change 3225274 on 2016/12/07 by Michael.Noland@mnoland_T2801_WEX_Main Engine: Made "Can't load invalid package" warning clearer that it has a name (and thus clearer when there was no name at all) Change 3224426 on 2016/12/06 by Michael.Noland@mnoland_T2801_WEX_Main Platform: Improved the warning message slightly when there is no local notification service Change 3224421 on 2016/12/06 by Michael.Noland@mnoland_T2801_WEX_Main Engine: Prevent fighting between GEngine->SetMaxFPS and UGameUserSettings::SetFrameRateLimitCVar that caused log spam by preserving the 'last set' reason when changing the value Change 3224401 on 2016/12/06 by Michael.Noland@mnoland_T2801_WEX_Main [Reimplemented CL# 3134965 from Dev-Blueprints] Fix for crash in FCDODiffControl when CDOs have different numbers of properties. First branch in the while loop would incorrectly advance Iter past the end of the array. Comments courtesy of Jon.Nabozny #jira UE-36263 Change 3224380 on 2016/12/06 by Michael.Noland@mnoland_T2801_WEX_Main UMG: Added a compilation warning for naughty child blueprints that define a widget hierarchy if the parent also has one (only the children widgets will be created, the parent ones are ignored) Change 3224084 on 2016/12/06 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: josh.markiewicz #UE4 - Add ue4.displaymetrics.dpi metadata to query device DPI for Android *MERGED* Change: 3216126 Date: 11/30/2016 6:10 PM Change 3223665 on 2016/12/06 by Chance.Lyon@Chance.Lyon_WEX_Dev-Main #WEX #JIRA: WEX-3557 - Reduce the uniform buffer size for Android GPU's Change 3222576 on 2016/12/05 by Michael.Noland@mnoland_T2801_WEX_Main MediaPlayer: Fixed a typo in the editor style that included .png twice Change 3222574 on 2016/12/05 by Michael.Noland@mnoland_T2801_WEX_Main Editor: Added the missing editor Slate brush WhiteGroupBorder (been missing since branch creation, no idea why) Change 3222487 on 2016/12/05 by Michael.Noland@mnoland_T2801_WEX_Main [Reimplementing CL# 3149669 from Dev-Core] Lower verbosity of warnings from deleting native properties. These cases do not cause any problems and are not fixable without resaving the content after it has started warning. I checked Jira history and neither of these warnings has ever found a real bug, but has caused a lot of content to be resaved unnecessarily. Change 3222486 on 2016/12/05 by Michael.Noland@mnoland_T2801_WEX_Main [Reimplementing CL# 3149397 from Dev-Framework] Fix collision profile writing out response values to channels that don't exist. Change 3222485 on 2016/12/05 by Michael.Noland@mnoland_T2801_WEX_Main Engine: Undoing a temporary workaround for one kind of warning that caused a different kind of warning (RE: property in collision profiles) Change 3222341 on 2016/12/05 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: david.nikdel Back out changelist 3220848 now that NickD's proper fix is in Change 3222327 on 2016/12/05 by Nick.Darnell@Nick.Darnell_BattleBreakers UI - Missions markers should now accept a single click to become activated. UI - This should resolve the majority of problems with the game getting stuck in a state where mouse capture was stolen permanatly. UI - Game should no longer register swipe too easily, it's now using the physical distance calculation for the screen. #jira WEX-4390 #jira WEX-4137 #jira WEX-4373 Change 3222046 on 2016/12/05 by Nick.Darnell@Nick.Darnell_BattleBreakers Android / IOS / Platform - Updating the logic for screen density to call an internal one overridden by each platform, and to cache that in GenericPlatformMisc, also adding some calls to convert Inches to Pixels and Pixels to Inches. Did some general cleanup around this work with names and such. Slate - Also fixing an issue in SlateApp, we now always break mouse lock on Touch input when a finger is released. Change 3221875 on 2016/12/05 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: david.nikdel #ChunkInstaller: - Added support for errors that may occur during ParseManifest - Renamed BuildVersion (variable) to BuildUrl to match JSON key - Fail parsing on bad file entry - In the event of a client mismatch, fail manifest download with a specific error (will need to plus this later at the app level) - Don't rebind delegates when entering Setup after a Retry - Check bNeedsRetry befpre doing countdown for auto-retry Change 3221737 on 2016/12/05 by Michael.Noland@mnoland_T2801_WEX_Main Engine: Added the ability to suppress warnings when using on-screen log warning/error display (DurationOfErrorsAndWarningsOnHUD > 0) by setting Engine.SupressWarningsInOnScreenDisplay to 1 Change 3221593 on 2016/12/05 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei fix for icons missing in the IPA #jira WEX-4380 Change 3220588 on 2016/12/03 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: david.nikdel #IOS #PlatformMisc: Adding PPI information for IOS_IPhone7 and IOS_IPhone7Plus Change 3220084 on 2016/12/02 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei fix for iPhone 7/7Plus not finding the correct splash screen image for holding addition of iPhone 7/7Plus device profiles hold the splash screen until the manifest is downloaded Change 3220056 on 2016/12/02 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei changes to make it so we only copy the images needed for the support orientations set minimu iOS to 8 Change3220036on 2016/12/02 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei make it so the engine doesn't try to load editor only content in the game #jira WEX-4319 Change 3219992 on 2016/12/02 by Nick.Darnell@Nick.Darnell_BattleBreakers Slate - Locking down the exposure of ComputeDesiredSize, this function was never intended to be public on widgets, so trying to prevent that. Change 3219754 on 2016/12/02 by Nick.Darnell@Nick.Darnell_BattleBreakers Adding the console command Slate.ShowDebugTextLayout to help debug layout issues in Slate. Change 3218374 on 2016/12/01 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei some code missed in an earlier check-in to reduce data duplication in chunks Change 3218358 on 2016/12/01 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: michael.noland Engine: Changed FPSChart analytics events to send IniPlatformName instead of PlatformName for the PlatformName parameter - Most platforms don't change - Android removes the texture format suffix from it (main goal of the change, though it also unifies behavior with a number of other analytics events that were already using IniPlatformName) - Desktop platforms remove the editor/client/server distinction, which should be fine since the event names for client/server are different already #rb david.nikdel Change 3218354 on 2016/12/01 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: michael.noland Engine: Added FPlatformMisc::GetDeviceMakeAndModel() which tries to return DeviceMake|DeviceModel where possible, and CPUVendor|CPUBrand otherwise #rb david.nikdel Change 3218353 on 2016/12/01 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: michael.noland Engine: Added reporting of PeakPhysical and PeakVirtual memory usage to FPS chart analytics #rb david.nikdel #jira WEX-4342 Change 3217769 on 2016/12/01 by Nick.Darnell@Nick.Darnell_BattleBreakers Slate - Disabled widgets now render correctly on mobile. Previously they were being transformed as if they were in linear space, on mobile the textures and fonts are already in gamma space, so the transform for luminance needs to also be done in gamma space. Change 3217059 on 2016/12/01 by Nick.Darnell@Nick.Darnell_BattleBreakers Slate/UMG - Tweaking how the scrollbars fade on different platforms to be a platform defined feature. Cleaning up some logic in the InertialScrollManager to be configurable externally. Change 3216605 on 2016/12/01 by Dmitriy.Dyomin@dmitriy.dyomin-wex Fixed precision issues on Adreno devices when sampling sRGB textures #rb Jack.Porter Change 3216388 on 2016/11/30 by Nick.Darnell@Nick.Darnell_BattleBreakers IOS - Tweaking the unknown screen density value to be a multiple of the native CSF, which should get us pretty close. Change 3216382 on 2016/11/30 by Nick.Darnell@Nick.Darnell_BattleBreakers Android - Calculating CSF using the surface size vs window size. Change 3216376 on 2016/11/30 by Nick.Darnell@Nick.Darnell_BattleBreakers IOS - Fixing a bug with scaling screen density by the content scale factor. Change 3216335 on 2016/11/30 by Nick.Darnell@Nick.Darnell_BattleBreakers Android - Converting the code over in GetPhysicalScreenDensity to use an average of xdpi and ydpi as the approximate density, as the direct density call is affected by users adjusting their screen size option in the OS, which we definitely are not interested in taking into account here. Change 3216313 on 2016/11/30 by Nick.Darnell@Nick.Darnell_BattleBreakers Build - Fixing the build on mac. Change 3216126 on 2016/11/30 by Chris.Babcock@Chris.Babcock_Z2433_WEX Add ue4.displaymetrics.dpi metadata to query device DPI for Android Change 3215983 on 2016/11/30 by Nick.Darnell@Nick.Darnell_BattleBreakers Slate - Reverting a change to button I was testing things with. Change 3215971 on 2016/11/30 by Nick.Darnell@Nick.Darnell_BattleBreakers UMG/Android - Making several improvements to the way mobile scrolling is handled in UMG/Slate. Introducing a way to get the Physical Screen Density on Android and iOS. On iOS it's a hardcoded set of densities, for android they're loaded from the AndroidEngine.ini. If we can't find a match to the model phone you're on, we rely on the OS to report a reasonable screen density. With physical screen dimension knowledge, we can make much better decisions about deadzones around the finger before things like Drags are triggered. This change also introduces a gesture detector to Slate so that Slate can simulate gestures that may not be provided by the OS. The first and only gesture we currently support is the new Long Press gesture that has been added. The innertial scrolling logic has been rewriten on the ScrollBox, and the inertial scroll manager now has a better default experience. Change 3215963 on 2016/11/30 by Nick.Darnell@Nick.Darnell_BattleBreakers UMG - Making a pass on invalidation. The ability to store invalidated elements in local space locations and apply transforms in the GPU had rotted, restoring that functionality. Change 3214960 on 2016/11/30 by Nick.Darnell@Nick.Darnell_BattleBreakers Android - Adding a visualizers file for the Nsight Tegra debugger for visual studio for UE4 types. Change 3214557 on 2016/11/29 by Dmitriy.Dyomin@dmitriy.dyomin-wex Disable dynamic buffer discarding on Adreno330 (was casuing 10ms stalls on slate buffers update) #rb Jack.Porter Change 3214410 on 2016/11/29 by Josh.May@josh.may-WEX-MacBookPro-DevMain #WEX #JIRA: WEX-4255 - Ensure pending HTML content and URL are properly retained for IOSWebViewWrapper instances. Change 3213890 on 2016/11/29 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei update to the notification delegates to add a parameter for the state of the app when the notification was recieved Change 3212287 on 2016/11/28 by Josh.May@josh.may-WEX-JMAY-Main #WEX #JIRA: WEX-4135 - Added a full purge of GC array pool following full GC purges. Change 3212256 on 2016/11/28 by Chris.Babcock@Chris.Babcock_Z2433_WEX Adjust analytics plugin for Android and iOS #jira WEX-3939 #rb David.Nikdel Change 3211730 on 2016/11/28 by Allan.Bentham@allan.bentham_WEX Create and set PrimitiveSceneProxy->PrimitiveSceneInfo before SetTransform render thread command is enqueued. Avoids race condition with FPrimitiveSceneInfo's constructor which can occur on out-of-order CPUs. #jira WEX-3691 #rb jack.porter Change 3207395 on 2016/11/22 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: bruce.knapik #WEX Final fix for buildmachine crash Change 3207375 on 2016/11/22 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: bruce.knapik #WEX Fix for crash on buildmachine part 2: this time I saved the file! Change 3207341 on 2016/11/22 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: bruce.knapik #WEX Fix for crash on buildmachine Change 3207019 on 2016/11/21 by Jason.Bestimt@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei temporary fix for crash after logging in #jira WEX-4085 Change 3205594 on 2016/11/20 by Jack.Porter@Jack.Porter_WEX_Stream Added workaround for WEX-2079 - Fog effects on the map are rendering as circles. Change 3204498 on 2016/11/18 by Peter.Sauerbrei@peter.sauerbrei_WEX update IPP to look at Library/Caches as well when backing up the documents Change 3204238 on 2016/11/18 by Peter.Sauerbrei@peter.sauerbrei_MacWEX implement peak memory stats on IOS #jira WEX-3947 Change 3204187 on 2016/11/18 by Peter.Sauerbrei@peter.sauerbrei_WEX GPU vendor data from MichaelN Change 3203487 on 2016/11/17 by Peter.Sauerbrei@peter.sauerbrei_WEX latest changes to generate the proper manifest and be ready for MCP Change 3203362 on 2016/11/17 by Peter.Sauerbrei@peter.sauerbrei_WEX bringing over fix for Apple HTTP requests Change 3203188 on 2016/11/17 by Peter.Sauerbrei@peter.sauerbrei_WEX slightly better fix for the curl crash Change 3202785 on 2016/11/17 by Peter.Sauerbrei@peter.sauerbrei_MacWEX IOS now reads/writes from Library/Caches instead of Documents Change 3202565 on 2016/11/17 by Peter.Sauerbrei@peter.sauerbrei_WEX switch to platform manifest names in prep for switch to MCP disable screen saver while downloading chunks another potential build machine speed up Change 3202141 on 2016/11/17 by Peter.Sauerbrei@peter.sauerbrei_WEX correct fix for cook crash Change 3201994 on 2016/11/17 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for crash when cooking without chunks Change 3201552 on 2016/11/16 by Peter.Sauerbrei@peter.sauerbrei_WEX chunk assignment fixes Change 3201315 on 2016/11/16 by Chris.Babcock@Chris.Babcock_Z2433_WEX Return Android Make, Model, and Version for GetCPUVendor, GetCPUBrand, GetOSVersions #rb Michael.Noland Change 3200892 on 2016/11/16 by Michael.Noland@mnoland_T2801_WEX_Main Editor: Fixed a crash when opening the cooker settings panel (and got rid of some junk string literals) Change 3200737 on 2016/11/16 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for Android build error Change 3200719 on 2016/11/16 by Peter.Sauerbrei@peter.sauerbrei_WEX potential speed up of builds Change 3200608 on 2016/11/16 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for crash in the curl debug info callback #jira WEX-4039 Change 3200237 on 2016/11/16 by Jack.Porter@Jack.Porter_WEX_Stream Remove mosaic resolution limitation on ES3 devices #jira WEX-3119 #rb Dmitriy.Dyomin Change 3199640 on 2016/11/15 by Peter.Sauerbrei@peter.sauerbrei_WEX addition of the device token to the log Change 3199313 on 2016/11/15 by Peter.Sauerbrei@peter.sauerbrei_WEX switch back to IOSCompile-01 for default mac Change 3198769 on 2016/11/15 by Peter.Sauerbrei@peter.sauerbrei_WEX allow different deployments from the command line when using chunking NOTE: you can NOT change the deployment after starting due to the way chunking downloads data #jira WEX-3951 Change 3198423 on 2016/11/15 by Peter.Sauerbrei@peter.sauerbrei_WEX potential fix for audio cued at different speeds #jira WEX-3637 Change 3197915 on 2016/11/15 by Josh.May@josh.may-WEX-MacBookPro-DevMain #WEX - Disabled freed alloc caching for MallocBinned on mobile. Change 3197734 on 2016/11/14 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for IOS never enabling the chunk data Change 3197732 on 2016/11/14 by Michael.Noland@mnoland_T2801_WEX_Main Engine: Moved FDumpFPSChartToEndpoint to the public header, and fixed an ensure if sending FPS chart analytics during shutdown (now sends 0,0 for SizeX/SizeY rather than omitting them entirely) Change 3197720 on 2016/11/14 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #WEX - reconciled android settings - added placeholder app id Change 3196696 on 2016/11/14 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for missing platform for promotion Change 3196628 on 2016/11/14 by David.Nikdel@david.nikdel_WEX #Analytics: Added "AttributionId" field to SessionStart event. This reflects the advertising tracking ID for a given device (for iOS this is the IDFA). Change 3196534 on 2016/11/14 by Peter.Sauerbrei@peter.sauerbrei_WEX missed one texture on the resave Change 3196310 on 2016/11/14 by Peter.Sauerbrei@peter.sauerbrei_WEX warning reduction Change 3196287 on 2016/11/14 by Peter.Sauerbrei@peter.sauerbrei_WEX resaved engine materials to a version Change 3196103 on 2016/11/12 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for heroes not showing up in the hero inspect menu for chunking they will briefly show as a question mark until the download completes, might want an animated effect instead for the future #jira WEX-3936 #jira WEX-3958 Change 3195827 on 2016/11/11 by Michael.Noland@mnoland_T2801_WEX_Main UMG: Changed wording of warning slightly Change 3195806 on 2016/11/11 by Michael.Noland@mnoland_T2801_WEX_Main UMG: Added a warning message to UWidget::RemoveFromParent when being used to remove an instantiated widget that has no UMG parent owner (e.g., someone manually called TakeWidget and placed it in a native Slate slot). In this case it is a no-op, and the user was probably expecting it to remove it from the native parent widget and destroy the slot, which is impossible at this level (the calling code needs to handle that directly) Change 3195210 on 2016/11/11 by Peter.Sauerbrei@peter.sauerbrei_WEX addition of advertising id, IOS implemented Change 3195124 on 2016/11/11 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #WEX - android setup for new permanent backend - added BattleBreakers keystore - added billing settings for android in both Engine/Game AndroidEngine.ini (why do we have settings in both that overlap, DefaultPlatform for OSS was wrong there) - turned on ForDistribution (not sure how this affects other platforms, but Android won't work without this) Change 3194283 on 2016/11/10 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - hopefully last of the Android/GooglePlay cleanup - QueryInAppPurchases never needed an array of consumables flag - BeginPurchase doesn't take a bConsumable flag (old code calls it inside PurchaseComplete, new interface requires call to FinalizePurchase) - all java functions now return the productToken as part of the callback if applicable -- token easily accessible in java, saves Base64 decode and json calls to get in native - ** note ** fixed up GameCircle/Amazon, fortunately it didn't use these flags either Change 3194208 on 2016/11/10 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - GooglePlay purchasing refactor - finished QueryReceipts to not care about bRestorePurchases and left comment with explanation - delegates to low level GooglePlay calls return FGoogleTransactionData to sooner encapsulate the opaque data - fixed up RestoreTransactions for StoreV1 to use multicast delegate as well - changed delegate assignment to use thread safe shared pointers (required adding Init() and moving code out of constructor where .AsShared is premature) - reduced log verbosity and log spam Change 3194205 on 2016/11/10 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #Android - small java code cleanup Change 3194003 on 2016/11/10 by Michael.Noland@mnoland_T2801_WEX_Main Engine: Made the set of interesting FPS thresholds for FPS charts configurable (as a comma separated list in cvar t.FPSChart.InterestingFramerates) Engine: Exposed helpers on FPerformanceTrackingChart (GetAverageFramerate() and GetPercentMissedVSync()) #rb david.nikdel Change 3194002 on 2016/11/10 by Michael.Noland@mnoland_T2801_WEX_Main Core: Added FHistogram::InitFromArray to create a histogram from an explicit list of thresholds #rb david.nikdel Change 3193771 on 2016/11/10 by Chance.Lyon@Chance.Lyon_WEX_Dev-Main #WEX #JIRA: WEX-3856 - Refactored how loading screens work - Allow Pre / Post load map to handle loading screen setup / teardown by default - Manually show the loading screen when we perform the initial level save - Re-enable the loading screen ensure Change 3193723 on 2016/11/10 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for crash when bringing up the console in chunked build #jira WEX-3922 fix for missing assets at game start in chunked build Change 3193503 on 2016/11/10 by Peter.Sauerbrei@peter.sauerbrei_WEX start pushing streaming data to the appropriate deployment Change 3193210 on 2016/11/10 by Peter.Sauerbrei@peter.sauerbrei_WEX allow CloudStorage to be re-initialized with new credentials if necessary Change 3192750 on 2016/11/09 by Josh.May@josh.may-WEX-JMAY-Main #WEX - Added a mechanism for force-disabling GPU particles. - Disabled GPU particles for all iOS devices. This was eating up a constant 56MB of render target memory, whether or not the feature was used. Change 3192686 on 2016/11/09 by Peter.Sauerbrei@peter.sauerbrei_WEX latest s3 chunk data placement Change 3192468 on 2016/11/09 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #Android - added features to GooglePlay IAP apis - audited code against example code - added some code to JNI to make IAP functions not optional if store is enabled - added ConsumePurchase call to separate consumption until after entitlements have been granted - added QueryExistingPurchases call to enumerate pending/permanent transactions Change 3192246 on 2016/11/09 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for windows build failure first attempt at promotion code Change 3191660 on 2016/11/09 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for PC build of IOS Change 3191598 on 2016/11/09 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for too many open handles Change 3191459 on 2016/11/09 by Peter.Sauerbrei@peter.sauerbrei_WEX more fixes for building chunks on the build machines Change 3190565 on 2016/11/08 by Peter.Sauerbrei@peter.sauerbrei_MacWEX fixes for Remote notifications Change 3190466 on 2016/11/08 by Peter.Sauerbrei@peter.sauerbrei_WEX pointing at the s3 servers Change 3189120 on 2016/11/07 by Peter.Sauerbrei@peter.sauerbrei_WEX optimization for obtaining chunk data startup screen which checks for updated data before loading the entry (not yet enabled) Change 3186019 on 2016/11/03 by David.Nikdel@david.nikdel_WEX #Engine: Empty string is a valid ImportText for an array (indicates an empty array) Change 3185461 on 2016/11/03 by Chris.Babcock@Chris.Babcock_Z2433_WEX Corrections to memory stats for Android #jira WEX-3760 #ue4 #android Change 3184309 on 2016/11/02 by Chance.Lyon@Chance.Lyon_WEX_Main #WEX #JIRA: WEX-3721 - Remove all the "WaitForLoadingScreen" calls. These actually kill the loading screen before the travel, causing the actual travel to be a visible hang instead of a spinner - Commented out and ensure that got hit before it killed the loading screen. Seems like the wrong check to me. Change 3184029 on 2016/11/02 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for some load hitches on mobile Change 3183761 on 2016/11/02 by Peter.Sauerbrei@peter.sauerbrei_WEX allow Android to specify which texture format to get Change 3183760 on 2016/11/02 by Peter.Sauerbrei@peter.sauerbrei_WEX updates for chunking on the various platforms Change 3182107 on 2016/11/01 by Peter.Sauerbrei@peter.sauerbrei_WEX when chunking is disable, initialize the chunk installer in a paused state Change 3182068 on 2016/11/01 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for Scheme name when project is not UE4Game Change 3182007 on 2016/11/01 by Peter.Sauerbrei@peter.sauerbrei_WEX more logging to track down this iOS signing failure Change 3181844 on 2016/11/01 by Peter.Sauerbrei@peter.sauerbrei_WEX attempt to generate the plist before trying to generate the project for stub generation for iOS Change 3181816 on 2016/11/01 by Peter.Sauerbrei@peter.sauerbrei_WEX revert out the extra logging for the iOS build now that I have verified it is working correctly Change 3181806 on 2016/11/01 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for warnings on IOS Change 3181779 on 2016/11/01 by David.Nikdel@david.nikdel_WEX #Engine: Fix for null pointer dereference if you have closed the animation tool window. Change 3181773 on 2016/11/01 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for shipping build failure Change 3181763 on 2016/11/01 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for Android compile failure Change 3181667 on 2016/11/01 by Josh.May@josh.may-WEX-JMAY-Main #WEX #JIRA: WEX-3753 - Ensure the input type of Android keyboard input textbox is set before populating the initial content. Change 3181666 on 2016/11/01 by Peter.Sauerbrei@peter.sauerbrei_WEX initial chunk installer submission, first pass, disabled by default #rb none Change 3181408 on 2016/11/01 by Peter.Sauerbrei@peter.sauerbrei_WEX some logging to track down why the build machine is using the wrong certificate and provision Change 3181070 on 2016/11/01 by Nathan.Green@Nathan.Green_Friday_Main #WEX - Fixing broken android build temporarily Change 3180690 on 2016/10/31 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #WEX - Android support enabled - some better java logging - added ini placeholder for GooglePlay features that need setting (set locally, not ready to check in yet without backend app setup) Change 3180322 on 2016/10/31 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - setup catalog to be GooglePlay aware - fixed up some log output inconsistencies Change 3180307 on 2016/10/31 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - updating libPNG to 1.5.27 for Android only (from Main, early integration) - wolf platform commented out (needs to be reinstated before merge to main) Change 3175413 on 2016/10/26 by Peter.Sauerbrei@peter.sauerbrei_MacWEX fix for buffer being re-used before it was out of use by GPU #rb mark.satterthwaite #jira WEX-3482 Change 3175143 on 2016/10/26 by Steve.Allison@steve.allison_Z4797_6338 Adding: Personal_iPhone6SP_DavidN Personal_iPhone7P_DonaldM Change 3174322 on 2016/10/25 by Steve.Allison@steve.allison_Z4797_6338 Adding: Personal_iPhone6P_ZakP Change 3173760 on 2016/10/25 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for incorrect icons and missing splash screens #rb none #jira wex-3012 Change 3169892 on 2016/10/20 by Steve.Allison@steve.allison_Friday_Main_Stream Adding: UX_iPadMini4_UX8 UX_iPadMini4_UX7 UX_iPadAir2_UX6 UX_iPadAir2_UX5 UX_iPhone6SP_UX4 UX_iPhone6SP_UX3 UX_iPhone6S_UX2 UX_iPhone6S_UX1 Personal_iPhone5S_PaulH Personal_iPhone6_PaulI Personal_iPhone6_EdZ Change 3169848 on 2016/10/20 by Steve.Allison@steve.allison_Friday_Main_Stream Adding: Personal_iPhone6S_NickP Personal_iPhone6SP_SteveA Personal_iPhone6_NickC Personal_iPhone6_GeremyM Personal_iPhone6S_AndyK_HSL Personal_iPhone6_LizS_HSL Personal_iPhone7_JoshM_HSL Personal_iPhone6_CaseyS Personal_iPhone6S_GregL Personal_iPhone6S_BruceK Personal2_iPhone7P_DavidH Personal1_iPhone7P_DavidH Personal_iPhone6SP_SimonH Change 3169651 on 2016/10/20 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for profile captures not working with Metal Change 3169537 on 2016/10/20 by Josh.May@josh.may-WEX-MacPro2-Main #WEX #JIRA: WEX-3059 - Added injection of TouchMoved events whenever a TouchBegin is triggered. This allows legacy iOS devices (i.e. pre-3D Touch) to properly emulate MouseOver/MouseMoved events for rapid taps. Change 3169294 on 2016/10/20 by Josh.May@josh.may-WEX-JMAY-Main #WEX #JIRA: WEX-3497, WEX-3499 - Downgraded a few Engine-level log warnings to verbose. These are cases where the logs are either redundent or triggering in spite of nothing being functionally wrong. Change 3168564 on 2016/10/19 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - typo fix Change 3165381 on 2016/10/17 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - changed log formatting line for GFrameCounter to properly use %llu instead of %d - fixes Android display problems #rb josh.adams Change 3165359 on 2016/10/17 by Steve.Allison@steve.allison_Friday_Main_Stream Adding: Partner_01_iPhone6SP_HardSuit Change 3165127 on 2016/10/17 by Nathan.Green@Nathan.Green_Friday_Main #WEX #JIRA: WEX-3320 - Putting back code erased by the merge, since the viewport is always handling touch commands we'll never get a chance to attempt to drop the object and cancel the operation if we fail, instead we should handle DropEvents first as otherwise our widgets will never recieve an NativeOnDragCancelled event. Change 3164936 on 2016/10/17 by Josh.Markiewicz@JMARKIEWICZ_WEXMAIN #UE4 - missing code related to the OSS plugin refactor to respect the "enabled by default" settings in the .plugin file Change 3164933 on 2016/10/17 by Josh.May@josh.may-WEX-MacPro2-Main #WEX - Fixed naming conventions for the iPadPro device profile configs. Change 3162452 on 2016/10/13 by Peter.Sauerbrei@peter.sauerbrei_WEX missed one engine texture for optimization, do not merge back to engine #rb none Change 3162414 on 2016/10/13 by Peter.Sauerbrei@peter.sauerbrei_WEX reduce the engine texture sizes, do not merge this back to the main engine stream #rb none Change 3162326 on 2016/10/13 by Nathan.Green@Nathan.Green_Friday_Main #WEX - Reverting change, with Peter's ok, to fix scrollboxes behaving strangely on mobile devices Change 3160261 on 2016/10/12 by Steve.Allison@steve.allison_Friday_Main_Stream Adding: 9744_iPhone7P_EpicQA 9745_iPhone7_EpicQA Change 3157269 on 2016/10/10 by Peter.Sauerbrei@peter.sauerbrei_WEX removed a line that shouldn't have been in, fixes MattH save crash #rb none Change 3155086 on 2016/10/07 by David.Nikdel@david.nikdel_WEX #Analytics: Better support for connection loss scenarios - Enforce a minimum delay (2 min) after any failed submission. - Delay only applies to timeout/capcaity flushes, not flushes due to end of session or manually requested flushes. - Remove URL from the DroppedSubmission event per Wes Change 3154873 on 2016/10/07 by Steve.Allison@steve.allison_Friday_Main_Stream Add: 8034_iPhone7_EpicQA Change 3153367 on 2016/10/06 by Steve.Allison@steve.allison_Friday_Main_Stream Adding: 9597_iPhone6SP_Epic Change 3153322 on 2016/10/06 by Peter.Sauerbrei@peter.sauerbrei_WEX disable shadows for android devices as well Change 3152758 on 2016/10/05 by Peter.Sauerbrei@peter.sauerbrei_MacWEX disable shadows for all IOS device profiles enable arm64 for development and shipping #rb none Change 3150660 on 2016/10/04 by David.Nikdel@ROBOMERGE_WEX_Main #ROBOMERGE-AUTHOR: peter.sauerbrei Merging //WEX/Main/Engine/... to //WEX/Release-03/Engine/... Change 3150347 on 2016/10/04 by Steve.Allison@steve.allison_Friday_Main_Stream Adding: 9724_iPadAir2_EpicQA Change 3149190 on 2016/10/03 by Peter.Sauerbrei@peter.sauerbrei_WEX bring over the rest of the code signing fixes for Xcode 8 #rb none Change 3149101 on 2016/10/03 by Peter.Sauerbrei@peter.sauerbrei_WEX re-submit a built IPP with the code signing changes Change 3147338 on 2016/09/30 by David.Nikdel@david.nikdel_WEX Merging CL 3136158 from //UE4/Main/... to //WEX/Main/... UBT: Fix support for the x64-on-x86 compiler shipped with Visual Studio Express, which is causing errors for artists generating project files with UGS. Was not looking for the compiler executable at the correct path. Change 3143944 on 2016/09/28 by Peter.Sauerbrei@peter.sauerbrei_WEX Merging using WEX_Main_to_UE4_WEX_Staging Bringing in Main from WEX-Staging #rb none Change 3138249 on 2016/09/23 by Chad.Garyet@cgaryet_wex_main Integrating codesign fix into WEX/Main Change 3137757 on 2016/09/23 by Peter.Sauerbrei@peter.sauerbrei_WEX fix for code signing on Xcode 8 (re-made from 4.13 stream) #rb none Change 3133037 on 2016/09/20 by Chance.Lyon@Chance.Lyon_WEX_Main #WEX - Fix warning about architecture mismatch Change 3131645 on 2016/09/19 by Josh.May@josh.may-WEX-MacPro2-Main #WEX - Changed hard-coded TextureCube asset defaults from SunsetAmbientCubemap to DefaultTextureCube. This buys us ~16MB memory savings on mobile. Change 3131515 on 2016/09/19 by David.Nikdel@david.nikdel_WEX #Slate: Replace WheelScrollAmount constant with a CVAR Change 3130602 on 2016/09/19 by Nathan.Green@Nathan.Green_Friday_Main #WEX #JIRA: WEX-3154, WEX-2954, WEX-2953 - Fix location of WidgetComponents when we're offsetting the screen of the game (fullscreen mode in the game state) [CL 3479958 by Peter Sauerbrei in Main branch]
3246 lines
134 KiB
C++
3246 lines
134 KiB
C++
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "LevelEditorActions.h"
|
|
#include "SceneView.h"
|
|
#include "Factories/Factory.h"
|
|
#include "Animation/AnimSequence.h"
|
|
#include "Components/LightComponent.h"
|
|
#include "HAL/PlatformFilemanager.h"
|
|
#include "Misc/MessageDialog.h"
|
|
#include "HAL/FileManager.h"
|
|
#include "Misc/App.h"
|
|
#include "Modules/ModuleManager.h"
|
|
#include "Layout/WidgetPath.h"
|
|
#include "Framework/Application/MenuStack.h"
|
|
#include "Framework/Application/SlateApplication.h"
|
|
#include "TexAlignTools.h"
|
|
#include "Components/SkeletalMeshComponent.h"
|
|
#include "Materials/Material.h"
|
|
#include "Editor/EditorPerProjectUserSettings.h"
|
|
#include "ISourceControlModule.h"
|
|
#include "Editor/UnrealEdEngine.h"
|
|
#include "Settings/EditorExperimentalSettings.h"
|
|
#include "Factories/BlueprintFactory.h"
|
|
#include "Editor/GroupActor.h"
|
|
#include "Materials/MaterialInstance.h"
|
|
#include "Engine/Light.h"
|
|
#include "Engine/BlueprintGeneratedClass.h"
|
|
#include "Kismet2/ComponentEditorUtils.h"
|
|
#include "Engine/Selection.h"
|
|
#include "Misc/ConfigCacheIni.h"
|
|
#include "UObject/UObjectIterator.h"
|
|
#include "EngineUtils.h"
|
|
#include "EditorModes.h"
|
|
#include "UnrealEdMisc.h"
|
|
#include "FileHelpers.h"
|
|
#include "EditorModeInterpolation.h"
|
|
#include "UnrealEdGlobals.h"
|
|
#include "Toolkits/AssetEditorManager.h"
|
|
#include "LevelEditor.h"
|
|
#include "Matinee/MatineeActor.h"
|
|
#include "Engine/LevelScriptBlueprint.h"
|
|
#include "LightingBuildOptions.h"
|
|
#include "EditorSupportDelegates.h"
|
|
#include "SLevelEditor.h"
|
|
#include "EditorBuildUtils.h"
|
|
#include "ScopedTransaction.h"
|
|
#include "Kismet2/KismetEditorUtilities.h"
|
|
#include "IContentBrowserSingleton.h"
|
|
#include "ContentBrowserModule.h"
|
|
#include "Interfaces/IMainFrameModule.h"
|
|
#include "DlgDeltaTransform.h"
|
|
#include "Editor/NewLevelDialog/Public/NewLevelDialogModule.h"
|
|
#include "MRUFavoritesList.h"
|
|
#include "Private/SSocketChooser.h"
|
|
#include "SnappingUtils.h"
|
|
#include "LevelEditorViewport.h"
|
|
#include "Layers/ILayers.h"
|
|
#include "IPlacementMode.h"
|
|
#include "IPlacementModeModule.h"
|
|
#include "AssetSelection.h"
|
|
#include "IDocumentation.h"
|
|
#include "SourceCodeNavigation.h"
|
|
#include "EngineAnalytics.h"
|
|
#include "Interfaces/IAnalyticsProvider.h"
|
|
#include "ReferenceViewer.h"
|
|
#include "ISizeMapModule.h"
|
|
#include "EditorClassUtils.h"
|
|
|
|
#include "EditorActorFolders.h"
|
|
#include "ActorPickerMode.h"
|
|
#include "Misc/EngineBuildSettings.h"
|
|
#include "Misc/HotReloadInterface.h"
|
|
#include "SourceControlWindows.h"
|
|
#include "Framework/Notifications/NotificationManager.h"
|
|
#include "Widgets/Notifications/SNotificationList.h"
|
|
#include "CreateBlueprintFromActorDialog.h"
|
|
#include "Settings/EditorProjectSettings.h"
|
|
#include "Engine/LODActor.h"
|
|
#include "IHierarchicalLODUtilities.h"
|
|
#include "HierarchicalLODUtilitiesModule.h"
|
|
#include "Application/IPortalApplicationWindow.h"
|
|
#include "IPortalServiceLocator.h"
|
|
#include "MaterialShaderQualitySettings.h"
|
|
#include "IVREditorModule.h"
|
|
#include "ComponentRecreateRenderStateContext.h"
|
|
#include "Engine/LevelStreaming.h"
|
|
#include "Engine/LevelStreamingKismet.h"
|
|
#include "EditorLevelUtils.h"
|
|
#include "ActorGroupingUtils.h"
|
|
#include "LevelUtils.h"
|
|
|
|
DEFINE_LOG_CATEGORY_STATIC(LevelEditorActions, Log, All);
|
|
|
|
#define LOCTEXT_NAMESPACE "LevelEditorActions"
|
|
|
|
const FName HotReloadModule("HotReload");
|
|
|
|
namespace LevelEditorActionsHelpers
|
|
{
|
|
/**
|
|
* If the passed in class is generated by a Blueprint, it will open that Blueprint, otherwise it will help the user create a Blueprint based on that class
|
|
*
|
|
* @param InWindowTitle The window title if the Blueprint needs to be created
|
|
* @param InBlueprintClass The class to create a Blueprint based on or to open if it is a Blueprint
|
|
* @param InLevelEditor When opening the Blueprint, this level editor is the parent window
|
|
* @param InNewBPName If we have to create a new BP, this is the suggested name
|
|
*/
|
|
UBlueprint* OpenOrCreateBlueprintFromClass(FText InWindowTitle, UClass* InBlueprintClass, TWeakPtr< SLevelEditor > InLevelEditor, FString InNewBPName = TEXT(""))
|
|
{
|
|
UBlueprint* Blueprint = NULL;
|
|
|
|
// If the current set class is not a Blueprint, we need to allow the user to create one to edit
|
|
if(!InBlueprintClass->ClassGeneratedBy)
|
|
{
|
|
Blueprint = FKismetEditorUtilities::CreateBlueprintFromClass(InWindowTitle, InBlueprintClass, InNewBPName);
|
|
}
|
|
else
|
|
{
|
|
Blueprint = Cast<UBlueprint>(InBlueprintClass->ClassGeneratedBy);
|
|
}
|
|
|
|
if(Blueprint)
|
|
{
|
|
// @todo Re-enable once world centric works
|
|
const bool bOpenWorldCentric = false;
|
|
FAssetEditorManager::Get().OpenEditorForAsset(
|
|
Blueprint,
|
|
bOpenWorldCentric ? EToolkitMode::WorldCentric : EToolkitMode::Standalone,
|
|
InLevelEditor.Pin() );
|
|
}
|
|
|
|
return Blueprint;
|
|
}
|
|
|
|
/** Check to see whether this world is a persistent world with a valid file on disk */
|
|
bool IsPersistentWorld(UWorld* InWorld)
|
|
{
|
|
UPackage* Pkg = InWorld ? InWorld->GetOutermost() : nullptr;
|
|
if (Pkg && FPackageName::IsValidLongPackageName(Pkg->GetName()))
|
|
{
|
|
FString FileName;
|
|
return FPackageName::DoesPackageExist(Pkg->GetName(), nullptr, &FileName);
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::DefaultCanExecuteAction()
|
|
{
|
|
return FSlateApplication::Get().IsNormalExecution();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::BrowseDocumentation()
|
|
{
|
|
IDocumentation::Get()->OpenHome(FDocumentationSourceInfo(TEXT("help_menu")));
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::BrowseAPIReference()
|
|
{
|
|
IDocumentation::Get()->OpenAPIHome();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::BrowseCVars()
|
|
{
|
|
GEditor->Exec(GetWorld(), TEXT("help"));
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::BrowseViewportControls()
|
|
{
|
|
FString URL;
|
|
if (FUnrealEdMisc::Get().GetURL(TEXT("ViewportControlsURL"), URL))
|
|
{
|
|
FPlatformProcess::LaunchURL(*URL, NULL, NULL);
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::NewLevel()
|
|
{
|
|
if (GUnrealEd->WarnIfLightingBuildIsCurrentlyRunning())
|
|
{
|
|
return;
|
|
}
|
|
|
|
IMainFrameModule& MainFrameModule = FModuleManager::GetModuleChecked<IMainFrameModule>("MainFrame");
|
|
|
|
FString TemplateMapPackageName;
|
|
FNewLevelDialogModule& NewLevelDialogModule = FModuleManager::LoadModuleChecked<FNewLevelDialogModule>("NewLevelDialog");
|
|
if (NewLevelDialogModule.CreateAndShowNewLevelDialog(MainFrameModule.GetParentWindow(), TemplateMapPackageName))
|
|
{
|
|
// The new map screen will return a blank TemplateName if the user has selected to begin a new blank map
|
|
if (TemplateMapPackageName.IsEmpty())
|
|
{
|
|
GEditor->CreateNewMapForEditing();
|
|
}
|
|
else
|
|
{
|
|
// New map screen returned a non-empty TemplateName, so the user has selected to begin from a template map
|
|
bool TemplateFound = false;
|
|
|
|
// Search all template map folders for a match with TemplateName
|
|
const bool bIncludeReadOnlyRoots = true;
|
|
if ( FPackageName::IsValidLongPackageName(TemplateMapPackageName, bIncludeReadOnlyRoots) )
|
|
{
|
|
const FString MapPackageFilename = FPackageName::LongPackageNameToFilename(TemplateMapPackageName, FPackageName::GetMapPackageExtension());
|
|
if ( FPaths::FileExists(MapPackageFilename) )
|
|
{
|
|
// File found because the size check came back non-zero
|
|
TemplateFound = true;
|
|
|
|
// If there are any unsaved changes to the current level, see if the user wants to save those first.
|
|
bool bPromptUserToSave = true;
|
|
bool bSaveMapPackages = true;
|
|
bool bSaveContentPackages = false;
|
|
if ( FEditorFileUtils::SaveDirtyPackages(bPromptUserToSave, bSaveMapPackages, bSaveContentPackages) )
|
|
{
|
|
// Load the template map file - passes LoadAsTemplate==true making the
|
|
// level load into an untitled package that won't save over the template
|
|
FEditorFileUtils::LoadMap(*MapPackageFilename, /*bLoadAsTemplate=*/true);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!TemplateFound)
|
|
{
|
|
UE_LOG( LevelEditorActions, Warning, TEXT("Couldn't find template map package %s"), *TemplateMapPackageName);
|
|
GEditor->CreateNewMapForEditing();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::NewLevel_CanExecute()
|
|
{
|
|
return FSlateApplication::Get().IsNormalExecution() && !GLevelEditorModeTools().IsTracking();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OpenLevel()
|
|
{
|
|
FEditorFileUtils::LoadMap();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::OpenLevel_CanExecute()
|
|
{
|
|
return FSlateApplication::Get().IsNormalExecution() && !GLevelEditorModeTools().IsTracking();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::DeltaTransform()
|
|
{
|
|
if (GUnrealEd->WarnIfLightingBuildIsCurrentlyRunning())
|
|
{
|
|
return;
|
|
}
|
|
|
|
FDlgDeltaTransform DeltaDialog;
|
|
|
|
const FDlgDeltaTransform::EResult MoveDialogResult = DeltaDialog.ShowModal();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OpenRecentFile( int32 RecentFileIndex )
|
|
{
|
|
IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>( "MainFrame" );
|
|
FMainMRUFavoritesList* RecentsAndFavorites = MainFrameModule.GetMRUFavoritesList();
|
|
|
|
// Save the name of the file we are attempting to load as VerifyFile/AskSaveChanges might rearrange the MRU list on us
|
|
const FString NewPackageName = RecentsAndFavorites->GetMRUItem( RecentFileIndex );
|
|
|
|
if( RecentsAndFavorites->VerifyMRUFile( RecentFileIndex ) )
|
|
{
|
|
// Prompt the user to save any outstanding changes.
|
|
if( FEditorFileUtils::SaveDirtyPackages(true, true, false) )
|
|
{
|
|
FString NewFilename;
|
|
if (FPackageName::TryConvertLongPackageNameToFilename(NewPackageName, NewFilename, FPackageName::GetMapPackageExtension()))
|
|
{
|
|
// Load the requested level.
|
|
FEditorFileUtils::LoadMap(NewFilename);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// something went wrong or the user pressed cancel. Return to the editor so the user doesn't lose their changes
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::OpenFavoriteFile( int32 FavoriteFileIndex )
|
|
{
|
|
IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>( "MainFrame" );
|
|
FMainMRUFavoritesList* MRUFavoritesList = MainFrameModule.GetMRUFavoritesList();
|
|
|
|
const FString PackageName = MRUFavoritesList->GetFavoritesItem( FavoriteFileIndex );
|
|
|
|
if( MRUFavoritesList->VerifyFavoritesFile( FavoriteFileIndex ) )
|
|
{
|
|
// Prompt the user to save any outstanding changes
|
|
if( FEditorFileUtils::SaveDirtyPackages(true, true, false) )
|
|
{
|
|
FString FileName;
|
|
if (FPackageName::TryConvertLongPackageNameToFilename(PackageName, FileName, FPackageName::GetMapPackageExtension()))
|
|
{
|
|
// Load the requested level.
|
|
FEditorFileUtils::LoadMap(FileName);
|
|
}
|
|
|
|
// Move the item to the head of the list
|
|
MRUFavoritesList->MoveFavoritesItemToHead(PackageName);
|
|
}
|
|
else
|
|
{
|
|
// something went wrong or the user pressed cancel. Return to the editor so the user doesn't lose their changes
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::ToggleFavorite()
|
|
{
|
|
IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>( "MainFrame" );
|
|
FMainMRUFavoritesList* MRUFavoritesList = MainFrameModule.GetMRUFavoritesList();
|
|
check( MRUFavoritesList );
|
|
|
|
if (LevelEditorActionsHelpers::IsPersistentWorld(GetWorld()))
|
|
{
|
|
const FString PackageName = GetWorld()->GetOutermost()->GetName();
|
|
|
|
// If the map was already favorited, remove it from the favorites
|
|
if ( MRUFavoritesList->ContainsFavoritesItem(PackageName) )
|
|
{
|
|
MRUFavoritesList->RemoveFavoritesItem(PackageName);
|
|
}
|
|
// If the map was not already favorited, add it to the favorites
|
|
else
|
|
{
|
|
MRUFavoritesList->AddFavoritesItem(PackageName);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::RemoveFavorite( int32 FavoriteFileIndex )
|
|
{
|
|
IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>( "MainFrame" );
|
|
FMainMRUFavoritesList* MRUFavoritesList = MainFrameModule.GetMRUFavoritesList();
|
|
|
|
const FString PackageName = MRUFavoritesList->GetFavoritesItem( FavoriteFileIndex );
|
|
|
|
if( MRUFavoritesList->VerifyFavoritesFile( FavoriteFileIndex ) )
|
|
{
|
|
if ( MRUFavoritesList->ContainsFavoritesItem(PackageName) )
|
|
{
|
|
MRUFavoritesList->RemoveFavoritesItem(PackageName);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
bool FLevelEditorActionCallbacks::ToggleFavorite_CanExecute()
|
|
{
|
|
// Disable the favorites button if the map isn't associated to a file yet (new map, never before saved, etc.)
|
|
return LevelEditorActionsHelpers::IsPersistentWorld(GetWorld());
|
|
}
|
|
|
|
|
|
bool FLevelEditorActionCallbacks::ToggleFavorite_IsChecked()
|
|
{
|
|
bool bIsChecked = false;
|
|
|
|
if (LevelEditorActionsHelpers::IsPersistentWorld(GetWorld()))
|
|
{
|
|
const FString PackageName = GetWorld()->GetOutermost()->GetName();
|
|
|
|
IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>( "MainFrame" );
|
|
bIsChecked = MainFrameModule.GetMRUFavoritesList()->ContainsFavoritesItem(PackageName);
|
|
}
|
|
|
|
return bIsChecked;
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::CanSaveWorld()
|
|
{
|
|
return FSlateApplication::Get().IsNormalExecution() && (!GUnrealEd || !GUnrealEd->GetPackageAutoSaver().IsAutoSaving());
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::Save()
|
|
{
|
|
FEditorFileUtils::SaveCurrentLevel();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SaveCurrentAs()
|
|
{
|
|
UWorld* World = GetWorld();
|
|
ULevel* CurrentLevel = World->GetCurrentLevel();
|
|
|
|
UClass* CurrentStreamingLevelClass = ULevelStreamingKismet::StaticClass();
|
|
|
|
for (ULevelStreaming* StreamingLevel : World->StreamingLevels)
|
|
{
|
|
if (StreamingLevel->GetLoadedLevel() == CurrentLevel)
|
|
{
|
|
CurrentStreamingLevelClass = StreamingLevel->GetClass();
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
const bool bSavedPersistentLevelAs = CurrentLevel == World->PersistentLevel;
|
|
FString SavedFilename;
|
|
bool bSaved = FEditorFileUtils::SaveLevelAs(CurrentLevel, &SavedFilename);
|
|
if(bSaved)
|
|
{
|
|
if (bSavedPersistentLevelAs)
|
|
{
|
|
FEditorFileUtils::LoadMap(SavedFilename);
|
|
}
|
|
else
|
|
{
|
|
// Remove the level we just saved over
|
|
EditorLevelUtils::RemoveLevelFromWorld(CurrentLevel);
|
|
|
|
// Add the new level we just saved as to the plevel
|
|
FString PackageName;
|
|
if (FPackageName::TryConvertFilenameToLongPackageName(SavedFilename, PackageName))
|
|
{
|
|
ULevelStreaming* StreamingLevel = UEditorLevelUtils::AddLevelToWorld(World, *PackageName, CurrentStreamingLevelClass);
|
|
|
|
// Make the level we just added current because the expectation is that the new level replaces the existing current level
|
|
EditorLevelUtils::MakeLevelCurrent(StreamingLevel->GetLoadedLevel());
|
|
}
|
|
|
|
FEditorDelegates::RefreshLevelBrowser.Broadcast();
|
|
}
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SaveAllLevels()
|
|
{
|
|
const bool bPromptUserToSave = false;
|
|
const bool bSaveMapPackages = true;
|
|
const bool bSaveContentPackages = false;
|
|
const bool bFastSave = false;
|
|
FEditorFileUtils::SaveDirtyPackages( bPromptUserToSave, bSaveMapPackages, bSaveContentPackages, bFastSave );
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::ImportScene_Clicked()
|
|
{
|
|
FEditorFileUtils::Import();
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::ExportAll_Clicked()
|
|
{
|
|
const bool bExportSelectedActorsOnly = false;
|
|
FEditorFileUtils::Export( bExportSelectedActorsOnly );
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::ExportSelected_Clicked()
|
|
{
|
|
const bool bExportSelectedActorsOnly = true;
|
|
FEditorFileUtils::Export( bExportSelectedActorsOnly );
|
|
}
|
|
|
|
|
|
bool FLevelEditorActionCallbacks::ExportSelected_CanExecute()
|
|
{
|
|
// Only enable the option if at least one thing is selected and its not a worldsettings
|
|
return GEditor->GetSelectedActors()->Num() > 0 && !GEditor->IsWorldSettingsSelected();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::AttachToActor(AActor* ParentActorPtr)
|
|
{
|
|
USceneComponent* ComponentWithSockets = NULL;
|
|
|
|
//@TODO: Should create a menu for each component that contains sockets, or have some form of disambiguation within the menu (like a fully qualified path)
|
|
// Instead, we currently only display the sockets on the root component
|
|
if (ParentActorPtr != NULL)
|
|
{
|
|
if (USceneComponent* RootComponent = Cast<USceneComponent>(ParentActorPtr->GetRootComponent()))
|
|
{
|
|
if (RootComponent->HasAnySockets())
|
|
{
|
|
ComponentWithSockets = RootComponent;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Show socket chooser if we have sockets to select
|
|
if (ComponentWithSockets != NULL)
|
|
{
|
|
FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked<FLevelEditorModule>( "LevelEditor");
|
|
TSharedPtr< ILevelEditor > LevelEditor = LevelEditorModule.GetFirstLevelEditor();
|
|
|
|
// Create as context menu
|
|
FSlateApplication::Get().PushMenu(
|
|
LevelEditor.ToSharedRef(),
|
|
FWidgetPath(),
|
|
SNew(SSocketChooserPopup)
|
|
.SceneComponent( ComponentWithSockets )
|
|
.OnSocketChosen_Static( &FLevelEditorActionCallbacks::AttachToSocketSelection, ParentActorPtr ),
|
|
FSlateApplication::Get().GetCursorPos(),
|
|
FPopupTransitionEffect( FPopupTransitionEffect::ContextMenu )
|
|
);
|
|
}
|
|
else
|
|
{
|
|
AttachToSocketSelection( NAME_None, ParentActorPtr );
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::AttachToSocketSelection(const FName SocketName, AActor* ParentActorPtr)
|
|
{
|
|
FSlateApplication::Get().DismissAllMenus();
|
|
|
|
if(ParentActorPtr != NULL)
|
|
{
|
|
// Attach each child
|
|
FScopedTransaction Transaction(LOCTEXT("AttachActors", "Attach actors"));
|
|
bool bAttached = false;
|
|
|
|
for ( FSelectionIterator It( GEditor->GetSelectedActorIterator() ) ; It ; ++It )
|
|
{
|
|
AActor* Actor = Cast<AActor>( *It );
|
|
if (GEditor->CanParentActors(ParentActorPtr, Actor))
|
|
{
|
|
bAttached = true;
|
|
GEditor->ParentActors(ParentActorPtr, Actor, SocketName);
|
|
}
|
|
}
|
|
|
|
if (!bAttached)
|
|
{
|
|
Transaction.Cancel();
|
|
}
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetMaterialQualityLevel( EMaterialQualityLevel::Type NewQualityLevel )
|
|
{
|
|
auto* Settings = GetMutableDefault<UEditorPerProjectUserSettings>();
|
|
Settings->MaterialQualityLevel = NewQualityLevel;
|
|
Settings->PostEditChange();
|
|
|
|
//Ensure the material quality cvar is also set.
|
|
static IConsoleVariable* MaterialQualityLevelVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.MaterialQualityLevel"));
|
|
MaterialQualityLevelVar->Set(NewQualityLevel, ECVF_SetByScalability);
|
|
|
|
GUnrealEd->RedrawAllViewports();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::IsMaterialQualityLevelChecked( EMaterialQualityLevel::Type TestQualityLevel )
|
|
{
|
|
static const auto MaterialQualityLevelVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MaterialQualityLevel"));
|
|
EMaterialQualityLevel::Type MaterialQualityLevel = (EMaterialQualityLevel::Type)FMath::Clamp(MaterialQualityLevelVar->GetValueOnGameThread(), 0, (int32)EMaterialQualityLevel::Num-1);
|
|
return TestQualityLevel == MaterialQualityLevel;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetPreviewPlatform(FName MaterialQualityPlatform, ERHIFeatureLevel::Type PreviewFeatureLevel)
|
|
{
|
|
// If we have specified a MaterialQualityPlatform ensure its feature level matches the requested feature level.
|
|
check(MaterialQualityPlatform.IsNone() || GetMaxSupportedFeatureLevel(ShaderFormatToLegacyShaderPlatform(MaterialQualityPlatform)) == PreviewFeatureLevel);
|
|
|
|
UMaterialShaderQualitySettings* MaterialShaderQualitySettings = UMaterialShaderQualitySettings::Get();
|
|
const FName InitialPreviewPlatform = MaterialShaderQualitySettings->GetPreviewPlatform();
|
|
|
|
const ERHIFeatureLevel::Type InitialFeatureLevel = GetWorld()->FeatureLevel;
|
|
MaterialShaderQualitySettings->SetPreviewPlatform(MaterialQualityPlatform);
|
|
SetFeatureLevelPreview(PreviewFeatureLevel);
|
|
|
|
if (
|
|
// Rebuild materials if the preview platform has changed.
|
|
InitialPreviewPlatform != MaterialQualityPlatform
|
|
// If the feature level changed then materials have been rebuilt already.
|
|
&& InitialFeatureLevel == PreviewFeatureLevel)
|
|
{
|
|
FGlobalComponentRecreateRenderStateContext Recreate;
|
|
FlushRenderingCommands();
|
|
UMaterial::AllMaterialsCacheResourceShadersForRendering();
|
|
UMaterialInstance::AllMaterialsCacheResourceShadersForRendering();
|
|
}
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::IsPreviewPlatformChecked(FName MaterialQualityPlatform, ERHIFeatureLevel::Type PreviewFeatureLevel)
|
|
{
|
|
const FName& PreviewPlatform = UMaterialShaderQualitySettings::Get()->GetPreviewPlatform();
|
|
return PreviewPlatform == MaterialQualityPlatform && PreviewFeatureLevel == GetWorld()->FeatureLevel;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetFeatureLevelPreview(ERHIFeatureLevel::Type InPreviewFeatureLevel)
|
|
{
|
|
// Record this feature level as we want to use it for all subsequent level creation and loading
|
|
GEditor->DefaultWorldFeatureLevel = InPreviewFeatureLevel;
|
|
|
|
GetWorld()->ChangeFeatureLevel(InPreviewFeatureLevel);
|
|
|
|
// Update any currently running PIE sessions.
|
|
for (TObjectIterator<UWorld> It; It; ++It)
|
|
{
|
|
UWorld* ItWorld = *It;
|
|
if (ItWorld->WorldType == EWorldType::PIE)
|
|
{
|
|
ItWorld->ChangeFeatureLevel(InPreviewFeatureLevel);
|
|
}
|
|
}
|
|
|
|
GUnrealEd->RedrawAllViewports();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::IsFeatureLevelPreviewChecked(ERHIFeatureLevel::Type InPreviewFeatureLevel)
|
|
{
|
|
return InPreviewFeatureLevel == GetWorld()->FeatureLevel;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::ConfigureLightingBuildOptions( const FLightingBuildOptions& Options )
|
|
{
|
|
GConfig->SetBool( TEXT("LightingBuildOptions"), TEXT("OnlyBuildSelected"), Options.bOnlyBuildSelected, GEditorPerProjectIni );
|
|
GConfig->SetBool( TEXT("LightingBuildOptions"), TEXT("OnlyBuildCurrentLevel"), Options.bOnlyBuildCurrentLevel, GEditorPerProjectIni );
|
|
GConfig->SetBool( TEXT("LightingBuildOptions"), TEXT("OnlyBuildSelectedLevels"),Options.bOnlyBuildSelectedLevels, GEditorPerProjectIni );
|
|
GConfig->SetBool( TEXT("LightingBuildOptions"), TEXT("OnlyBuildVisibility"), Options.bOnlyBuildVisibility, GEditorPerProjectIni );
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::Build_Execute()
|
|
{
|
|
// Reset build options
|
|
ConfigureLightingBuildOptions( FLightingBuildOptions() );
|
|
|
|
// Build everything!
|
|
FEditorBuildUtils::EditorBuild( GetWorld(), FBuildOptions::BuildAll );
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::Build_CanExecute()
|
|
{
|
|
return !(GEditor->PlayWorld || GUnrealEd->bIsSimulatingInEditor);
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::BuildAndSubmitToSourceControl_Execute()
|
|
{
|
|
FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked<FLevelEditorModule>( TEXT("LevelEditor") );
|
|
LevelEditorModule.SummonBuildAndSubmit();
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::BuildLightingOnly_Execute()
|
|
{
|
|
// Reset build options
|
|
ConfigureLightingBuildOptions( FLightingBuildOptions() );
|
|
|
|
// Build lighting!
|
|
const bool bAllowLightingDialog = false;
|
|
FEditorBuildUtils::EditorBuild( GetWorld(), FBuildOptions::BuildLighting, bAllowLightingDialog );
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::BuildLighting_CanExecute()
|
|
{
|
|
static const auto AllowStaticLightingVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.AllowStaticLighting"));
|
|
const bool bAllowStaticLighting = (!AllowStaticLightingVar || AllowStaticLightingVar->GetValueOnGameThread() != 0);
|
|
return bAllowStaticLighting && !(GEditor->PlayWorld || GUnrealEd->bIsSimulatingInEditor);
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::BuildReflectionCapturesOnly_Execute()
|
|
{
|
|
GEditor->UpdateReflectionCaptures();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::BuildLightingOnly_VisibilityOnly_Execute()
|
|
{
|
|
// Configure build options
|
|
FLightingBuildOptions LightingBuildOptions;
|
|
LightingBuildOptions.bOnlyBuildVisibility = true;
|
|
ConfigureLightingBuildOptions( LightingBuildOptions );
|
|
|
|
// Build lighting!
|
|
const bool bAllowLightingDialog = false;
|
|
FEditorBuildUtils::EditorBuild( GetWorld(), FBuildOptions::BuildLighting, bAllowLightingDialog );
|
|
|
|
// Reset build options
|
|
ConfigureLightingBuildOptions( FLightingBuildOptions() );
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::LightingBuildOptions_UseErrorColoring_IsChecked()
|
|
{
|
|
bool bUseErrorColoring = false;
|
|
GConfig->GetBool(TEXT("LightingBuildOptions"), TEXT("UseErrorColoring"), bUseErrorColoring, GEditorPerProjectIni);
|
|
return bUseErrorColoring;
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::LightingBuildOptions_UseErrorColoring_Toggled()
|
|
{
|
|
bool bUseErrorColoring = false;
|
|
GConfig->GetBool( TEXT("LightingBuildOptions"), TEXT("UseErrorColoring"), bUseErrorColoring, GEditorPerProjectIni );
|
|
GConfig->SetBool( TEXT("LightingBuildOptions"), TEXT("UseErrorColoring"), !bUseErrorColoring, GEditorPerProjectIni );
|
|
}
|
|
|
|
|
|
bool FLevelEditorActionCallbacks::LightingBuildOptions_ShowLightingStats_IsChecked()
|
|
{
|
|
bool bShowLightingBuildInfo = false;
|
|
GConfig->GetBool(TEXT("LightingBuildOptions"), TEXT("ShowLightingBuildInfo"), bShowLightingBuildInfo, GEditorPerProjectIni);
|
|
return bShowLightingBuildInfo;
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::LightingBuildOptions_ShowLightingStats_Toggled()
|
|
{
|
|
bool bShowLightingBuildInfo = false;
|
|
GConfig->GetBool( TEXT("LightingBuildOptions"), TEXT("ShowLightingBuildInfo"), bShowLightingBuildInfo, GEditorPerProjectIni );
|
|
GConfig->SetBool( TEXT("LightingBuildOptions"), TEXT("ShowLightingBuildInfo"), !bShowLightingBuildInfo, GEditorPerProjectIni );
|
|
}
|
|
|
|
|
|
|
|
void FLevelEditorActionCallbacks::BuildGeometryOnly_Execute()
|
|
{
|
|
// Build geometry!
|
|
FEditorBuildUtils::EditorBuild( GetWorld(), FBuildOptions::BuildVisibleGeometry );
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::BuildGeometryOnly_OnlyCurrentLevel_Execute()
|
|
{
|
|
// Build geometry (current level)!
|
|
FEditorBuildUtils::EditorBuild( GetWorld(), FBuildOptions::BuildGeometry );
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::BuildPathsOnly_Execute()
|
|
{
|
|
// Build paths!
|
|
FEditorBuildUtils::EditorBuild( GetWorld(), FBuildOptions::BuildAIPaths );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::BuildLODsOnly_Execute()
|
|
{
|
|
// Build HLOD
|
|
FEditorBuildUtils::EditorBuild(GetWorld(), FBuildOptions::BuildHierarchicalLOD);
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::BuildTextureStreamingOnly_Execute()
|
|
{
|
|
FEditorBuildUtils::EditorBuildTextureStreaming(GetWorld());
|
|
GEngine->DeferredCommands.AddUnique(TEXT("MAP CHECK NOTIFYRESULTS"));
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::IsLightingQualityChecked( ELightingBuildQuality TestQuality )
|
|
{
|
|
int32 CurrentQualityLevel;
|
|
GConfig->GetInt(TEXT("LightingBuildOptions"), TEXT("QualityLevel"), CurrentQualityLevel, GEditorPerProjectIni);
|
|
return TestQuality == CurrentQualityLevel;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetLightingQuality( ELightingBuildQuality NewQuality )
|
|
{
|
|
GConfig->SetInt(TEXT("LightingBuildOptions"), TEXT("QualityLevel"), (int32)NewQuality, GEditorPerProjectIni);
|
|
}
|
|
|
|
float FLevelEditorActionCallbacks::GetLightingDensityIdeal()
|
|
{
|
|
return ( GEngine->IdealLightMapDensity );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetLightingDensityIdeal( float Value )
|
|
{
|
|
GEngine->IdealLightMapDensity = Value;
|
|
|
|
// We need to make sure that Maximum is always slightly larger than ideal...
|
|
if (GEngine->IdealLightMapDensity >= GEngine->MaxLightMapDensity - 0.01f)
|
|
{
|
|
SetLightingDensityMaximum( GEngine->IdealLightMapDensity + 0.01f );
|
|
}
|
|
|
|
FEditorSupportDelegates::RedrawAllViewports.Broadcast();
|
|
}
|
|
|
|
float FLevelEditorActionCallbacks::GetLightingDensityMaximum()
|
|
{
|
|
return ( GEngine->MaxLightMapDensity );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetLightingDensityMaximum( float Value )
|
|
{
|
|
GEngine->MaxLightMapDensity = Value;
|
|
|
|
// We need to make sure that Maximum is always slightly larger than ideal...
|
|
if (GEngine->MaxLightMapDensity <= GEngine->IdealLightMapDensity + 0.01f)
|
|
{
|
|
GEngine->MaxLightMapDensity = GEngine->IdealLightMapDensity + 0.01f;
|
|
}
|
|
|
|
FEditorSupportDelegates::RedrawAllViewports.Broadcast();
|
|
}
|
|
|
|
float FLevelEditorActionCallbacks::GetLightingDensityColorScale()
|
|
{
|
|
return ( GEngine->RenderLightMapDensityColorScale );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetLightingDensityColorScale( float Value )
|
|
{
|
|
GEngine->RenderLightMapDensityColorScale = Value;
|
|
|
|
FEditorSupportDelegates::RedrawAllViewports.Broadcast();
|
|
}
|
|
|
|
float FLevelEditorActionCallbacks::GetLightingDensityGrayscaleScale()
|
|
{
|
|
return ( GEngine->RenderLightMapDensityGrayscaleScale );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetLightingDensityGrayscaleScale( float Value )
|
|
{
|
|
GEngine->RenderLightMapDensityGrayscaleScale = Value;
|
|
|
|
FEditorSupportDelegates::RedrawAllViewports.Broadcast();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetLightingDensityRenderGrayscale()
|
|
{
|
|
GEngine->bRenderLightMapDensityGrayscale = !GEngine->bRenderLightMapDensityGrayscale;
|
|
GEngine->SaveConfig();
|
|
FEditorSupportDelegates::RedrawAllViewports.Broadcast();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::IsLightingDensityRenderGrayscaleChecked()
|
|
{
|
|
return GEngine->bRenderLightMapDensityGrayscale;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetLightingResolutionStaticMeshes( ECheckBoxState NewCheckedState )
|
|
{
|
|
FLightmapResRatioAdjustSettings& Settings = FLightmapResRatioAdjustSettings::Get();
|
|
Settings.bStaticMeshes = ( NewCheckedState == ECheckBoxState::Checked );
|
|
}
|
|
|
|
ECheckBoxState FLevelEditorActionCallbacks::IsLightingResolutionStaticMeshesChecked()
|
|
{
|
|
return ( FLightmapResRatioAdjustSettings::Get().bStaticMeshes ? ECheckBoxState::Checked : ECheckBoxState::Unchecked );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetLightingResolutionBSPSurfaces( ECheckBoxState NewCheckedState )
|
|
{
|
|
FLightmapResRatioAdjustSettings& Settings = FLightmapResRatioAdjustSettings::Get();
|
|
Settings.bBSPSurfaces = ( NewCheckedState == ECheckBoxState::Checked );
|
|
}
|
|
|
|
ECheckBoxState FLevelEditorActionCallbacks::IsLightingResolutionBSPSurfacesChecked()
|
|
{
|
|
return ( FLightmapResRatioAdjustSettings::Get().bBSPSurfaces ? ECheckBoxState::Checked : ECheckBoxState::Unchecked );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetLightingResolutionLevel( FLightmapResRatioAdjustSettings::AdjustLevels NewLevel )
|
|
{
|
|
FLightmapResRatioAdjustSettings& Settings = FLightmapResRatioAdjustSettings::Get();
|
|
Settings.LevelOptions = NewLevel;
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::IsLightingResolutionLevelChecked( FLightmapResRatioAdjustSettings::AdjustLevels TestLevel )
|
|
{
|
|
return ( FLightmapResRatioAdjustSettings::Get().LevelOptions == TestLevel );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetLightingResolutionSelectedObjectsOnly()
|
|
{
|
|
FLightmapResRatioAdjustSettings& Settings = FLightmapResRatioAdjustSettings::Get();
|
|
Settings.bSelectedObjectsOnly = !Settings.bSelectedObjectsOnly;
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::IsLightingResolutionSelectedObjectsOnlyChecked()
|
|
{
|
|
return FLightmapResRatioAdjustSettings::Get().bSelectedObjectsOnly;
|
|
}
|
|
|
|
float FLevelEditorActionCallbacks::GetLightingResolutionMinSMs()
|
|
{
|
|
return static_cast<float>( FLightmapResRatioAdjustSettings::Get().Min_StaticMeshes );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetLightingResolutionMinSMs( float Value )
|
|
{
|
|
FLightmapResRatioAdjustSettings& Settings = FLightmapResRatioAdjustSettings::Get();
|
|
Settings.Min_StaticMeshes = static_cast<int32>( Value );
|
|
}
|
|
|
|
float FLevelEditorActionCallbacks::GetLightingResolutionMaxSMs()
|
|
{
|
|
return static_cast<float>( FLightmapResRatioAdjustSettings::Get().Max_StaticMeshes );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetLightingResolutionMaxSMs( float Value )
|
|
{
|
|
FLightmapResRatioAdjustSettings& Settings = FLightmapResRatioAdjustSettings::Get();
|
|
Settings.Max_StaticMeshes = static_cast<int32>( Value );
|
|
}
|
|
|
|
float FLevelEditorActionCallbacks::GetLightingResolutionMinBSPs()
|
|
{
|
|
return static_cast<float>( FLightmapResRatioAdjustSettings::Get().Min_BSPSurfaces );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetLightingResolutionMinBSPs( float Value )
|
|
{
|
|
FLightmapResRatioAdjustSettings& Settings = FLightmapResRatioAdjustSettings::Get();
|
|
Settings.Min_BSPSurfaces = static_cast<int32>( Value );
|
|
}
|
|
|
|
float FLevelEditorActionCallbacks::GetLightingResolutionMaxBSPs()
|
|
{
|
|
return static_cast<float>( FLightmapResRatioAdjustSettings::Get().Max_BSPSurfaces );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetLightingResolutionMaxBSPs( float Value )
|
|
{
|
|
FLightmapResRatioAdjustSettings& Settings = FLightmapResRatioAdjustSettings::Get();
|
|
Settings.Max_BSPSurfaces = static_cast<int32>( Value );
|
|
}
|
|
|
|
int32 FLevelEditorActionCallbacks::GetLightingResolutionRatio()
|
|
{
|
|
return FMath::RoundToInt(FLightmapResRatioAdjustSettings::Get().Ratio * 100.0f);
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetLightingResolutionRatio( int32 Value )
|
|
{
|
|
FLightmapResRatioAdjustSettings& Settings = FLightmapResRatioAdjustSettings::Get();
|
|
const float NewValue = Value / 100.0f;
|
|
if ( Settings.Ratio != NewValue )
|
|
{
|
|
Settings.Ratio = NewValue;
|
|
Settings.ApplyRatioAdjustment();
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetLightingResolutionRatioCommit( int32 Value, ETextCommit::Type CommitInfo)
|
|
{
|
|
if ((CommitInfo == ETextCommit::OnEnter) || (CommitInfo == ETextCommit::OnUserMovedFocus))
|
|
{
|
|
SetLightingResolutionRatio( Value );
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::ShowLightingStaticMeshInfo()
|
|
{
|
|
if (GUnrealEd)
|
|
{
|
|
GUnrealEd->ShowLightingStaticMeshInfoWindow();
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::ShowSceneStats()
|
|
{
|
|
if (GUnrealEd)
|
|
{
|
|
GUnrealEd->OpenSceneStatsWindow();
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::ShowTextureStats()
|
|
{
|
|
if (GUnrealEd)
|
|
{
|
|
GUnrealEd->OpenTextureStatsWindow();
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::MapCheck_Execute()
|
|
{
|
|
GEditor->Exec( GetWorld(), TEXT("MAP CHECK") );
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::CanShowSourceCodeActions()
|
|
{
|
|
if (GEditor)
|
|
{
|
|
// Don't allow hot reloading if we're running networked PIE instances
|
|
// The reason, is it's fairly complicated to handle the re-wiring that needs to happen when we re-instance objects like player controllers, possessed pawns, etc...
|
|
const TIndirectArray<FWorldContext>& WorldContextList = GEditor->GetWorldContexts();
|
|
|
|
for (const FWorldContext& WorldContext : WorldContextList)
|
|
{
|
|
if (WorldContext.World() && WorldContext.World()->WorldType == EWorldType::PIE && WorldContext.World()->NetDriver)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
IHotReloadInterface& HotReloadSupport = FModuleManager::LoadModuleChecked<IHotReloadInterface>(HotReloadModule);
|
|
// If there is at least one loaded game module, source code actions should be available.
|
|
return HotReloadSupport.IsAnyGameModuleLoaded();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::RecompileGameCode_Clicked()
|
|
{
|
|
// Don't allow a recompile while already compiling!
|
|
IHotReloadInterface& HotReloadSupport = FModuleManager::LoadModuleChecked<IHotReloadInterface>(HotReloadModule);
|
|
if( !HotReloadSupport.IsCurrentlyCompiling() )
|
|
{
|
|
// Don't wait -- we want compiling to happen asynchronously
|
|
const bool bWaitForCompletion = false;
|
|
HotReloadSupport.DoHotReloadFromEditor(bWaitForCompletion);
|
|
}
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::Recompile_CanExecute()
|
|
{
|
|
// We're not able to recompile if a compile is already in progress!
|
|
|
|
IHotReloadInterface& HotReloadSupport = FModuleManager::LoadModuleChecked<IHotReloadInterface>(HotReloadModule);
|
|
return !HotReloadSupport.IsCurrentlyCompiling() && !(FApp::GetEngineIsPromotedBuild() && FEngineBuildSettings::IsPerforceBuild());
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::ConnectToSourceControl_Clicked()
|
|
{
|
|
// Show login window regardless of current status - its useful as a shortcut to change settings.
|
|
ISourceControlModule& SourceControlModule = ISourceControlModule::Get();
|
|
SourceControlModule.ShowLoginDialog(FSourceControlLoginClosed(), ELoginWindowMode::Modeless, EOnLoginWindowStartup::PreserveProvider);
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::CheckOutModifiedFiles_CanExecute()
|
|
{
|
|
ISourceControlModule& SourceControlModule = ISourceControlModule::Get();
|
|
if (ISourceControlModule::Get().IsEnabled() &&
|
|
ISourceControlModule::Get().GetProvider().IsAvailable())
|
|
{
|
|
TArray<UPackage*> PackagesToSave;
|
|
FEditorFileUtils::GetDirtyWorldPackages(PackagesToSave);
|
|
FEditorFileUtils::GetDirtyContentPackages(PackagesToSave);
|
|
|
|
return PackagesToSave.Num() > 0;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::CheckOutModifiedFiles_Clicked()
|
|
{
|
|
TArray<UPackage*> PackagesToSave;
|
|
FEditorFileUtils::GetDirtyWorldPackages(PackagesToSave);
|
|
FEditorFileUtils::GetDirtyContentPackages(PackagesToSave);
|
|
|
|
const bool bCheckDirty = true;
|
|
const bool bPromptUserToSave = false;
|
|
FEditorFileUtils::PromptForCheckoutAndSave(PackagesToSave, bCheckDirty, bPromptUserToSave);
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::SubmitToSourceControl_CanExecute()
|
|
{
|
|
ISourceControlModule& SourceControlModule = ISourceControlModule::Get();
|
|
return ISourceControlModule::Get().IsEnabled() &&
|
|
ISourceControlModule::Get().GetProvider().IsAvailable() &&
|
|
FSourceControlWindows::CanChoosePackagesToCheckIn();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SubmitToSourceControl_Clicked()
|
|
{
|
|
FSourceControlWindows::ChoosePackagesToCheckIn();
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::GoToCodeForActor_Clicked()
|
|
{
|
|
const auto& SelectedActorInfo = AssetSelectionUtils::GetSelectedActorInfo();
|
|
if( SelectedActorInfo.SelectionClass != nullptr )
|
|
{
|
|
FString ClassHeaderPath;
|
|
if( FSourceCodeNavigation::FindClassHeaderPath( SelectedActorInfo.SelectionClass, ClassHeaderPath ) && IFileManager::Get().FileSize( *ClassHeaderPath ) != INDEX_NONE )
|
|
{
|
|
FString AbsoluteHeaderPath = IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*ClassHeaderPath);
|
|
FSourceCodeNavigation::OpenSourceFile( AbsoluteHeaderPath );
|
|
}
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::GoToDocsForActor_Clicked()
|
|
{
|
|
const auto& SelectedActorInfo = AssetSelectionUtils::GetSelectedActorInfo();
|
|
if( SelectedActorInfo.SelectionClass != nullptr )
|
|
{
|
|
FString DocumentationLink = FEditorClassUtils::GetDocumentationLink(SelectedActorInfo.SelectionClass);
|
|
if (!DocumentationLink.IsEmpty())
|
|
{
|
|
IDocumentation::Get()->Open( DocumentationLink, FDocumentationSourceInfo(TEXT("rightclick_viewdoc")) );
|
|
}
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::FindInContentBrowser_Clicked()
|
|
{
|
|
GEditor->SyncToContentBrowser();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::ViewReferences_Execute()
|
|
{
|
|
if( GEditor->GetSelectedActorCount() > 0 )
|
|
{
|
|
TArray< UObject* > ReferencedAssets;
|
|
GEditor->GetReferencedAssetsForEditorSelection( ReferencedAssets );
|
|
|
|
if (ReferencedAssets.Num() > 0)
|
|
{
|
|
TArray< FName > ViewableObjects;
|
|
for( auto ObjectIter = ReferencedAssets.CreateConstIterator(); ObjectIter; ++ObjectIter )
|
|
{
|
|
// Don't allow user to perform certain actions on objects that aren't actually assets (e.g. Level Script blueprint objects)
|
|
const auto EditingObject = *ObjectIter;
|
|
if( EditingObject != NULL && EditingObject->IsAsset() )
|
|
{
|
|
ViewableObjects.Add( EditingObject->GetOuter()->GetFName());
|
|
}
|
|
}
|
|
|
|
IReferenceViewerModule::Get().InvokeReferenceViewerTab(ViewableObjects);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::CanViewReferences()
|
|
{
|
|
TArray< UObject* > ReferencedAssets;
|
|
GEditor->GetReferencedAssetsForEditorSelection(ReferencedAssets);
|
|
return ReferencedAssets.Num() > 0;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::ViewSizeMap_Execute()
|
|
{
|
|
if( GEditor->GetSelectedActorCount() > 0 )
|
|
{
|
|
TArray< UObject* > ReferencedAssets;
|
|
GEditor->GetReferencedAssetsForEditorSelection( ReferencedAssets );
|
|
|
|
if (ReferencedAssets.Num() > 0)
|
|
{
|
|
TArray< FName > ViewableObjects;
|
|
for( auto ObjectIter = ReferencedAssets.CreateConstIterator(); ObjectIter; ++ObjectIter )
|
|
{
|
|
// Don't allow user to perform certain actions on objects that aren't actually assets (e.g. Level Script blueprint objects)
|
|
const auto EditingObject = *ObjectIter;
|
|
if( EditingObject != NULL && EditingObject->IsAsset() )
|
|
{
|
|
ViewableObjects.Add( EditingObject->GetOuter()->GetFName());
|
|
}
|
|
}
|
|
|
|
ISizeMapModule::Get().InvokeSizeMapTab(ViewableObjects);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::CanViewSizeMap()
|
|
{
|
|
TArray< UObject* > ReferencedAssets;
|
|
GEditor->GetReferencedAssetsForEditorSelection(ReferencedAssets);
|
|
return ReferencedAssets.Num() > 0;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::EditAsset_Clicked( const EToolkitMode::Type ToolkitMode, TWeakPtr< SLevelEditor > LevelEditor, bool bConfirmMultiple )
|
|
{
|
|
if( GEditor->GetSelectedActorCount() > 0 )
|
|
{
|
|
TArray< UObject* > ReferencedAssets;
|
|
const bool bIgnoreOtherAssetsIfBPReferenced = true;
|
|
GEditor->GetReferencedAssetsForEditorSelection( ReferencedAssets, bIgnoreOtherAssetsIfBPReferenced );
|
|
|
|
bool bShouldOpenEditors = (ReferencedAssets.Num() == 1);
|
|
|
|
if (ReferencedAssets.Num() > 1)
|
|
{
|
|
if (bConfirmMultiple)
|
|
{
|
|
int32 Response = FMessageDialog::Open(
|
|
EAppMsgType::YesNo,
|
|
LOCTEXT("OpenAllAssetEditors", "There is more than one referenced asset in the selection. Do you want to open them all for editing?")
|
|
);
|
|
|
|
bShouldOpenEditors = (Response == EAppReturnType::Yes);
|
|
}
|
|
else
|
|
{
|
|
bShouldOpenEditors = true;
|
|
}
|
|
}
|
|
|
|
if (bShouldOpenEditors)
|
|
{
|
|
// Clear focus so the level viewport can receive its focus lost call (and clear pending keyup events which wouldn't arrive)
|
|
FSlateApplication::Get().ClearKeyboardFocus(EFocusCause::WindowActivate);
|
|
|
|
auto LevelEditorSharedPtr = LevelEditor.Pin();
|
|
|
|
if (LevelEditorSharedPtr.IsValid())
|
|
{
|
|
for (auto Asset : ReferencedAssets)
|
|
{
|
|
FAssetEditorManager::Get().OpenEditorForAsset(Asset, ToolkitMode, LevelEditorSharedPtr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::LockActorMovement_Clicked()
|
|
{
|
|
GEditor->ToggleSelectedActorMovementLock();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::DetachActor_Clicked()
|
|
{
|
|
GEditor->DetachSelectedActors();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::AttachSelectedActors()
|
|
{
|
|
GUnrealEd->AttachSelectedActors();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::AttachActorIteractive()
|
|
{
|
|
if(GUnrealEd->GetSelectedActorCount())
|
|
{
|
|
FActorPickerModeModule& ActorPickerMode = FModuleManager::Get().GetModuleChecked<FActorPickerModeModule>("ActorPickerMode");
|
|
|
|
ActorPickerMode.BeginActorPickingMode(
|
|
FOnGetAllowedClasses(),
|
|
FOnShouldFilterActor::CreateStatic(&FLevelEditorActionCallbacks::IsAttachableActor),
|
|
FOnActorSelected::CreateStatic(&FLevelEditorActionCallbacks::AttachToActor)
|
|
);
|
|
}
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::IsAttachableActor( const AActor* const ParentActor )
|
|
{
|
|
for ( FSelectionIterator It( GEditor->GetSelectedActorIterator() ) ; It ; ++It )
|
|
{
|
|
AActor* Actor = static_cast<AActor*>( *It );
|
|
if (!GEditor->CanParentActors(ParentActor, Actor))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
USceneComponent* ChildRoot = Actor->GetRootComponent();
|
|
USceneComponent* ParentRoot = ParentActor->GetRootComponent();
|
|
|
|
if (ChildRoot != nullptr && ParentRoot != nullptr && ChildRoot->IsAttachedTo(ParentRoot))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::CreateNewOutlinerFolder_Clicked()
|
|
{
|
|
const FName NewFolderName = FActorFolders::Get().GetDefaultFolderNameForSelection(*GetWorld());
|
|
FActorFolders::Get().CreateFolderContainingSelection(*GetWorld(), NewFolderName);
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::GoHere_Clicked( const FVector* Point )
|
|
{
|
|
if( GCurrentLevelEditingViewportClient )
|
|
{
|
|
FVector ZoomToPoint;
|
|
if( !Point )
|
|
{
|
|
FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues(
|
|
GCurrentLevelEditingViewportClient->Viewport,
|
|
GCurrentLevelEditingViewportClient->GetWorld()->Scene,
|
|
GCurrentLevelEditingViewportClient->EngineShowFlags)
|
|
.SetRealtimeUpdate(true));
|
|
|
|
|
|
FSceneView* SceneView = GCurrentLevelEditingViewportClient->CalcSceneView(&ViewFamily);
|
|
|
|
if(SceneView)
|
|
{
|
|
FIntPoint MousePosition;
|
|
FVector WorldOrigin;
|
|
FVector WorldDirection;
|
|
GCurrentLevelEditingViewportClient->Viewport->GetMousePos(MousePosition);
|
|
|
|
SceneView->DeprojectFVector2D(MousePosition, WorldOrigin, WorldDirection);
|
|
|
|
FHitResult HitResult;
|
|
|
|
FCollisionQueryParams LineParams(SCENE_QUERY_STAT(FocusOnPoint), true);
|
|
|
|
if(GCurrentLevelEditingViewportClient->GetWorld()->LineTraceSingleByObjectType(HitResult, WorldOrigin, WorldOrigin + WorldDirection * HALF_WORLD_MAX, FCollisionObjectQueryParams(ECC_WorldStatic), LineParams))
|
|
{
|
|
ZoomToPoint = HitResult.ImpactPoint;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ZoomToPoint = *Point;
|
|
}
|
|
|
|
const float PushOutSize = 500;
|
|
FBox BoundingBox(ZoomToPoint-PushOutSize, ZoomToPoint+PushOutSize);
|
|
|
|
GCurrentLevelEditingViewportClient->FocusViewportOnBox(BoundingBox);
|
|
}
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::LockActorMovement_IsChecked()
|
|
{
|
|
return GEditor->HasLockedActors();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::AddActor_Clicked( UActorFactory* ActorFactory, FAssetData AssetData, bool bUsePlacement )
|
|
{
|
|
UObject* Object = AssetData.GetAsset();
|
|
if(bUsePlacement && IPlacementModeModule::IsAvailable() && Object != NULL)
|
|
{
|
|
FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
|
|
LevelEditorModule.FocusViewport();
|
|
|
|
// Make sure we're in actor placement mode
|
|
GLevelEditorModeTools().ActivateMode(FBuiltinEditorModes::EM_Placement);
|
|
|
|
TArray<UObject*> AssetsToPlace;
|
|
AssetsToPlace.Add(Object);
|
|
|
|
auto* PlacementMode = GLevelEditorModeTools().GetActiveModeTyped<IPlacementMode>(FBuiltinEditorModes::EM_Placement);
|
|
PlacementMode->StartPlacing(AssetsToPlace, ActorFactory);
|
|
}
|
|
else
|
|
{
|
|
FLevelEditorActionCallbacks::AddActor(ActorFactory, AssetData, NULL);
|
|
}
|
|
}
|
|
|
|
AActor* FLevelEditorActionCallbacks::AddActor( UActorFactory* ActorFactory, const FAssetData& AssetData, const FTransform* ActorTransform )
|
|
{
|
|
AActor* NewActor = GEditor->UseActorFactory( ActorFactory, AssetData, ActorTransform );
|
|
|
|
if ( NewActor != NULL && IPlacementModeModule::IsAvailable() )
|
|
{
|
|
IPlacementModeModule::Get().AddToRecentlyPlaced( AssetData.GetAsset(), ActorFactory );
|
|
}
|
|
|
|
return NewActor;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::AddActorFromClass_Clicked( UClass* ActorClass )
|
|
{
|
|
FLevelEditorActionCallbacks::AddActorFromClass(ActorClass);
|
|
}
|
|
|
|
AActor* FLevelEditorActionCallbacks::AddActorFromClass( UClass* ActorClass )
|
|
{
|
|
AActor* NewActor = NULL;
|
|
|
|
if ( ActorClass )
|
|
{
|
|
// Look for an actor factory capable of creating actors of that type.
|
|
UActorFactory* ActorFactory = GEditor->FindActorFactoryForActorClass( ActorClass );
|
|
if( ActorFactory )
|
|
{
|
|
NewActor = GEditor->UseActorFactoryOnCurrentSelection( ActorFactory, nullptr );
|
|
|
|
if ( NewActor != NULL && IPlacementModeModule::IsAvailable() )
|
|
{
|
|
IPlacementModeModule::Get().AddToRecentlyPlaced( ActorClass, ActorFactory );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// No actor factory was found; use SpawnActor instead.
|
|
GUnrealEd->Exec( GetWorld(), *FString::Printf( TEXT("ACTOR ADD CLASS=%s"), *ActorClass->GetName() ) );
|
|
}
|
|
}
|
|
|
|
return NewActor;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::ReplaceActors_Clicked( UActorFactory* ActorFactory, FAssetData AssetData )
|
|
{
|
|
FLevelEditorActionCallbacks::ReplaceActors(ActorFactory, AssetData);
|
|
}
|
|
|
|
AActor* FLevelEditorActionCallbacks::ReplaceActors( UActorFactory* ActorFactory, const FAssetData& AssetData )
|
|
{
|
|
AActor* NewActor = NULL;
|
|
|
|
// Have a first stab at filling in the factory properties.
|
|
FText ErrorMessage;
|
|
if( ActorFactory->CanCreateActorFrom( AssetData, ErrorMessage ) )
|
|
{
|
|
// Replace all selected actors with actors created from the specified factory
|
|
GEditor->ReplaceSelectedActors( ActorFactory, AssetData );
|
|
|
|
if ( IPlacementModeModule::IsAvailable() )
|
|
{
|
|
IPlacementModeModule::Get().AddToRecentlyPlaced( AssetData.GetAsset(), ActorFactory );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FNotificationInfo ErrorNotification( ErrorMessage );
|
|
ErrorNotification.Image = FEditorStyle::GetBrush(TEXT("MessageLog.Error"));
|
|
ErrorNotification.bFireAndForget = true;
|
|
ErrorNotification.ExpireDuration = 3.0f; // Need this message to last a little longer than normal since the user may want to "Show Log"
|
|
ErrorNotification.bUseThrobber = true;
|
|
|
|
FSlateNotificationManager::Get().AddNotification(ErrorNotification);
|
|
}
|
|
|
|
return NewActor;
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::ReplaceActorsFromClass_Clicked( UClass* ActorClass )
|
|
{
|
|
if ( ActorClass )
|
|
{
|
|
// Look for an actor factory capable of creating actors of that type.
|
|
UActorFactory* ActorFactory = GEditor->FindActorFactoryForActorClass( ActorClass );
|
|
if( ActorFactory )
|
|
{
|
|
// Replace all selected actors with actors created from the specified factory
|
|
UObject* TargetAsset = GEditor->GetSelectedObjects()->GetTop<UObject>();
|
|
|
|
FText ErrorMessage;
|
|
FText UnusedErrorMessage;
|
|
const FAssetData NoAssetData;
|
|
const FAssetData TargetAssetData(TargetAsset);
|
|
if( ActorFactory->CanCreateActorFrom( TargetAssetData, ErrorMessage ) )
|
|
{
|
|
// Replace all selected actors with actors created from the specified factory
|
|
GEditor->ReplaceSelectedActors( ActorFactory, TargetAssetData );
|
|
}
|
|
else if ( ActorFactory->CanCreateActorFrom( NoAssetData, UnusedErrorMessage ) )
|
|
{
|
|
// Replace all selected actors with actors created from the specified factory
|
|
GEditor->ReplaceSelectedActors( ActorFactory, NoAssetData );
|
|
}
|
|
else
|
|
{
|
|
FNotificationInfo ErrorNotification( ErrorMessage );
|
|
ErrorNotification.Image = FEditorStyle::GetBrush(TEXT("MessageLog.Error"));
|
|
ErrorNotification.bFireAndForget = true;
|
|
ErrorNotification.ExpireDuration = 3.0f; // Need this message to last a little longer than normal since the user may want to "Show Log"
|
|
ErrorNotification.bUseThrobber = true;
|
|
|
|
FSlateNotificationManager::Get().AddNotification(ErrorNotification);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// No actor factory was found; use SpawnActor instead.
|
|
GUnrealEd->Exec( GetWorld(), *FString::Printf( TEXT("ACTOR REPLACE CLASS=%s"), *ActorClass->GetName() ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::Duplicate_CanExecute()
|
|
{
|
|
TArray<FEdMode*> ActiveModes;
|
|
GLevelEditorModeTools().GetActiveModes( ActiveModes );
|
|
for( int32 ModeIndex = 0; ModeIndex < ActiveModes.Num(); ++ModeIndex )
|
|
{
|
|
const EEditAction::Type CanProcess = ActiveModes[ModeIndex]->GetActionEditDuplicate();
|
|
if (CanProcess == EEditAction::Process)
|
|
{
|
|
return true;
|
|
}
|
|
else if (CanProcess == EEditAction::Halt)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// If we can copy, we can duplicate
|
|
bool bCanCopy = false;
|
|
if (GEditor->GetSelectedComponentCount() > 0)
|
|
{
|
|
TArray<UActorComponent*> SelectedComponents;
|
|
for (FSelectionIterator It(GEditor->GetSelectedComponentIterator()); It; ++It)
|
|
{
|
|
SelectedComponents.Add(CastChecked<UActorComponent>(*It));
|
|
}
|
|
|
|
bCanCopy = FComponentEditorUtils::CanCopyComponents(SelectedComponents);
|
|
}
|
|
else
|
|
{
|
|
bCanCopy = GUnrealEd->CanCopySelectedActorsToClipboard(GetWorld());
|
|
}
|
|
|
|
return bCanCopy;
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::Delete_CanExecute()
|
|
{
|
|
TArray<FEdMode*> ActiveModes;
|
|
GLevelEditorModeTools().GetActiveModes( ActiveModes );
|
|
for( int32 ModeIndex = 0; ModeIndex < ActiveModes.Num(); ++ModeIndex )
|
|
{
|
|
const EEditAction::Type CanProcess = ActiveModes[ModeIndex]->GetActionEditDelete();
|
|
if (CanProcess == EEditAction::Process)
|
|
{
|
|
return true;
|
|
}
|
|
else if (CanProcess == EEditAction::Halt)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool bCanDelete = false;
|
|
if (GEditor->GetSelectedComponentCount() > 0)
|
|
{
|
|
TArray<UActorComponent*> SelectedComponents;
|
|
for (FSelectionIterator It(GEditor->GetSelectedComponentIterator()); It; ++It)
|
|
{
|
|
SelectedComponents.Add(CastChecked<UActorComponent>(*It));
|
|
}
|
|
|
|
bCanDelete = FComponentEditorUtils::CanDeleteComponents(SelectedComponents);
|
|
}
|
|
else
|
|
{
|
|
bCanDelete = GUnrealEd->CanDeleteSelectedActors(GetWorld(), true, false);
|
|
}
|
|
|
|
return bCanDelete;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::Rename_Execute()
|
|
{
|
|
UActorComponent* Component = Cast<UActorComponent>(*GEditor->GetSelectedComponentIterator());
|
|
if (Component)
|
|
{
|
|
GEditor->BroadcastLevelComponentRequestRename(Component);
|
|
}
|
|
else
|
|
{
|
|
AActor* Actor = Cast<AActor>(*GEditor->GetSelectedActorIterator());
|
|
if (Actor)
|
|
{
|
|
GEditor->BroadcastLevelActorRequestRename(Actor);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::Rename_CanExecute()
|
|
{
|
|
bool bCanRename = false;
|
|
if (GEditor->GetSelectedComponentCount() == 1)
|
|
{
|
|
if (UActorComponent* ComponentToRename = GEditor->GetSelectedComponents()->GetTop<UActorComponent>())
|
|
{
|
|
// We can't edit non-instance components or the default scene root
|
|
bCanRename = ComponentToRename->CreationMethod == EComponentCreationMethod::Instance && ComponentToRename->GetFName() != USceneComponent::GetDefaultSceneRootVariableName();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bCanRename = GEditor->GetSelectedActorCount() == 1;
|
|
}
|
|
|
|
return bCanRename;
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::Cut_CanExecute()
|
|
{
|
|
TArray<FEdMode*> ActiveModes;
|
|
GLevelEditorModeTools().GetActiveModes( ActiveModes );
|
|
for( int32 ModeIndex = 0; ModeIndex < ActiveModes.Num(); ++ModeIndex )
|
|
{
|
|
const EEditAction::Type CanProcess = ActiveModes[ModeIndex]->GetActionEditCut();
|
|
if (CanProcess == EEditAction::Process)
|
|
{
|
|
return true;
|
|
}
|
|
else if (CanProcess == EEditAction::Halt)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool bCanCut = false;
|
|
if (GEditor->GetSelectedComponentCount() > 0)
|
|
{
|
|
// Make sure the components can be copied and deleted
|
|
TArray<UActorComponent*> SelectedComponents;
|
|
for (FSelectionIterator It(GEditor->GetSelectedComponentIterator()); It; ++It)
|
|
{
|
|
SelectedComponents.Add(CastChecked<UActorComponent>(*It));
|
|
}
|
|
|
|
bCanCut = FComponentEditorUtils::CanCopyComponents(SelectedComponents) && FComponentEditorUtils::CanDeleteComponents(SelectedComponents);
|
|
}
|
|
else
|
|
{
|
|
// For actors, if we can copy, we can cut
|
|
bCanCut = GUnrealEd->CanCopySelectedActorsToClipboard(GetWorld());
|
|
}
|
|
|
|
return bCanCut;
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::Copy_CanExecute()
|
|
{
|
|
TArray<FEdMode*> ActiveModes;
|
|
GLevelEditorModeTools().GetActiveModes( ActiveModes );
|
|
for( int32 ModeIndex = 0; ModeIndex < ActiveModes.Num(); ++ModeIndex )
|
|
{
|
|
const EEditAction::Type CanProcess = ActiveModes[ModeIndex]->GetActionEditCopy();
|
|
if (CanProcess == EEditAction::Process)
|
|
{
|
|
return true;
|
|
}
|
|
else if (CanProcess == EEditAction::Halt)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool bCanCopy = false;
|
|
if (GEditor->GetSelectedComponentCount() > 0)
|
|
{
|
|
TArray<UActorComponent*> SelectedComponents;
|
|
for (FSelectionIterator It(GEditor->GetSelectedComponentIterator()); It; ++It)
|
|
{
|
|
SelectedComponents.Add(CastChecked<UActorComponent>(*It));
|
|
}
|
|
|
|
bCanCopy = FComponentEditorUtils::CanCopyComponents(SelectedComponents);
|
|
}
|
|
else
|
|
{
|
|
bCanCopy = GUnrealEd->CanCopySelectedActorsToClipboard(GetWorld());
|
|
}
|
|
|
|
return bCanCopy;
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::Paste_CanExecute()
|
|
{
|
|
TArray<FEdMode*> ActiveModes;
|
|
GLevelEditorModeTools().GetActiveModes( ActiveModes );
|
|
for( int32 ModeIndex = 0; ModeIndex < ActiveModes.Num(); ++ModeIndex )
|
|
{
|
|
const EEditAction::Type CanProcess = ActiveModes[ModeIndex]->GetActionEditPaste();
|
|
if (CanProcess == EEditAction::Process)
|
|
{
|
|
return true;
|
|
}
|
|
else if (CanProcess == EEditAction::Halt)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool bCanPaste = false;
|
|
if (GEditor->GetSelectedComponentCount() > 0)
|
|
{
|
|
if(ensureMsgf(GEditor->GetSelectedActorCount() == 1, TEXT("Expected SelectedActorCount to be 1 but was %d"), GEditor->GetSelectedActorCount()))
|
|
{
|
|
auto SelectedActor = CastChecked<AActor>(*GEditor->GetSelectedActorIterator());
|
|
bCanPaste = FComponentEditorUtils::CanPasteComponents(SelectedActor->GetRootComponent());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bCanPaste = GUnrealEd->CanPasteSelectedActorsFromClipboard(GetWorld());
|
|
}
|
|
|
|
return bCanPaste;
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::PasteHere_CanExecute()
|
|
{
|
|
return Paste_CanExecute(); // For now, just do the same check as Paste
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::ExecuteExecCommand( FString Command )
|
|
{
|
|
UWorld* OldWorld = nullptr;
|
|
|
|
// The play world needs to be selected if it exists
|
|
if (GIsEditor && GEditor->PlayWorld && !GIsPlayInEditorWorld)
|
|
{
|
|
OldWorld = SetPlayInEditorWorld(GEditor->PlayWorld);
|
|
}
|
|
|
|
GUnrealEd->Exec(GetWorld(), *Command);
|
|
|
|
// Restore the old world if there was one
|
|
if (OldWorld)
|
|
{
|
|
RestoreEditorWorld(OldWorld);
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnSelectAllActorsOfClass( bool bArchetype )
|
|
{
|
|
GEditor->SelectAllActorsWithClass( bArchetype );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnSelectComponentOwnerActor()
|
|
{
|
|
auto ComponentOwner = Cast<AActor>(*GEditor->GetSelectedActorIterator());
|
|
check(ComponentOwner);
|
|
|
|
GEditor->SelectNone(true, true, false);
|
|
GEditor->SelectActor(ComponentOwner, true, true, true);
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::CanSelectComponentOwnerActor()
|
|
{
|
|
return GEditor->GetSelectedComponentCount() > 0;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnSelectAllActorsControlledByMatinee()
|
|
{
|
|
GEditor->SelectAllActorsControlledByMatinee();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnSelectOwningHLODCluster()
|
|
{
|
|
if (GEditor->GetSelectedActorCount() > 0)
|
|
{
|
|
AActor* Actor = Cast<AActor>(GEditor->GetSelectedActors()->GetSelectedObject(0));
|
|
|
|
FHierarchicalLODUtilitiesModule& Module = FModuleManager::LoadModuleChecked<FHierarchicalLODUtilitiesModule>("HierarchicalLODUtilities");
|
|
IHierarchicalLODUtilities* Utilities = Module.GetUtilities();
|
|
|
|
ALODActor* ParentActor = Utilities->GetParentLODActor(Actor);
|
|
if (Actor && ParentActor)
|
|
{
|
|
GEditor->SelectNone(false, true);
|
|
GEditor->SelectActor(ParentActor, true, false);
|
|
GEditor->NoteSelectionChange();
|
|
}
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnSelectMatineeActor( AMatineeActor * ActorToSelect )
|
|
{
|
|
GEditor->SelectNone( false, true );
|
|
GEditor->SelectActor(ActorToSelect, true, false, true);
|
|
|
|
GEditor->NoteSelectionChange();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnSelectMatineeGroup( AActor* Actor )
|
|
{
|
|
if( GLevelEditorModeTools().IsModeActive( FBuiltinEditorModes::EM_InterpEdit ) )
|
|
{
|
|
FEdModeInterpEdit* InterpEditMode = (FEdModeInterpEdit*)GLevelEditorModeTools().GetActiveMode( FBuiltinEditorModes::EM_InterpEdit );
|
|
|
|
if ( InterpEditMode && InterpEditMode->MatineeActor )
|
|
{
|
|
InterpEditMode->UpdateSelectedActor();
|
|
}
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnApplyMaterialToSurface()
|
|
{
|
|
FEditorDelegates::LoadSelectedAssetsIfNeeded.Broadcast();
|
|
|
|
GUnrealEd->Exec( GetWorld(), TEXT("POLY SETMATERIAL") );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnSelectAllLights()
|
|
{
|
|
GEditor->GetSelectedActors()->BeginBatchSelectOperation();
|
|
// Select all light actors.
|
|
for( ALight* Light : TActorRange<ALight>(GetWorld()) )
|
|
{
|
|
GUnrealEd->SelectActor( Light, true, false, false );
|
|
}
|
|
|
|
GEditor->GetSelectedActors()->EndBatchSelectOperation();
|
|
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnSelectStationaryLightsExceedingOverlap()
|
|
{
|
|
GEditor->SelectNone( true, true );
|
|
for( FActorIterator It(GetWorld()); It; ++It )
|
|
{
|
|
AActor* Actor = *It;
|
|
|
|
TInlineComponentArray<ULightComponent*> Components;
|
|
Actor->GetComponents(Components);
|
|
|
|
for (int32 ComponentIndex = 0; ComponentIndex < Components.Num(); ComponentIndex++)
|
|
{
|
|
ULightComponent* LightComponent = Components[ComponentIndex];
|
|
|
|
if (LightComponent->GetOwner()
|
|
// Use the component's lighting properties to determine if this is a stationary light, instead of checking the actor type
|
|
// Because blueprint lights may be operating as stationary lights
|
|
&& LightComponent->HasStaticShadowing()
|
|
&& !LightComponent->HasStaticLighting()
|
|
&& LightComponent->bAffectsWorld
|
|
&& LightComponent->CastShadows
|
|
&& LightComponent->CastStaticShadows
|
|
&& LightComponent->PreviewShadowMapChannel == INDEX_NONE)
|
|
{
|
|
GUnrealEd->SelectActor( LightComponent->GetOwner(), true, true, false );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnSurfaceAlignment( ETexAlign AlignmentMode )
|
|
{
|
|
GTexAlignTools.GetAligner( AlignmentMode )->Align( GetWorld(), AlignmentMode );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::RegroupActor_Clicked()
|
|
{
|
|
UActorGroupingUtils::Get()->GroupSelected();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::UngroupActor_Clicked()
|
|
{
|
|
UActorGroupingUtils::Get()->UngroupSelected();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::LockGroup_Clicked()
|
|
{
|
|
UActorGroupingUtils::Get()->LockSelectedGroups();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::UnlockGroup_Clicked()
|
|
{
|
|
UActorGroupingUtils::Get()->UnlockSelectedGroups();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::AddActorsToGroup_Clicked()
|
|
{
|
|
UActorGroupingUtils::Get()->AddSelectedToGroup();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::RemoveActorsFromGroup_Clicked()
|
|
{
|
|
UActorGroupingUtils::Get()->RemoveSelectedFromGroup();
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::LocationGridSnap_Clicked()
|
|
{
|
|
GUnrealEd->Exec( GetWorld(), *FString::Printf( TEXT("MODE GRID=%d"), !GetDefault<ULevelEditorViewportSettings>()->GridEnabled ? 1 : 0 ) );
|
|
}
|
|
|
|
|
|
bool FLevelEditorActionCallbacks::LocationGridSnap_IsChecked()
|
|
{
|
|
return GetDefault<ULevelEditorViewportSettings>()->GridEnabled;
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::RotationGridSnap_Clicked()
|
|
{
|
|
GUnrealEd->Exec( GetWorld(), *FString::Printf( TEXT("MODE ROTGRID=%d"), !GetDefault<ULevelEditorViewportSettings>()->RotGridEnabled ? 1 : 0 ) );
|
|
}
|
|
|
|
|
|
bool FLevelEditorActionCallbacks::RotationGridSnap_IsChecked()
|
|
{
|
|
return GetDefault<ULevelEditorViewportSettings>()->RotGridEnabled;
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::ScaleGridSnap_Clicked()
|
|
{
|
|
GUnrealEd->Exec( GetWorld(), *FString::Printf( TEXT("MODE SCALEGRID=%d"), !GetDefault<ULevelEditorViewportSettings>()->SnapScaleEnabled ? 1 : 0 ) );
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::ScaleGridSnap_IsChecked()
|
|
{
|
|
return GetDefault<ULevelEditorViewportSettings>()->SnapScaleEnabled;
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::SaveAnimationFromSkeletalMeshComponent(AActor * EditorActor, AActor * SimActor, TArray<class USkeletalMeshComponent*> & OutEditorComponents)
|
|
{
|
|
FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked<FLevelEditorModule>( TEXT("LevelEditor") );
|
|
|
|
// currently blueprint actors don't work because their property can't get copied over.
|
|
if (Cast<UBlueprintGeneratedClass>(EditorActor->GetClass()) != nullptr)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// find all skel components
|
|
TInlineComponentArray<class USkeletalMeshComponent *> SimSkelComponents;
|
|
SimActor->GetComponents<USkeletalMeshComponent>(SimSkelComponents);
|
|
|
|
if(SimSkelComponents.Num() > 0)
|
|
{
|
|
// see if simulating,
|
|
bool bSimulating = false;
|
|
for (auto & Comp : SimSkelComponents)
|
|
{
|
|
bSimulating |= (Comp->SkeletalMesh && Comp->SkeletalMesh->Skeleton && Comp->IsSimulatingPhysics());
|
|
}
|
|
|
|
// if any of them are legitimately simulating
|
|
if (bSimulating)
|
|
{
|
|
// ask users if you'd like to make an animation
|
|
FFormatNamedArguments Args;
|
|
Args.Add(TEXT("ActorName"), FText::FromString(GetNameSafe(EditorActor)));
|
|
FText AskQuestion = FText::Format(LOCTEXT("KeepSimulationChanges_AskSaveAnimation", "Would you like to save animations from simulation for {ActorName} actor"), Args);
|
|
if(EAppReturnType::Yes == FMessageDialog::Open(EAppMsgType::YesNo, AskQuestion))
|
|
{
|
|
for (auto & Comp : SimSkelComponents)
|
|
{
|
|
if (Comp->SkeletalMesh && Comp->SkeletalMesh->Skeleton && Comp->IsSimulatingPhysics())
|
|
{
|
|
// now record to animation
|
|
class UAnimSequence* Sequence = LevelEditorModule.OnCaptureSingleFrameAnimSequence().IsBound() ? LevelEditorModule.OnCaptureSingleFrameAnimSequence().Execute(Comp) : nullptr;
|
|
if(Sequence)
|
|
{
|
|
Comp->SetAnimationMode(EAnimationMode::AnimationSingleNode);
|
|
Comp->AnimationData.AnimToPlay = Sequence;
|
|
Comp->SetAnimation(Sequence);
|
|
Comp->SetSimulatePhysics(false);
|
|
|
|
// add the matching component to EditorCompoennts
|
|
class USkeletalMeshComponent * MatchingComponent = Cast<USkeletalMeshComponent>(EditorUtilities::FindMatchingComponentInstance(Comp, EditorActor));
|
|
if (MatchingComponent)
|
|
{
|
|
OutEditorComponents.Add(MatchingComponent);
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LevelEditorActions, Warning, TEXT("Matching component could not be found %s(%s)"), *GetNameSafe(Comp), *GetNameSafe(EditorActor));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OpenMergeActor_Clicked()
|
|
{
|
|
FGlobalTabmanager::Get()->InvokeTab(FName("MergeActors"));
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnKeepSimulationChanges()
|
|
{
|
|
// @todo simulate: There are lots of types of changes that can't be "kept", like attachment or newly-spawned actors. This
|
|
// feature currently only supports propagating changes to regularly-editable properties on an instance of a PIE actor
|
|
// that still exists in the editor world.
|
|
|
|
// Make sure we have some actors selected, and PIE is running
|
|
if( GEditor->GetSelectedActorCount() > 0 && GEditor->PlayWorld != NULL )
|
|
{
|
|
int32 UpdatedActorCount = 0;
|
|
int32 TotalCopiedPropertyCount = 0;
|
|
FString FirstUpdatedActorLabel;
|
|
{
|
|
const FScopedTransaction Transaction( NSLOCTEXT( "LevelEditorCommands", "KeepSimulationChanges", "Keep Simulation Changes" ) );
|
|
|
|
TArray<class USkeletalMeshComponent*> ComponentsToReinitialize;
|
|
|
|
for( auto ActorIt( GEditor->GetSelectedActorIterator() ); ActorIt; ++ActorIt )
|
|
{
|
|
auto* SimWorldActor = CastChecked<AActor>( *ActorIt );
|
|
|
|
// Find our counterpart actor
|
|
AActor* EditorWorldActor = EditorUtilities::GetEditorWorldCounterpartActor( SimWorldActor );
|
|
if( EditorWorldActor != NULL )
|
|
{
|
|
SaveAnimationFromSkeletalMeshComponent(EditorWorldActor, SimWorldActor, ComponentsToReinitialize);
|
|
|
|
// We only want to copy CPF_Edit properties back, or properties that are set through editor manipulation
|
|
// NOTE: This needs to match what we're doing in the BuildSelectedActorInfo() function
|
|
const auto CopyOptions = ( EditorUtilities::ECopyOptions::Type )(
|
|
EditorUtilities::ECopyOptions::CallPostEditChangeProperty |
|
|
EditorUtilities::ECopyOptions::CallPostEditMove |
|
|
EditorUtilities::ECopyOptions::OnlyCopyEditOrInterpProperties |
|
|
EditorUtilities::ECopyOptions::FilterBlueprintReadOnly);
|
|
const int32 CopiedPropertyCount = EditorUtilities::CopyActorProperties( SimWorldActor, EditorWorldActor, CopyOptions );
|
|
|
|
if( CopiedPropertyCount > 0 )
|
|
{
|
|
++UpdatedActorCount;
|
|
TotalCopiedPropertyCount += CopiedPropertyCount;
|
|
|
|
if( FirstUpdatedActorLabel.IsEmpty() )
|
|
{
|
|
FirstUpdatedActorLabel = EditorWorldActor->GetActorLabel();
|
|
}
|
|
}
|
|
}
|
|
|
|
// need to reinitialize animation
|
|
for (auto MeshComp : ComponentsToReinitialize)
|
|
{
|
|
if(MeshComp->SkeletalMesh)
|
|
{
|
|
MeshComp->InitAnim(true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Let the user know what happened
|
|
{
|
|
FNotificationInfo NotificationInfo( FText::GetEmpty() );
|
|
NotificationInfo.bFireAndForget = true;
|
|
NotificationInfo.FadeInDuration = 0.25f;
|
|
NotificationInfo.FadeOutDuration = 1.0f;
|
|
NotificationInfo.ExpireDuration = 1.0f;
|
|
NotificationInfo.bUseLargeFont = false;
|
|
NotificationInfo.bUseSuccessFailIcons = true;
|
|
NotificationInfo.bAllowThrottleWhenFrameRateIsLow = false; // Don't throttle as it causes distracting hitches in Simulate mode
|
|
SNotificationItem::ECompletionState CompletionState;
|
|
if( UpdatedActorCount > 0 )
|
|
{
|
|
if( UpdatedActorCount > 1 )
|
|
{
|
|
FFormatNamedArguments Args;
|
|
Args.Add( TEXT("UpdatedActorCount"), UpdatedActorCount );
|
|
Args.Add( TEXT("TotalCopiedPropertyCount"), TotalCopiedPropertyCount );
|
|
NotificationInfo.Text = FText::Format( NSLOCTEXT( "LevelEditorCommands", "KeepSimulationChanges_MultipleActorsUpdatedNotification", "Saved state for {UpdatedActorCount} actors ({TotalCopiedPropertyCount} properties)" ), Args );
|
|
}
|
|
else
|
|
{
|
|
FFormatNamedArguments Args;
|
|
Args.Add( TEXT("FirstUpdatedActorLabel"), FText::FromString( FirstUpdatedActorLabel ) );
|
|
Args.Add( TEXT("TotalCopiedPropertyCount"), TotalCopiedPropertyCount );
|
|
NotificationInfo.Text = FText::Format( NSLOCTEXT( "LevelEditorCommands", "KeepSimulationChanges_ActorUpdatedNotification", "Saved state for {FirstUpdatedActorLabel} ({TotalCopiedPropertyCount} properties)" ), Args );
|
|
}
|
|
CompletionState = SNotificationItem::CS_Success;
|
|
}
|
|
else
|
|
{
|
|
NotificationInfo.Text = NSLOCTEXT( "LevelEditorCommands", "KeepSimulationChanges_NoActorsUpdated", "No properties were copied" );
|
|
CompletionState = SNotificationItem::CS_Fail;
|
|
}
|
|
const auto Notification = FSlateNotificationManager::Get().AddNotification( NotificationInfo );
|
|
Notification->SetCompletionState( CompletionState );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
bool FLevelEditorActionCallbacks::CanExecuteKeepSimulationChanges()
|
|
{
|
|
return AssetSelectionUtils::GetSelectedActorInfo().NumSimulationChanges > 0;
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::OnMakeSelectedActorLevelCurrent()
|
|
{
|
|
GUnrealEd->MakeSelectedActorsLevelCurrent();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnMoveSelectedToCurrentLevel()
|
|
{
|
|
UEditorLevelUtils::MoveSelectedActorsToLevel(GetWorld()->GetCurrentLevel());
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnFindActorLevelInContentBrowser()
|
|
{
|
|
GEditor->SyncActorLevelsToContentBrowser();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::CanExecuteFindActorLevelInContentBrowser()
|
|
{
|
|
return GEditor->CanSyncActorLevelsToContentBrowser();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnFindLevelsInLevelBrowser()
|
|
{
|
|
const bool bDeselectOthers = true;
|
|
GEditor->SelectLevelInLevelBrowser( bDeselectOthers );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnSelectLevelInLevelBrowser()
|
|
{
|
|
const bool bDeselectOthers = false;
|
|
GEditor->SelectLevelInLevelBrowser( bDeselectOthers );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnDeselectLevelInLevelBrowser()
|
|
{
|
|
GEditor->DeselectLevelInLevelBrowser();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnFindActorInLevelScript()
|
|
{
|
|
GUnrealEd->FindSelectedActorsInLevelScript();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnShowWorldProperties( TWeakPtr< SLevelEditor > LevelEditor )
|
|
{
|
|
FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked<FLevelEditorModule>( TEXT("LevelEditor") );
|
|
LevelEditorModule.GetLevelEditorTabManager()->InvokeTab(FName("WorldSettingsTab"));
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OpenContentBrowser()
|
|
{
|
|
FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked<FContentBrowserModule>("ContentBrowser");
|
|
ContentBrowserModule.Get().FocusPrimaryContentBrowser(true);
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OpenMarketplace()
|
|
{
|
|
FUnrealEdMisc::Get().OpenMarketplace();
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::ToggleVR()
|
|
{
|
|
IVREditorModule& VREditorModule = IVREditorModule::Get();
|
|
VREditorModule.EnableVREditor( !VREditorModule.IsVREditorEnabled() );
|
|
}
|
|
|
|
|
|
bool FLevelEditorActionCallbacks::ToggleVR_CanExecute()
|
|
{
|
|
IVREditorModule& VREditorModule = IVREditorModule::Get();
|
|
return VREditorModule.IsVREditorAvailable();
|
|
}
|
|
|
|
|
|
bool FLevelEditorActionCallbacks::ToggleVR_IsChecked()
|
|
{
|
|
IVREditorModule& VREditorModule = IVREditorModule::Get();
|
|
return VREditorModule.IsVREditorEnabled();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::CanSelectGameModeBlueprint()
|
|
{
|
|
bool bCheckOutNeeded = false;
|
|
|
|
FString ConfigFilePath = FPaths::ConvertRelativePathToFull(FString::Printf(TEXT("%sDefaultEngine.ini"), *FPaths::SourceConfigDir()));
|
|
if(ISourceControlModule::Get().IsEnabled())
|
|
{
|
|
// note: calling QueueStatusUpdate often does not spam status updates as an internal timer prevents this
|
|
//ISourceControlModule::Get().QueueStatusUpdate(ConfigFilePath);
|
|
|
|
ISourceControlProvider& SourceControlProvider = ISourceControlModule::Get().GetProvider();
|
|
FSourceControlStatePtr SourceControlState = SourceControlProvider.GetState(ConfigFilePath, EStateCacheUsage::Use);
|
|
bCheckOutNeeded = SourceControlState.IsValid() && SourceControlState->CanCheckout();
|
|
}
|
|
else
|
|
{
|
|
bCheckOutNeeded = (FPaths::FileExists(ConfigFilePath) && IFileManager::Get().IsReadOnly(*ConfigFilePath));
|
|
}
|
|
return !bCheckOutNeeded;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OpenLevelBlueprint( TWeakPtr< SLevelEditor > LevelEditor )
|
|
{
|
|
if( LevelEditor.Pin()->GetWorld()->GetCurrentLevel() )
|
|
{
|
|
ULevelScriptBlueprint* LevelScriptBlueprint = LevelEditor.Pin()->GetWorld()->PersistentLevel->GetLevelScriptBlueprint();
|
|
if (LevelScriptBlueprint)
|
|
{
|
|
// @todo Re-enable once world centric works
|
|
const bool bOpenWorldCentric = false;
|
|
FAssetEditorManager::Get().OpenEditorForAsset(
|
|
LevelScriptBlueprint,
|
|
bOpenWorldCentric ? EToolkitMode::WorldCentric : EToolkitMode::Standalone,
|
|
LevelEditor.Pin() );
|
|
}
|
|
else
|
|
{
|
|
FMessageDialog::Open( EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "UnableToCreateLevelScript", "Unable to find or create a level blueprint for this level.") );
|
|
}
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::CreateBlankBlueprintClass()
|
|
{
|
|
// Use the BlueprintFactory to allow the user to pick a parent class for the new Blueprint class
|
|
UBlueprintFactory* NewFactory = Cast<UBlueprintFactory>(NewObject<UFactory>(GetTransientPackage(), UBlueprintFactory::StaticClass()));
|
|
FEditorDelegates::OnConfigureNewAssetProperties.Broadcast(NewFactory);
|
|
if ( NewFactory->ConfigureProperties() )
|
|
{
|
|
UClass* SelectedClass = NewFactory->ParentClass;
|
|
|
|
// Now help the user pick a path and name for the new Blueprint
|
|
UBlueprint* Blueprint = FKismetEditorUtilities::CreateBlueprintFromClass(NSLOCTEXT("LevelEditorCommands", "CreateBlankBlueprintClass_Title", "Create Blank Blueprint Class"), SelectedClass);
|
|
|
|
if( Blueprint )
|
|
{
|
|
// @todo Re-enable once world centric works
|
|
const bool bOpenWorldCentric = false;
|
|
FAssetEditorManager::Get().OpenEditorForAsset(
|
|
Blueprint,
|
|
bOpenWorldCentric ? EToolkitMode::WorldCentric : EToolkitMode::Standalone);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::CanHarvestSelectedActorsIntoBlueprintClass()
|
|
{
|
|
return GEditor->GetSelectedActorCount() > 0;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::HarvestSelectedActorsIntoBlueprintClass()
|
|
{
|
|
const bool bHarvest = true;
|
|
FCreateBlueprintFromActorDialog::OpenDialog(bHarvest);
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::CanSubclassSelectedActorIntoBlueprintClass()
|
|
{
|
|
bool bCanSubclass = GEditor->GetSelectedActorCount() == 1;
|
|
if (bCanSubclass)
|
|
{
|
|
AActor* Actor = Cast<AActor>(*GEditor->GetSelectedActorIterator());
|
|
bCanSubclass = FKismetEditorUtilities::CanCreateBlueprintOfClass(Actor->GetClass());
|
|
}
|
|
return bCanSubclass;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SubclassSelectedActorIntoBlueprintClass()
|
|
{
|
|
const bool bHarvest = false;
|
|
FCreateBlueprintFromActorDialog::OpenDialog(bHarvest);
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::CheckOutProjectSettingsConfig( )
|
|
{
|
|
FString ConfigFilePath = FPaths::ConvertRelativePathToFull(FString::Printf(TEXT("%sDefaultEngine.ini"), *FPaths::SourceConfigDir()));
|
|
if(ISourceControlModule::Get().IsEnabled())
|
|
{
|
|
SourceControlHelpers::CheckOutFile(ConfigFilePath);
|
|
}
|
|
else
|
|
{
|
|
FPlatformFileManager::Get().GetPlatformFile().SetReadOnly(*ConfigFilePath, false);
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnShowOnlySelectedActors()
|
|
{
|
|
const FScopedTransaction Transaction( NSLOCTEXT( "LevelEditorCommands", "ShowOnlySelectedActors", "Show Only Selected Actors" ) );
|
|
// First hide unselected as this will also hide group actor members
|
|
GUnrealEd->edactHideUnselected( GetWorld() );
|
|
// Then unhide selected to ensure that everything that's selected will be unhidden
|
|
GUnrealEd->edactUnhideSelected(GetWorld());
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnToggleTransformWidgetVisibility()
|
|
{
|
|
GLevelEditorModeTools().SetShowWidget( !GLevelEditorModeTools().GetShowWidget() );
|
|
GUnrealEd->RedrawAllViewports();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::OnGetTransformWidgetVisibility()
|
|
{
|
|
return GLevelEditorModeTools().GetShowWidget();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnAllowTranslucentSelection()
|
|
{
|
|
auto* Settings = GetMutableDefault<UEditorPerProjectUserSettings>();
|
|
|
|
// Toggle 'allow select translucent'
|
|
Settings->bAllowSelectTranslucent = !Settings->bAllowSelectTranslucent;
|
|
Settings->PostEditChange();
|
|
|
|
// Need to refresh hit proxies as we changed what should be rendered into them
|
|
GUnrealEd->RedrawAllViewports();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::OnIsAllowTranslucentSelectionEnabled()
|
|
{
|
|
return GetDefault<UEditorPerProjectUserSettings>()->bAllowSelectTranslucent == true;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnAllowGroupSelection()
|
|
{
|
|
AGroupActor::ToggleGroupMode();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::OnIsAllowGroupSelectionEnabled()
|
|
{
|
|
return UActorGroupingUtils::IsGroupingActive();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnToggleStrictBoxSelect()
|
|
{
|
|
ULevelEditorViewportSettings* ViewportSettings = GetMutableDefault<ULevelEditorViewportSettings>();
|
|
ViewportSettings->bStrictBoxSelection = !ViewportSettings->bStrictBoxSelection;
|
|
ViewportSettings->PostEditChange();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::OnIsStrictBoxSelectEnabled()
|
|
{
|
|
return GetDefault<ULevelEditorViewportSettings>()->bStrictBoxSelection;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnToggleTransparentBoxSelect()
|
|
{
|
|
ULevelEditorViewportSettings* ViewportSettings = GetMutableDefault<ULevelEditorViewportSettings>();
|
|
ViewportSettings->bTransparentBoxSelection = !ViewportSettings->bTransparentBoxSelection;
|
|
ViewportSettings->PostEditChange();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::OnIsTransparentBoxSelectEnabled()
|
|
{
|
|
return GetDefault<ULevelEditorViewportSettings>()->bTransparentBoxSelection;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnDrawBrushMarkerPolys()
|
|
{
|
|
GEditor->Exec( GetWorld(), *FString::Printf( TEXT("MODE SHOWBRUSHMARKERPOLYS=%d"), !GEditor->bShowBrushMarkerPolys ? 1 : 0 ) );
|
|
GEditor->SaveConfig();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::OnIsDrawBrushMarkerPolysEnabled()
|
|
{
|
|
return GEditor->bShowBrushMarkerPolys;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnToggleOnlyLoadVisibleInPIE()
|
|
{
|
|
ULevelEditorPlaySettings* PlaySettings = GetMutableDefault<ULevelEditorPlaySettings>();
|
|
PlaySettings->bOnlyLoadVisibleLevelsInPIE = !PlaySettings->bOnlyLoadVisibleLevelsInPIE;
|
|
PlaySettings->PostEditChange();
|
|
PlaySettings->SaveConfig();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::OnIsOnlyLoadVisibleInPIEEnabled()
|
|
{
|
|
return GetDefault<ULevelEditorPlaySettings>()->bOnlyLoadVisibleLevelsInPIE;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnToggleSocketSnapping()
|
|
{
|
|
GEditor->bEnableSocketSnapping = !GEditor->bEnableSocketSnapping;
|
|
GEditor->RedrawLevelEditingViewports();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::OnIsSocketSnappingEnabled()
|
|
{
|
|
return GEditor->bEnableSocketSnapping;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnToggleParticleSystemLOD()
|
|
{
|
|
GEngine->bEnableEditorPSysRealtimeLOD = !GEngine->bEnableEditorPSysRealtimeLOD;
|
|
GEditor->RedrawLevelEditingViewports();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::OnIsParticleSystemLODEnabled()
|
|
{
|
|
return GEditor->bEnableEditorPSysRealtimeLOD;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnToggleFreezeParticleSimulation()
|
|
{
|
|
IConsoleManager& ConsoleManager = IConsoleManager::Get();
|
|
IConsoleVariable* CVar = ConsoleManager.FindConsoleVariable(TEXT("FX.FreezeParticleSimulation"));
|
|
if (CVar)
|
|
{
|
|
CVar->Set(CVar->GetInt() == 0 ? 1 : 0, ECVF_SetByConsole);
|
|
}
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::OnIsParticleSimulationFrozen()
|
|
{
|
|
IConsoleManager& ConsoleManager = IConsoleManager::Get();
|
|
static const auto* CVar = ConsoleManager.FindTConsoleVariableDataInt(TEXT("FX.FreezeParticleSimulation"));
|
|
if (CVar)
|
|
{
|
|
return CVar->GetValueOnGameThread() != 0;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnToggleParticleSystemHelpers()
|
|
{
|
|
GEditor->bDrawParticleHelpers = !GEditor->bDrawParticleHelpers;
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::OnIsParticleSystemHelpersEnabled()
|
|
{
|
|
return GEditor->bDrawParticleHelpers;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnToggleLODViewLocking()
|
|
{
|
|
GEditor->bEnableLODLocking = !GEditor->bEnableLODLocking;
|
|
GEditor->RedrawLevelEditingViewports();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::OnIsLODViewLockingEnabled()
|
|
{
|
|
return GEditor->bEnableLODLocking;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnToggleLevelStreamingVolumePrevis()
|
|
{
|
|
ULevelEditorViewportSettings* ViewportSettings = GetMutableDefault<ULevelEditorViewportSettings>();
|
|
|
|
ViewportSettings->bLevelStreamingVolumePrevis = !ViewportSettings->bLevelStreamingVolumePrevis;
|
|
ViewportSettings->PostEditChange();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::OnIsLevelStreamingVolumePrevisEnabled()
|
|
{
|
|
return GetDefault<ULevelEditorViewportSettings>()->bLevelStreamingVolumePrevis;
|
|
}
|
|
|
|
FText FLevelEditorActionCallbacks::GetAudioVolumeToolTip()
|
|
{
|
|
if ( !GEditor->IsRealTimeAudioMuted() )
|
|
{
|
|
const float Volume = GEditor->GetRealTimeAudioVolume() * 100.0f;
|
|
return FText::AsNumber( FMath::RoundToInt(Volume) );
|
|
}
|
|
return NSLOCTEXT("UnrealEd", "Muted", "Muted" );
|
|
}
|
|
|
|
float FLevelEditorActionCallbacks::GetAudioVolume()
|
|
{
|
|
return GEditor->GetRealTimeAudioVolume();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnAudioVolumeChanged(float Volume)
|
|
{
|
|
GEditor->SetRealTimeAudioVolume(Volume);
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::GetAudioMuted()
|
|
{
|
|
return GEditor->IsRealTimeAudioMuted();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnAudioMutedChanged(bool bMuted)
|
|
{
|
|
GEditor->MuteRealTimeAudio(bMuted);
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SnapObjectToView_Clicked()
|
|
{
|
|
const FScopedTransaction Transaction(NSLOCTEXT("UnrealEd", "SnapObjectToView", "Snap Object to View"));
|
|
for (FSelectionIterator It(GEditor->GetSelectedActorIterator()); It; ++It)
|
|
{
|
|
AActor* Actor = Cast<AActor>(*It);
|
|
Actor->Modify();
|
|
FVector Location = GCurrentLevelEditingViewportClient->GetViewLocation();
|
|
FRotator Rotation = GCurrentLevelEditingViewportClient->GetViewRotation();
|
|
|
|
Actor->SetActorLocation(Location);
|
|
Actor->SetActorRotation(Rotation);
|
|
}
|
|
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnEnableActorSnap()
|
|
{
|
|
FSnappingUtils::EnableActorSnap( !FSnappingUtils::IsSnapToActorEnabled() );
|
|
|
|
// If the setting is enabled and there's no distance, revert to default
|
|
if ( FSnappingUtils::IsSnapToActorEnabled() && FSnappingUtils::GetActorSnapDistance() == 0.0f )
|
|
{
|
|
FSnappingUtils::SetActorSnapDistance( 1.0f );
|
|
}
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::OnIsActorSnapEnabled()
|
|
{
|
|
return FSnappingUtils::IsSnapToActorEnabled();
|
|
}
|
|
|
|
|
|
void FLevelEditorActionCallbacks::OnEnableVertexSnap()
|
|
{
|
|
ULevelEditorViewportSettings* ViewportSettings = GetMutableDefault<ULevelEditorViewportSettings>();
|
|
ViewportSettings->bSnapVertices = !ViewportSettings->bSnapVertices;
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::OnIsVertexSnapEnabled()
|
|
{
|
|
return GetDefault<ULevelEditorViewportSettings>()->bSnapVertices;
|
|
}
|
|
|
|
FText FLevelEditorActionCallbacks::GetActorSnapTooltip()
|
|
{
|
|
// If the setting is enabled, return the distance, otherwise say disabled
|
|
if ( FSnappingUtils::IsSnapToActorEnabled() )
|
|
{
|
|
static const FNumberFormattingOptions FormatOptions = FNumberFormattingOptions()
|
|
.SetMinimumFractionalDigits(2)
|
|
.SetMaximumFractionalDigits(2);
|
|
return FText::AsNumber( FSnappingUtils::GetActorSnapDistance(), &FormatOptions );
|
|
}
|
|
return NSLOCTEXT("UnrealEd", "Disabled", "Disabled" );
|
|
}
|
|
|
|
float FLevelEditorActionCallbacks::GetActorSnapSetting()
|
|
{
|
|
// If the setting is enabled, return the distance, otherwise say 0
|
|
if (FSnappingUtils::IsSnapToActorEnabled() )
|
|
{
|
|
return FSnappingUtils::GetActorSnapDistance(true) ;
|
|
}
|
|
return 0.0f;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetActorSnapSetting(float Distance)
|
|
{
|
|
FSnappingUtils::SetActorSnapDistance( Distance );
|
|
|
|
// If the distance is 0, disable the setting until it's > 0
|
|
FSnappingUtils::EnableActorSnap( ( Distance > 0.0f ? true : false ) );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnToggleHideViewportUI()
|
|
{
|
|
GLevelEditorModeTools().SetHideViewportUI( !GLevelEditorModeTools().IsViewportUIHidden() );
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::IsViewportUIHidden()
|
|
{
|
|
return GLevelEditorModeTools().IsViewportUIHidden();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::IsEditorModeActive( FEditorModeID EditorMode )
|
|
{
|
|
return GLevelEditorModeTools().IsModeActive( EditorMode );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnAddVolume( UClass* VolumeClass )
|
|
{
|
|
GUnrealEd->Exec( GetWorld(), *FString::Printf( TEXT("BRUSH ADDVOLUME CLASS=%s"), *VolumeClass->GetName() ) );
|
|
|
|
// A new volume actor was added, update the volumes visibility.
|
|
// This volume should be hidden if the user doesn't have this type of volume visible.
|
|
GUnrealEd->UpdateVolumeActorVisibility( VolumeClass );
|
|
|
|
GEditor->RedrawAllViewports();
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::OnAddMatinee()
|
|
{
|
|
// Warn the user prior to creating our actor
|
|
if ( GEditor->ShouldOpenMatinee( NULL ) )
|
|
{
|
|
// Spawn a matinee actor at the origin, and either move infront of the camera or focus camera on it (depending on the viewport) and open for edit
|
|
UActorFactory* ActorFactory = GEditor->FindActorFactoryForActorClass( AMatineeActor::StaticClass() );
|
|
check( ActorFactory );
|
|
AMatineeActor* MatineeActor = CastChecked<AMatineeActor>( FLevelEditorActionCallbacks::AddActor( ActorFactory, FAssetData(), &FTransform::Identity ) );
|
|
if( GCurrentLevelEditingViewportClient->IsPerspective() )
|
|
{
|
|
GEditor->MoveActorInFrontOfCamera( *MatineeActor, GCurrentLevelEditingViewportClient->GetViewLocation(), GCurrentLevelEditingViewportClient->GetViewRotation().Vector() );
|
|
}
|
|
else
|
|
{
|
|
GEditor->MoveViewportCamerasToActor( *MatineeActor, false );
|
|
}
|
|
GEditor->OpenMatinee( MatineeActor, false );
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SelectActorsInLayers()
|
|
{
|
|
// Iterate over selected actors and make a list of all layers the selected actors belong to.
|
|
TArray< FName > SelectedLayers;
|
|
for ( FSelectionIterator It( GEditor->GetSelectedActorIterator() ) ; It ; ++It )
|
|
{
|
|
AActor* Actor = Cast<AActor>( *It );
|
|
|
|
// Add them to the list of selected layers.
|
|
for( int32 LayerIndex = 0 ; LayerIndex < Actor->Layers.Num() ; ++LayerIndex )
|
|
{
|
|
SelectedLayers.AddUnique( Actor->Layers[ LayerIndex ] );
|
|
}
|
|
}
|
|
|
|
bool bSelect = true;
|
|
bool bNotify = true;
|
|
GEditor->Layers->SelectActorsInLayers( SelectedLayers, bSelect, bNotify );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetWidgetMode( FWidget::EWidgetMode WidgetMode )
|
|
{
|
|
if( !GLevelEditorModeTools().IsTracking() )
|
|
{
|
|
GLevelEditorModeTools().SetWidgetMode( WidgetMode );
|
|
GEditor->RedrawAllViewports();
|
|
}
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::IsWidgetModeActive( FWidget::EWidgetMode WidgetMode )
|
|
{
|
|
return GLevelEditorModeTools().GetWidgetMode() == WidgetMode;
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::CanSetWidgetMode( FWidget::EWidgetMode WidgetMode )
|
|
{
|
|
return GLevelEditorModeTools().UsesTransformWidget(WidgetMode) == true;
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::IsTranslateRotateModeVisible()
|
|
{
|
|
return GetDefault<ULevelEditorViewportSettings>()->bAllowTranslateRotateZWidget;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SetCoordinateSystem( ECoordSystem CoordinateSystem )
|
|
{
|
|
GLevelEditorModeTools().SetCoordSystem( CoordinateSystem );
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::IsCoordinateSystemActive( ECoordSystem CoordinateSystem )
|
|
{
|
|
return GLevelEditorModeTools().GetCoordSystem() == CoordinateSystem;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::MoveActorToGrid_Clicked( bool InAlign, bool bInPerActor )
|
|
{
|
|
const FScopedTransaction Transaction( NSLOCTEXT("UnrealEd", "MoveActorToGrid", "Snap Origin to Grid") );
|
|
MoveActorTo_Clicked( InAlign, NULL, bInPerActor );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::MoveActorToActor_Clicked( bool InAlign )
|
|
{
|
|
AActor* Actor = GEditor->GetSelectedActors()->GetBottom<AActor>();
|
|
if( Actor )
|
|
{
|
|
const FScopedTransaction Transaction( NSLOCTEXT("UnrealEd", "MoveActorToActor", "Snap Origin to Actor") );
|
|
MoveActorTo_Clicked( InAlign, Actor );
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::MoveActorTo_Clicked( const bool InAlign, const AActor* InDestination/* = NULL*/, bool bInPerActor/* = false*/ )
|
|
{
|
|
// Fires ULevel::LevelDirtiedEvent when falling out of scope.
|
|
FScopedLevelDirtied LevelDirtyCallback;
|
|
|
|
// Update the pivot location.
|
|
FVector Delta = FVector::ZeroVector;
|
|
FVector NewLocation = FVector::ZeroVector;
|
|
FRotator NewRotation = FRotator::ZeroRotator;
|
|
|
|
if(!bInPerActor)
|
|
{
|
|
if ( InDestination )
|
|
{
|
|
NewLocation = InDestination->GetActorLocation();
|
|
NewRotation = InDestination->GetActorRotation();
|
|
GEditor->SetPivot( NewLocation, false, true );
|
|
}
|
|
else
|
|
{
|
|
const FVector OldPivot = GEditor->GetPivotLocation();
|
|
const FVector NewPivot = OldPivot.GridSnap(GEditor->GetGridSize());
|
|
Delta = NewPivot - OldPivot;
|
|
GEditor->SetPivot( NewPivot, false, true );
|
|
}
|
|
}
|
|
|
|
for ( FSelectionIterator It( GEditor->GetSelectedActorIterator() ) ; It ; ++It )
|
|
{
|
|
AActor* Actor = Cast<AActor>( *It );
|
|
checkSlow( Actor );
|
|
if ( Actor == InDestination ) // Early out
|
|
{
|
|
continue;
|
|
}
|
|
|
|
Actor->Modify();
|
|
|
|
if(!InDestination)
|
|
{
|
|
if ( bInPerActor )
|
|
{
|
|
const FVector OldPivot = Actor->GetActorLocation();
|
|
const FVector NewPivot = OldPivot.GridSnap(GEditor->GetGridSize());
|
|
Delta = NewPivot - OldPivot;
|
|
GEditor->SetPivot( NewPivot, false, true );
|
|
}
|
|
|
|
NewLocation = Actor->GetActorLocation() + Delta;
|
|
}
|
|
|
|
Actor->TeleportTo( NewLocation, ( !InAlign ? Actor->GetActorRotation() : NewRotation ), false, true );
|
|
Actor->InvalidateLightingCache();
|
|
Actor->UpdateComponentTransforms();
|
|
|
|
Actor->MarkPackageDirty();
|
|
LevelDirtyCallback.Request();
|
|
}
|
|
|
|
GEditor->RedrawLevelEditingViewports();
|
|
GEditor->RebuildAlteredBSP(); // Update the Bsp of any levels containing a modified brush
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SnapTo2DLayer_Clicked()
|
|
{
|
|
// Fires ULevel::LevelDirtiedEvent when falling out of scope.
|
|
FScopedLevelDirtied LevelDirtyCallback;
|
|
|
|
const ULevelEditorViewportSettings* ViewportSettings = GetDefault<ULevelEditorViewportSettings>();
|
|
const ULevelEditor2DSettings* Settings2D = GetDefault<ULevelEditor2DSettings>();
|
|
if (Settings2D->SnapLayers.IsValidIndex(ViewportSettings->ActiveSnapLayerIndex))
|
|
{
|
|
const FScopedTransaction Transaction(NSLOCTEXT("UnrealEd", "SnapSelection2D", "Snap Selection to 2D Layer"));
|
|
|
|
float SnapDepth = Settings2D->SnapLayers[ViewportSettings->ActiveSnapLayerIndex].Depth;
|
|
USelection* SelectedActors = GEditor->GetSelectedActors();
|
|
for (FSelectionIterator Iter(*SelectedActors); Iter; ++Iter)
|
|
{
|
|
AActor* Actor = CastChecked<AActor>(*Iter);
|
|
|
|
// Only snap actors that are not attached to something else
|
|
if (Actor->GetAttachParentActor() == nullptr)
|
|
{
|
|
FTransform Transform = Actor->GetTransform();
|
|
FVector CurrentLocation = Transform.GetLocation();
|
|
|
|
switch (Settings2D->SnapAxis)
|
|
{
|
|
case ELevelEditor2DAxis::X: CurrentLocation.X = SnapDepth; break;
|
|
case ELevelEditor2DAxis::Y: CurrentLocation.Y = SnapDepth; break;
|
|
case ELevelEditor2DAxis::Z: CurrentLocation.Z = SnapDepth; break;
|
|
}
|
|
|
|
Transform.SetLocation(CurrentLocation);
|
|
Actor->Modify();
|
|
Actor->SetActorTransform(Transform);
|
|
|
|
Actor->InvalidateLightingCache();
|
|
Actor->UpdateComponentTransforms();
|
|
|
|
Actor->MarkPackageDirty();
|
|
LevelDirtyCallback.Request();
|
|
}
|
|
}
|
|
|
|
GEditor->RedrawLevelEditingViewports(true);
|
|
GEditor->RebuildAlteredBSP();
|
|
}
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::CanSnapTo2DLayer()
|
|
{
|
|
const ULevelEditor2DSettings* Settings = GetDefault<ULevelEditor2DSettings>();
|
|
return Settings->SnapLayers.IsValidIndex(GetDefault<ULevelEditorViewportSettings>()->ActiveSnapLayerIndex) && (GEditor->GetSelectedActorCount() > 0);
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::MoveSelectionToDifferent2DLayer_Clicked(bool bGoingUp, bool bForceToTopOrBottom)
|
|
{
|
|
// Change the active layer first
|
|
const ULevelEditor2DSettings* Settings2D = GetDefault<ULevelEditor2DSettings>();
|
|
ULevelEditorViewportSettings* SettingsVP = GetMutableDefault<ULevelEditorViewportSettings>();
|
|
|
|
const int32 NumLayers = Settings2D->SnapLayers.Num();
|
|
|
|
if (NumLayers > 0)
|
|
{
|
|
if (bGoingUp && (SettingsVP->ActiveSnapLayerIndex > 0))
|
|
{
|
|
SettingsVP->ActiveSnapLayerIndex = bForceToTopOrBottom ? 0 : (SettingsVP->ActiveSnapLayerIndex - 1);
|
|
SettingsVP->PostEditChange();
|
|
}
|
|
else if (!bGoingUp && ((SettingsVP->ActiveSnapLayerIndex + 1) < NumLayers))
|
|
{
|
|
SettingsVP->ActiveSnapLayerIndex = bForceToTopOrBottom ? (NumLayers - 1) : (SettingsVP->ActiveSnapLayerIndex + 1);
|
|
SettingsVP->PostEditChange();
|
|
}
|
|
}
|
|
|
|
// Snap the selection to the new active layer
|
|
SnapTo2DLayer_Clicked();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::CanMoveSelectionToDifferent2DLayer(bool bGoingUp)
|
|
{
|
|
const ULevelEditor2DSettings* Settings2D = GetDefault<ULevelEditor2DSettings>();
|
|
const ULevelEditorViewportSettings* SettingsVP = GetMutableDefault<ULevelEditorViewportSettings>();
|
|
|
|
const int32 SelectedIndex = SettingsVP->ActiveSnapLayerIndex;
|
|
const int32 NumLayers = Settings2D->SnapLayers.Num();
|
|
|
|
const bool bHasLayerInDirection = bGoingUp ? (SelectedIndex > 0) : (SelectedIndex + 1 < NumLayers);
|
|
const bool bHasActorSelected = GEditor->GetSelectedActorCount() > 0;
|
|
|
|
// Allow it even if there is no layer in the corresponding direction, to let it double as a snap operation shortcut even when at the end stops
|
|
return bHasLayerInDirection || bHasActorSelected;
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::Select2DLayerDeltaAway_Clicked(int32 Delta)
|
|
{
|
|
const ULevelEditor2DSettings* Settings2D = GetDefault<ULevelEditor2DSettings>();
|
|
ULevelEditorViewportSettings* SettingsVP = GetMutableDefault<ULevelEditorViewportSettings>();
|
|
|
|
const int32 SelectedIndex = SettingsVP->ActiveSnapLayerIndex;
|
|
const int32 NumLayers = Settings2D->SnapLayers.Num();
|
|
|
|
if (NumLayers > 0)
|
|
{
|
|
const int32 NewIndex = ((NumLayers + SelectedIndex + Delta) % NumLayers);
|
|
|
|
SettingsVP->ActiveSnapLayerIndex = NewIndex;
|
|
SettingsVP->PostEditChange();
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SnapToFloor_Clicked( bool InAlign, bool InUseLineTrace, bool InUseBounds, bool InUsePivot )
|
|
{
|
|
const FScopedTransaction Transaction( NSLOCTEXT("UnrealEd", "SnapActorsToFloor", "Snap Actors To Floor") );
|
|
SnapTo_Clicked( InAlign, InUseLineTrace, InUseBounds, InUsePivot );
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SnapActorToActor_Clicked( bool InAlign, bool InUseLineTrace, bool InUseBounds, bool InUsePivot )
|
|
{
|
|
AActor* Actor = GEditor->GetSelectedActors()->GetBottom<AActor>();
|
|
if( Actor )
|
|
{
|
|
const FScopedTransaction Transaction( NSLOCTEXT("UnrealEd", "SnapActorsToActor", "Snap Actors To Actor") );
|
|
SnapTo_Clicked( InAlign, InUseLineTrace, InUseBounds, InUsePivot, Actor );
|
|
}
|
|
}
|
|
|
|
void FLevelEditorActionCallbacks::SnapTo_Clicked( const bool InAlign, const bool InUseLineTrace, const bool InUseBounds, const bool InUsePivot, AActor* InDestination )
|
|
{
|
|
// Fires ULevel::LevelDirtiedEvent when falling out of scope.
|
|
FScopedLevelDirtied LevelDirtyCallback;
|
|
|
|
bool bSnappedComponents = false;
|
|
if( GEditor->GetSelectedComponentCount() > 0 )
|
|
{
|
|
for(FSelectedEditableComponentIterator It(GEditor->GetSelectedEditableComponentIterator()); It; ++It)
|
|
{
|
|
USceneComponent* SceneComponent = Cast<USceneComponent>(*It);
|
|
if(SceneComponent)
|
|
{
|
|
SceneComponent->Modify();
|
|
AActor* ActorOwner = SceneComponent->GetOwner();
|
|
bSnappedComponents = true;
|
|
if(ActorOwner)
|
|
{
|
|
ActorOwner->Modify();
|
|
GEditor->SnapObjectTo(FActorOrComponent(SceneComponent), InAlign, InUseLineTrace, InUseBounds, InUsePivot, FActorOrComponent(InDestination));
|
|
ActorOwner->InvalidateLightingCache();
|
|
ActorOwner->UpdateComponentTransforms();
|
|
|
|
LevelDirtyCallback.Request();
|
|
}
|
|
}
|
|
}
|
|
|
|
USceneComponent* LastComp = GEditor->GetSelectedComponents()->GetBottom<USceneComponent>();
|
|
|
|
GEditor->SetPivot(LastComp->GetComponentLocation(), false, true);
|
|
}
|
|
|
|
if( !bSnappedComponents )
|
|
{
|
|
for(FSelectionIterator It(GEditor->GetSelectedActorIterator()); It; ++It)
|
|
{
|
|
AActor* Actor = Cast<AActor>(*It);
|
|
if(Actor)
|
|
{
|
|
Actor->Modify();
|
|
GEditor->SnapObjectTo(FActorOrComponent(Actor), InAlign, InUseLineTrace, InUseBounds, InUsePivot, FActorOrComponent(InDestination));
|
|
Actor->InvalidateLightingCache();
|
|
Actor->UpdateComponentTransforms();
|
|
|
|
LevelDirtyCallback.Request();
|
|
}
|
|
}
|
|
|
|
|
|
AActor* Actor = GEditor->GetSelectedActors()->GetBottom<AActor>();
|
|
if(Actor)
|
|
{
|
|
GEditor->SetPivot(Actor->GetActorLocation(), false, true);
|
|
|
|
if(UActorGroupingUtils::IsGroupingActive())
|
|
{
|
|
// set group pivot for the root-most group
|
|
AGroupActor* ActorGroupRoot = AGroupActor::GetRootForActor(Actor, true, true);
|
|
if(ActorGroupRoot)
|
|
{
|
|
ActorGroupRoot->CenterGroupLocation();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GEditor->RedrawLevelEditingViewports();
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::ActorSelected_CanExecute()
|
|
{
|
|
// Had to have something selected
|
|
return ( ( GEditor->GetSelectedActorCount() > 0 ) ? true : false );
|
|
}
|
|
|
|
bool FLevelEditorActionCallbacks::ActorsSelected_CanExecute()
|
|
{
|
|
// Has to have more than one selected
|
|
return ( ( GEditor->GetSelectedActorCount() > 1 ) ? true : false );
|
|
}
|
|
|
|
class UWorld* FLevelEditorActionCallbacks::GetWorld()
|
|
{
|
|
return GEditor->GetEditorWorldContext().World();
|
|
}
|
|
|
|
/** UI_COMMAND takes long for the compile to optimize */
|
|
PRAGMA_DISABLE_OPTIMIZATION
|
|
void FLevelEditorCommands::RegisterCommands()
|
|
{
|
|
UI_COMMAND( BrowseDocumentation, "Documentation...", "Opens the main documentation page, and allows you to search across all UE4 support sites.", EUserInterfaceActionType::Button, FInputChord( EKeys::F1 ) );
|
|
UI_COMMAND( BrowseAPIReference, "API Reference...", "Opens the API reference documentation", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( BrowseCVars, "Console Variables", "Creates an HTML file to browse the console variables and commands (console command 'help')", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( BrowseViewportControls, "Viewport Controls...", "Opens the viewport controls cheat sheet", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( NewLevel, "New Level...", "Create a new level, or choose a level template to start from.", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Control, EKeys::N ) );
|
|
UI_COMMAND( OpenLevel, "Open Level...", "Loads an existing level", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Control, EKeys::O ) );
|
|
UI_COMMAND( Save, "Save", "Saves the current level to disk", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SaveAs, "Save As...", "Save the current level as...", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Control|EModifierKey::Alt, EKeys::S ) );
|
|
UI_COMMAND( SaveAllLevels, "Save All Levels", "Saves all unsaved levels to disk", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( ToggleFavorite, "Toggle Favorite", "Sets whether the currently loaded level will appear in the list of favorite levels", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
for( int32 CurRecentIndex = 0; CurRecentIndex < FLevelEditorCommands::MaxRecentFiles; ++CurRecentIndex )
|
|
{
|
|
// NOTE: The actual label and tool-tip will be overridden at runtime when the command is bound to a menu item, however
|
|
// we still need to set one here so that the key bindings UI can function properly
|
|
TSharedRef< FUICommandInfo > OpenRecentFile =
|
|
FUICommandInfoDecl(
|
|
this->AsShared(),
|
|
FName( *FString::Printf( TEXT( "OpenRecentFile%i" ), CurRecentIndex ) ),
|
|
FText::Format( NSLOCTEXT( "LevelEditorCommands", "OpenRecentFile", "Open Recent File {0}" ), FText::AsNumber( CurRecentIndex ) ),
|
|
NSLOCTEXT( "LevelEditorCommands", "OpenRecentFileToolTip", "Opens a recently opened file" ) )
|
|
.UserInterfaceType( EUserInterfaceActionType::Button )
|
|
.DefaultChord( FInputChord() );
|
|
OpenRecentFileCommands.Add( OpenRecentFile );
|
|
}
|
|
|
|
UI_COMMAND( ImportScene, "Import Into Level...", "Imports a scene from a FBX or T3D format into the current level", EUserInterfaceActionType::Button, FInputChord());
|
|
UI_COMMAND( ExportAll, "Export All...", "Exports the entire level to a file on disk (multiple formats are supported.)", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( ExportSelected, "Export Selected...", "Exports currently-selected objects to a file on disk (multiple formats are supported.)", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( Build, "Build All Levels", "Builds all levels (precomputes lighting data and visibility data, generates navigation networks and updates brush models.)", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( BuildAndSubmitToSourceControl, "Build and Submit...", "Displays a window that allows you to build all levels and submit them to source control", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( BuildLightingOnly, "Build Lighting", "Only precomputes lighting (all levels.)", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Control|EModifierKey::Shift, EKeys::Semicolon) );
|
|
UI_COMMAND( BuildReflectionCapturesOnly, "Update Reflection Captures", "Only updates Reflection Captures (all levels.)", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( BuildLightingOnly_VisibilityOnly, "Precompute Static Visibility", "Only precomputes static visibility data (all levels.)", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( LightingBuildOptions_UseErrorColoring, "Use Error Coloring", "When enabled, errors during lighting precomputation will be baked as colors into light map data", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( LightingBuildOptions_ShowLightingStats, "Show Lighting Stats", "When enabled, a window containing metrics about lighting performance and memory will be displayed after a successful build.", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( BuildGeometryOnly, "Build Geometry", "Only builds geometry (all levels.)", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( BuildGeometryOnly_OnlyCurrentLevel, "Build Geometry (Current Level)", "Builds geometry, only for the current level", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( BuildPathsOnly, "Build Paths", "Only builds paths (all levels.)", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( BuildLODsOnly, "Build LODs", "Only builds LODs (all levels.)", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( BuildTextureStreamingOnly, "Build Texture Streaming", "Build texture streaming data", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( LightingQuality_Production, "Production", "Sets precomputed lighting quality to highest possible quality (slowest computation time.)", EUserInterfaceActionType::RadioButton, FInputChord() );
|
|
UI_COMMAND( LightingQuality_High, "High", "Sets precomputed lighting quality to high quality", EUserInterfaceActionType::RadioButton, FInputChord() );
|
|
UI_COMMAND( LightingQuality_Medium, "Medium", "Sets precomputed lighting quality to medium quality", EUserInterfaceActionType::RadioButton, FInputChord() );
|
|
UI_COMMAND( LightingQuality_Preview, "Preview", "Sets precomputed lighting quality to preview quality (fastest computation time.)", EUserInterfaceActionType::RadioButton, FInputChord() );
|
|
UI_COMMAND( LightingDensity_RenderGrayscale, "Render Grayscale", "Renders the lightmap density.", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( LightingResolution_CurrentLevel, "Current Level", "Adjust only primitives in the current level.", EUserInterfaceActionType::RadioButton, FInputChord() );
|
|
UI_COMMAND( LightingResolution_SelectedLevels, "Selected Levels", "Adjust only primitives in the selected levels.", EUserInterfaceActionType::RadioButton, FInputChord() );
|
|
UI_COMMAND( LightingResolution_AllLoadedLevels, "All Loaded Levels", "Adjust primitives in all loaded levels.", EUserInterfaceActionType::RadioButton, FInputChord() );
|
|
UI_COMMAND( LightingResolution_SelectedObjectsOnly, "Selected Objects Only", "Adjust only selected objects in the levels.", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( LightingStaticMeshInfo, "Lighting StaticMesh Info...", "Shows the lighting information for the StaticMeshes.", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SceneStats, "Open Scene Stats", "Opens the Scene Stats viewer", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( TextureStats, "Open Texture Stats", "Opens the Texture Stats viewer", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( MapCheck, "Open Map Check", "Checks map for errors", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( RecompileGameCode, "Recompile Game Code", "Recompiles and reloads C++ code for game systems on the fly", EUserInterfaceActionType::Button, FInputChord( EKeys::P, EModifierKey::Alt | EModifierKey::Control | EModifierKey::Shift ) );
|
|
|
|
UI_COMMAND( EditAsset, "Edit Asset", "Edits the asset associated with the selected actor", EUserInterfaceActionType::Button, FInputChord( EKeys::E, EModifierKey::Control ) );
|
|
UI_COMMAND( EditAssetNoConfirmMultiple, "Edit Asset", "Edits the asset associated with the selected actor", EUserInterfaceActionType::Button, FInputChord( EKeys::E, EModifierKey::Control | EModifierKey::Shift ) );
|
|
|
|
UI_COMMAND( GoHere, "Go Here", "Moves the camera to the current mouse position", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( SnapCameraToObject, "Snap View to Object", "Snaps the view to the selected object", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SnapObjectToCamera, "Snap Object to View", "Snaps the selected object to the view", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( GoToCodeForActor, "Go to C++ Code for Actor", "Opens a code editing IDE and navigates to the source file associated with the seleced actor", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( GoToDocsForActor, "Go to Documentation for Actor", "Opens documentation for the Actor in the default web browser", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( PasteHere, "Paste Here", "Pastes the actor at the click location", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( SnapOriginToGrid, "Snap Origin to Grid", "Snaps the actor to the nearest grid location at its origin", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Control, EKeys::End ) );
|
|
UI_COMMAND( SnapOriginToGridPerActor, "Snap Origin to Grid Per Actor", "Snaps each selected actor separately to the nearest grid location at its origin", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( AlignOriginToGrid, "Align Origin to Grid", "Aligns the actor to the nearest grid location at its origin", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( SnapTo2DLayer, "Snap to 2D Layer", "Snaps the actor to the current 2D snap layer", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Control, EKeys::SpaceBar ) );
|
|
UI_COMMAND( MoveSelectionUpIn2DLayers, "Bring selection forward a snap layer", "Bring selection forward a snap layer", EUserInterfaceActionType::Button, FInputChord(EKeys::PageUp, EModifierKey::Control) );
|
|
UI_COMMAND( MoveSelectionDownIn2DLayers, "Send selection backward a snap layer", "Send selection backward a snap layer", EUserInterfaceActionType::Button, FInputChord(EKeys::PageDown, EModifierKey::Control) );
|
|
UI_COMMAND( MoveSelectionToTop2DLayer, "Bring selection to the front snap layer", "Bring selection to the front snap layer", EUserInterfaceActionType::Button, FInputChord(EKeys::PageUp, EModifierKey::Shift | EModifierKey::Control) );
|
|
UI_COMMAND( MoveSelectionToBottom2DLayer, "Send selection to the back snap layer", "Send selection to the back snap layer", EUserInterfaceActionType::Button, FInputChord(EKeys::PageDown, EModifierKey::Shift | EModifierKey::Control) );
|
|
UI_COMMAND( Select2DLayerAbove, "Select next 2D layer", "Changes the active layer to the next 2D layer", EUserInterfaceActionType::Button, FInputChord(EKeys::PageUp, EModifierKey::Alt) );
|
|
UI_COMMAND( Select2DLayerBelow, "Select previous 2D layer", "Changes the active layer to the previous 2D layer", EUserInterfaceActionType::Button, FInputChord(EKeys::PageDown, EModifierKey::Alt) );
|
|
|
|
|
|
UI_COMMAND( SnapToFloor, "Snap to Floor", "Snaps the actor or component to the floor below it", EUserInterfaceActionType::Button, FInputChord( EKeys::End ) );
|
|
UI_COMMAND( AlignToFloor, "Align to Floor", "Aligns the actor or component with the floor", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SnapPivotToFloor, "Snap Pivot to Floor", "Snaps the actor to the floor at its pivot point", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Alt, EKeys::End ) );
|
|
UI_COMMAND( AlignPivotToFloor, "Align Pivot to Floor", "Aligns the actor with the floor at its pivot point", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SnapBottomCenterBoundsToFloor, "Snap Bottom Center Bounds to Floor", "Snaps the actor to the floor at its bottom center bounds", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Shift, EKeys::End ) );
|
|
UI_COMMAND( AlignBottomCenterBoundsToFloor, "Align Bottom Center Bounds to Floor", "Aligns the actor with the floor at its bottom center bounds", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SnapOriginToActor, "Snap Origin to Actor", "SNaps the actor to another actor at its origin", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( AlignOriginToActor, "Align Origin to Actor", "Aligns the actor to another actor at its origin", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SnapToActor, "Snap to Actor", "Snaps the actor to another actor", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( AlignToActor, "Align to Actor", "Aligns the actor with another actor", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SnapPivotToActor, "Snap Pivot to Actor", "Snaps the actor to another actor at its pivot point", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( AlignPivotToActor, "Align Pivot to Actor", "Aligns the actor with another actor at its pivot point", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SnapBottomCenterBoundsToActor, "Snap Bottom Center Bounds to Actor", "Snaps the actor to another actor at its bottom center bounds", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( AlignBottomCenterBoundsToActor, "Align Bottom Center Bounds to Actor", "Aligns the actor with another actor at its bottom center bounds", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( DeltaTransformToActors, "Delta Transform", "Apply Delta Transform to selected actors", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( MirrorActorX, "Mirror X", "Mirrors the actor along the X axis", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( MirrorActorY, "Mirror Y", "Mirrors the actor along the Y axis", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( MirrorActorZ, "Mirror Z", "Mirrors the actor along the Z axis", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( LockActorMovement, "Lock Actor Movement", "Locks the actor so it cannot be moved", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( DetachFromParent, "Detach", "Detach the actor from its parent", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( AttachSelectedActors, "Attach Selected Actors", "Attach the selected actors to the last selected actor", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Alt, EKeys::B) );
|
|
UI_COMMAND( AttachActorIteractive, "Attach Actor Interactive", "Start an interactive actor picker to let you choose a parent for the currently selected actor", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Alt, EKeys::A) );
|
|
UI_COMMAND( CreateNewOutlinerFolder, "Create Folder", "Place the selected actors in a new folder", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( HoldToEnableVertexSnapping, "Hold to Enable Vertex Snapping", "When the key binding is pressed and held vertex snapping will be enabled", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::V) );
|
|
|
|
//@ todo Slate better tooltips for pivot options
|
|
UI_COMMAND( SavePivotToPrePivot, "Set as Pivot Offset", "Sets the current pivot location as the pivot offset for this actor", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( ResetPrePivot, "Reset Pivot Offset", "Resets the pivot offset for this actor", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( ResetPivot, "Reset Pivot", "Resets the pivot", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( MovePivotHere, "Set Pivot Offset Here", "Sets the pivot offset to the clicked location", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( MovePivotHereSnapped, "Set Pivot Offset Here (Snapped)", "Sets the pivot offset to the nearest grid point to the clicked location", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( MovePivotToCenter, "Center on Selection", "Centers the pivot to the middle of the selection", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( ConvertToAdditive, "Additive", "Converts the selected brushes to additive brushes", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( ConvertToSubtractive, "Subtractive", "Converts the selected brushes to subtractive brushes", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( OrderFirst, "To First", "Changes the drawing order of the selected brushes so they are the first to draw", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( OrderLast, "To Last", "Changes the drawing order of the selected brushes so they are the last to draw", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( MakeSolid, "Solid", "Makes the selected brushes solid", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( MakeSemiSolid, "Semi-Solid", "Makes the selected brushes semi-solid", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( MakeNonSolid, "Non-Solid", "Makes the selected brushes non-solid", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( MergePolys, "Merge", "Merges multiple polygons on a brush face into as few as possible", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SeparatePolys, "Separate", "Reverses the effect of a previous merge", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
// RegroupActors uses GroupActors for it's label and tooltip when simply grouping a selection of actors using overrides. This is to provide display of the chord which is the same for both.
|
|
UI_COMMAND( GroupActors, "Group", "Groups the selected actors", EUserInterfaceActionType::Button, FInputChord( /*EKeys::G, EModifierKey::Control*/ ) );
|
|
UI_COMMAND( RegroupActors, "Regroup", "Regroups the selected actors into a new group, removing any current groups in the selection", EUserInterfaceActionType::Button, FInputChord( EKeys::G, EModifierKey::Control ) );
|
|
UI_COMMAND( UngroupActors, "Ungroup", "Ungroups the selected actors", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Shift, EKeys::G ) );
|
|
UI_COMMAND( AddActorsToGroup, "Add to Group", "Adds the selected actors to the selected group", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( RemoveActorsFromGroup, "Remove from Group", "Removes the selected actors from the selected groups", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( LockGroup, "Lock", "Locks the selected groups", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( UnlockGroup, "Unlock", "Unlocks the selected groups", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
#if PLATFORM_MAC
|
|
UI_COMMAND( ShowAll, "Show All Actors", "Shows all actors", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Command, EKeys::H ) );
|
|
#else
|
|
UI_COMMAND( ShowAll, "Show All Actors", "Shows all actors", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Control, EKeys::H ) );
|
|
#endif
|
|
UI_COMMAND( ShowSelectedOnly, "Show Only Selected", "Shows only the selected actors", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( ShowSelected, "Show Selected", "Shows the selected actors", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Shift, EKeys::H ) );
|
|
UI_COMMAND( HideSelected, "Hide Selected", "Hides the selected actors", EUserInterfaceActionType::Button, FInputChord( EKeys::H ) );
|
|
UI_COMMAND( ShowAllStartup, "Show All At Startup", "Shows all actors at startup", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( ShowSelectedStartup, "Show Selected At Startup", "Shows selected actors at startup", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( HideSelectedStartup, "Hide Selected At Startup", "Hide selected actors at startup", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( CycleNavigationDataDrawn, "Cycle Navigation Data Drawn", "Cycles through navigation data (navmeshes for example) to draw one at a time", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Alt, EKeys::N ) );
|
|
|
|
UI_COMMAND( SelectNone, "Unselect All", "Unselects all actors", EUserInterfaceActionType::Button, FInputChord( EKeys::Escape ) ) ;
|
|
UI_COMMAND( InvertSelection, "Invert Selection", "Inverts the current selection", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( SelectAllActorsOfSameClass, "Select All Actors of Same Class", "Selects all the actors that have the same class", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Shift|EModifierKey::Control, EKeys::A) );
|
|
UI_COMMAND( SelectAllActorsOfSameClassWithArchetype, "Select All Actors with Same Archetype", "Selects all the actors of the same class that have the same archetype", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SelectComponentOwnerActor, "Select Component Owner", "Select the actor that owns the currently selected component(s)", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SelectRelevantLights, "Select Relevant Lights", "Select all lights relevant to the current selection", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SelectStaticMeshesOfSameClass, "Select All Using Selected Static Meshes (Selected Actor Types)", "Selects all actors with the same static mesh and actor class as the selection", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SelectOwningHierarchicalLODCluster, "Select Owning Hierarchical LOD cluster Using Selected Static Mesh (Selected Actor Types)", "Select Owning Hierarchical LOD cluster for the selected actor", EUserInterfaceActionType::Button, FInputChord());
|
|
UI_COMMAND( SelectStaticMeshesAllClasses, "Select All Using Selected Static Meshes (All Actor Types)", "Selects all actors with the same static mesh as the selection", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Shift, EKeys::E ) );
|
|
UI_COMMAND( SelectSkeletalMeshesOfSameClass, "Select All Using Selected Skeletal Meshes (Selected Actor Types)", "Selects all actors with the same skeletal mesh and actor class as the selection", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SelectSkeletalMeshesAllClasses, "Select All Using Selected Skeletal Meshes (All Actor Types)", "Selects all actors with the same skeletal mesh as the selection", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SelectAllWithSameMaterial, "Select All With Same Material", "Selects all actors with the same material as the selection", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SelectMatchingEmitter, "Select All Matching Emitters", "Selects all emitters with the same particle system as the selection", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SelectAllLights, "Select All Lights", "Selects all lights", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SelectStationaryLightsExceedingOverlap, "Select Stationary Lights exceeding overlap", "Selects all stationary lights exceeding the overlap limit", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SelectAllAddditiveBrushes, "Select All Additive Brushes", "Selects all additive brushes", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SelectAllSubtractiveBrushes, "Select All Subtractive Brushes", "Selects all subtractive brushes", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SelectAllActorsControlledByMatinee, "Select Actors Used by This Matinee", "Selects all actors controlled by this Matinee", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( SelectAllSurfaces, "Select All Surfaces", "Selects all bsp surfaces", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Shift, EKeys::S) );
|
|
|
|
UI_COMMAND( SurfSelectAllMatchingBrush, "Select Matching Brush", "Selects the surfaces belonging to the same brush as the selected surfaces", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Shift, EKeys::B) );
|
|
UI_COMMAND( SurfSelectAllMatchingTexture, "Select Matching Material", "Selects all surfaces with the same material as the selected surfaces", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Shift, EKeys::T) );
|
|
UI_COMMAND( SurfSelectAllAdjacents, "Select All Adjacent Surfaces", "Selects all surfaces adjacent to the currently selected surfaces", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Shift, EKeys::J) );
|
|
UI_COMMAND( SurfSelectAllAdjacentCoplanars, "Select All Coplanar Surfaces", "Selects all surfaces adjacent and coplanar with the selected surfaces", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Shift, EKeys::C) );
|
|
UI_COMMAND( SurfSelectAllAdjacentWalls, "Select All Adjacent Wall Surfaces", "Selects all adjacent upright surfaces", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Shift, EKeys::W) );
|
|
UI_COMMAND( SurfSelectAllAdjacentFloors, "Select All Adjacent Floor Surfaces", "Selects all adjacent floor sufaces(ones with normals pointing up)", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Shift, EKeys::U) );
|
|
UI_COMMAND( SurfSelectAllAdjacentSlants, "Select All Adjacent Slant Surfaces", "Selects all adjacent slant surfaces (surfaces that are not walls, floors, or ceilings according to their normals) to the currently selected surfaces.", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Shift, EKeys::Y) );
|
|
UI_COMMAND( SurfSelectReverse, "Invert Surface Selection", "Inverts the current surface selection", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Shift, EKeys::Q) );
|
|
UI_COMMAND( SurfSelectMemorize, "Memorize Surface Selection", "Stores the current surface selection in memory", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Shift, EKeys::M) );
|
|
UI_COMMAND( SurfSelectRecall, "Recall Surface Selection", "Replace the current selection with the selection saved in memory", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Shift, EKeys::R) );
|
|
UI_COMMAND( SurfSelectOr, "Surface Selection OR", "Replace the current selection with only the surfaces which are both currently selected and contained within the saved selection in memory", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Shift, EKeys::O) );
|
|
UI_COMMAND( SurfSelectAnd, "Surface Selection AND", "Add the selection of surfaces saved in memory to the current selection", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Shift, EKeys::A) );
|
|
UI_COMMAND( SurfSelectXor, "Surace Selection XOR", " Replace the current selection with only the surfaces that are not in both the current selection and the selection saved in memory", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Shift, EKeys::X) );
|
|
UI_COMMAND( SurfUnalign, "Align Surface Default", "Default surface alignment", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SurfAlignPlanarAuto, "Align Surface Planar", "Planar surface alignment", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SurfAlignPlanarWall, "Align Surface Planar Wall", "Planar wall surface alignment", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SurfAlignPlanarFloor, "Align Surface Planar Floor", "Planar floor surface alignment", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SurfAlignBox, "Align Surface Box", "Box surface alignment", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( SurfAlignFit, "Align Surface Fit", "Best fit surface alignment", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( ApplyMaterialToSurface, "Apply Material to Surface Selection", "Applies the selected material to the selected surfaces", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( CreateBoundingBoxVolume, "Create Bounding Box Blocking Volume From Mesh", "Create a bounding box blocking volume from the static mesh", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( CreateHeavyConvexVolume, "Heavy Convex Blocking Volume From Mesh", "Creates a heavy convex blocking volume from the static mesh", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( CreateNormalConvexVolume, "Normal Convex Blocking Volume From Mesh", "Creates a normal convex blocking volume from the static mesh", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( CreateLightConvexVolume, "Light Convex Blocking Volume From Mesh", "Creates a light convex blocking volume from the static mesh", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( CreateRoughConvexVolume, "Rought Convex Blocking Volume From Mesh", "Creates a rough convex blocking volume from the static mesh", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( KeepSimulationChanges, "Keep Simulation Changes", "Saves the changes made to this actor in Simulate mode to the actor's default state.", EUserInterfaceActionType::Button, FInputChord( EKeys::K ) );
|
|
|
|
UI_COMMAND( MakeActorLevelCurrent, "Make Selected Actor's Level Current", "Makes the selected actor's level the current level", EUserInterfaceActionType::Button, FInputChord( EKeys::M ) );
|
|
#if PLATFORM_MAC
|
|
UI_COMMAND( MoveSelectedToCurrentLevel, "Move Selection to Current Level", "Moves the selected actors to the current level", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Command, EKeys::M ) );
|
|
#else
|
|
UI_COMMAND( MoveSelectedToCurrentLevel, "Move Selection to Current Level", "Moves the selected actors to the current level", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Control, EKeys::M ) );
|
|
#endif
|
|
UI_COMMAND( FindActorLevelInContentBrowser, "Find Actor Level in Content Browser", "Finds the selected actors' level in the content browser", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( FindLevelsInLevelBrowser, "Find Levels in Level Browser", "Finds the selected actors' levels in the level browser", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( AddLevelsToSelection, "Add Levels to Selection", "Adds the selected actors' levels to the current level browser selection", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( RemoveLevelsFromSelection, "Remove Levels from Selection", "Removes the selected actors' levels from the current level browser selection", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( FindActorInLevelScript, "Find in Level Blueprint", "Finds any references to the selected actor in its level's blueprint", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( WorldProperties, "World Settings", "Displays the world settings", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( OpenContentBrowser, "Open Content Browser", "Opens the Content Browser", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Control|EModifierKey::Shift, EKeys::F) );
|
|
UI_COMMAND( OpenMarketplace, "Open Marketplace", "Opens the Marketplace", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( AddMatinee, "Add Matinee [Legacy]", "Creates a new matinee actor to edit", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( EditMatinee, "Edit Matinee", "Selects a Matinee to edit", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( ToggleVR, "Toggle VR", "Toggles VR (Virtual Reality) mode", EUserInterfaceActionType::ToggleButton, FInputChord( EModifierKey::Alt, EKeys::Tilde ) );
|
|
|
|
UI_COMMAND( OpenLevelBlueprint, "Open Level Blueprint", "Edit the Level Blueprint for the current level", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( CheckOutProjectSettingsConfig, "Check Out", "Checks out the project settings config file so the game mode can be set.", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( CreateBlankBlueprintClass, "New Empty Blueprint Class...", "Create a new Blueprint Class", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( ConvertSelectionToBlueprintViaHarvest, "Convert Selected Components to Blueprint Class...", "Replace all of the selected actors with a new Blueprint Class based on Actor that contains the components", EUserInterfaceActionType::Button, FInputChord() );
|
|
UI_COMMAND( ConvertSelectionToBlueprintViaSubclass, "Convert Selected Actor to Blueprint Class...", "Replace the selected actor with a new Blueprint subclass based on the class of the selected Actor", EUserInterfaceActionType::Button, FInputChord() );
|
|
|
|
UI_COMMAND( ShowTransformWidget, "Show Transform Widget", "Toggles the visibility of the transform widgets", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( AllowTranslucentSelection, "Allow Translucent Selection", "Allows translucent objects to be selected", EUserInterfaceActionType::ToggleButton, FInputChord(EKeys::T) );
|
|
UI_COMMAND( AllowGroupSelection, "Allow Group Selection", "Allows actor groups to be selected", EUserInterfaceActionType::ToggleButton, FInputChord(EModifierKey::Control|EModifierKey::Shift, EKeys::G) );
|
|
UI_COMMAND( StrictBoxSelect, "Strict Box Selection", "When enabled an object must be entirely encompassed by the selection box when marquee box selecting", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( TransparentBoxSelect, "Box Select Occluded Objects", "When enabled, marquee box select operations will also select objects that are occluded by other objects.", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( DrawBrushMarkerPolys, "Draw Brush Polys", "Draws semi-transparent polygons around a brush when selected", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( OnlyLoadVisibleInPIE, "Only Load Visible Levels in Game Preview", "If enabled, when game preview starts, only visible levels will be loaded", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( ToggleSocketSnapping, "Enable Socket Snapping", "Enables or disables snapping to sockets", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( ToggleParticleSystemLOD, "Enable Particle System LOD Switching", "If enabled particle systems will use distance LOD switching in perspective viewports", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( ToggleFreezeParticleSimulation, "Freeze Particle Simulation", "If enabled particle systems will freeze their simulation state", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( ToggleParticleSystemHelpers, "Toggle Particle System Helpers", "Toggles showing particle system helper widgets in viewports", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( ToggleLODViewLocking, "Enable LOD View Locking", "If enabled viewports of the same type will use the same LOD", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( LevelStreamingVolumePrevis, "Enable Automatic Level Streaming", "If enabled, the viewport will stream in levels automatically when the camera is moved", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( EnableActorSnap, "Enable Actor Snapping", "If enabled, actors will snap to the location of other actors when they are within distance", EUserInterfaceActionType::ToggleButton, FInputChord(EModifierKey::Control|EModifierKey::Shift, EKeys::K) );
|
|
UI_COMMAND( EnableVertexSnap, "Enable Vertex Snapping","If enabled, actors will snap to the location of the nearest vertex on another actor in the direction of movement", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
UI_COMMAND( ToggleHideViewportUI, "Hide Viewport UI", "Toggles hidden viewport UI mode. Hides all overlaid viewport UI widgets", EUserInterfaceActionType::ToggleButton, FInputChord() );
|
|
|
|
//if (FParse::Param( FCommandLine::Get(), TEXT( "editortoolbox" ) ))
|
|
//{
|
|
// UI_COMMAND( BspMode, "Enable Bsp Mode", "Enables BSP mode", EUserInterfaceActionType::ToggleButton, FInputChord( EModifierKey::Shift, EKeys::One ) );
|
|
// UI_COMMAND( MeshPaintMode, "Enable Mesh Paint Mode", "Enables mesh paint mode", EUserInterfaceActionType::ToggleButton, FInputChord( EModifierKey::Shift, EKeys::Two ) );
|
|
// UI_COMMAND( LandscapeMode, "Enable Landscape Mode", "Enables landscape editing", EUserInterfaceActionType::ToggleButton, FInputChord( EModifierKey::Shift, EKeys::Three ) );
|
|
// UI_COMMAND( FoliageMode, "Enable Foliage Mode", "Enables foliage editing", EUserInterfaceActionType::ToggleButton, FInputChord( EModifierKey::Shift, EKeys::Four ) );
|
|
//}
|
|
|
|
UI_COMMAND( ShowSelectedDetails, "Show Actor Details", "Opens a details panel for the selected actors", EUserInterfaceActionType::Button, FInputChord( EKeys::F4 ) );
|
|
|
|
UI_COMMAND( RecompileShaders, "Recompile Changed Shaders", "Recompiles shaders which are out of date", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Shift|EModifierKey::Control, EKeys::Period ) );
|
|
UI_COMMAND( ProfileGPU, "Profile GPU", "Profiles the GPU for the next frame and opens a window with profiled data", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Shift|EModifierKey::Control, EKeys::Comma ) );
|
|
|
|
UI_COMMAND( ResetAllParticleSystems, "Reset All Particle Systems", "Resets all particle system emitters (removes all active particles and restarts them)", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Shift, EKeys::Slash ) );
|
|
UI_COMMAND( ResetSelectedParticleSystem, "Resets Selected Particle Systems" , "Resets selected particle system emitters (removes all active particles and restarts them)", EUserInterfaceActionType::Button, FInputChord( EKeys::Slash ) );
|
|
|
|
UI_COMMAND( SelectActorsInLayers, "Select all actors in selected actor's layers", "Selects all actors belonging to the layers of the currently selected actors", EUserInterfaceActionType::Button, FInputChord( EModifierKey::Control, EKeys::L ) );
|
|
|
|
UI_COMMAND( FocusAllViewportsToSelection, "Focus Selected Actors in All Viewports", "Moves the camera in front of the selected actors in all open viewports", EUserInterfaceActionType::Button, FInputChord( EKeys::F, EModifierKey::Shift ) );
|
|
|
|
UI_COMMAND(MaterialQualityLevel_Low, "Low", "Sets material quality in the scene to low.", EUserInterfaceActionType::RadioButton, FInputChord());
|
|
UI_COMMAND(MaterialQualityLevel_Medium, "Medium", "Sets material quality in the scene to medium.", EUserInterfaceActionType::RadioButton, FInputChord());
|
|
UI_COMMAND(MaterialQualityLevel_High, "High", "Sets material quality in the scene to high.", EUserInterfaceActionType::RadioButton, FInputChord());
|
|
|
|
UI_COMMAND(PreviewPlatformOverride_DefaultES2, "Default Mobile / HTML5 Preview", "Use default mobile settings (no quality overrides).", EUserInterfaceActionType::RadioButton, FInputChord());
|
|
UI_COMMAND(PreviewPlatformOverride_AndroidGLES2, "Android Preview", "Mobile preview using Android's quality settings.", EUserInterfaceActionType::RadioButton, FInputChord());
|
|
UI_COMMAND(PreviewPlatformOverride_IOSGLES2, "iOS ES2 Preview", "Mobile preview using iOS's OpenGL ES2 quality settings.", EUserInterfaceActionType::RadioButton, FInputChord());
|
|
|
|
UI_COMMAND(PreviewPlatformOverride_DefaultES31, "Default High-End Mobile", "Use default mobile settings (no quality overrides).", EUserInterfaceActionType::RadioButton, FInputChord());
|
|
UI_COMMAND(PreviewPlatformOverride_AndroidGLES31, "Android GLES3.1 Preview", "Mobile preview using Android ES3.1 quality settings.", EUserInterfaceActionType::RadioButton, FInputChord());
|
|
UI_COMMAND(PreviewPlatformOverride_AndroidVulkanES31, "Android Vulkan Preview", "Mobile preview using Android Vulkan quality settings.", EUserInterfaceActionType::RadioButton, FInputChord());
|
|
UI_COMMAND(PreviewPlatformOverride_IOSMetalES31, "iOS Metal Preview", "Mobile preview using iOS Metal quality settings.", EUserInterfaceActionType::RadioButton, FInputChord());
|
|
|
|
|
|
UI_COMMAND( ConnectToSourceControl, "Connect to Source Control...", "Opens a dialog to connect to source control.", EUserInterfaceActionType::Button, FInputChord());
|
|
UI_COMMAND( ChangeSourceControlSettings, "Change Source Control Settings...", "Opens a dialog to change source control settings.", EUserInterfaceActionType::Button, FInputChord());
|
|
UI_COMMAND( CheckOutModifiedFiles, "Check Out Modified Files...", "Opens a dialog to check out any assets which have been modified.", EUserInterfaceActionType::Button, FInputChord());
|
|
UI_COMMAND( SubmitToSourceControl, "Submit to Source Control...", "Opens a dialog with check in options for content and levels.", EUserInterfaceActionType::Button, FInputChord());
|
|
|
|
static const FText FeatureLevelLabels[ERHIFeatureLevel::Num] =
|
|
{
|
|
NSLOCTEXT("LevelEditorCommands", "FeatureLevelPreviewType_ES2", "Mobile / HTML5"),
|
|
NSLOCTEXT("LevelEditorCommands", "FeatureLevelPreviewType_ES31", "High-End Mobile / Metal"),
|
|
NSLOCTEXT("LevelEditorCommands", "FeatureLevelPreviewType_SM4", "Shader Model 4"),
|
|
NSLOCTEXT("LevelEditorCommands", "FeatureLevelPreviewType_SM5", "Shader Model 5"),
|
|
};
|
|
|
|
static const FText FeatureLevelToolTips[ERHIFeatureLevel::Num] =
|
|
{
|
|
NSLOCTEXT("LevelEditorCommands", "FeatureLevelPreviewTooltip_ES2", "OpenGLES 2"),
|
|
NSLOCTEXT("LevelEditorCommands", "FeatureLevelPreviewTooltip_ES3", "OpenGLES 3.1, Metal"),
|
|
NSLOCTEXT("LevelEditorCommands", "FeatureLevelPreviewTooltip_SM4", "DirectX 10, OpenGL 3.3+"),
|
|
NSLOCTEXT("LevelEditorCommands", "FeatureLevelPreviewTooltip_SM5", "DirectX 11, OpenGL 4.3+, PS4, XB1"),
|
|
};
|
|
|
|
for (int32 i = 0; i < ERHIFeatureLevel::Num; ++i)
|
|
{
|
|
FName Name;
|
|
GetFeatureLevelName((ERHIFeatureLevel::Type)i, Name);
|
|
|
|
FeatureLevelPreview[i] =
|
|
FUICommandInfoDecl(
|
|
this->AsShared(),
|
|
Name,
|
|
FeatureLevelLabels[i],
|
|
FeatureLevelToolTips[i])
|
|
.UserInterfaceType(EUserInterfaceActionType::RadioButton)
|
|
.DefaultChord(FInputChord());
|
|
}
|
|
|
|
UI_COMMAND(OpenMergeActor, "Merge Actors", "Opens the Merge Actor panel", EUserInterfaceActionType::Button, FInputChord());
|
|
}
|
|
|
|
PRAGMA_ENABLE_OPTIMIZATION
|
|
|
|
#undef LOCTEXT_NAMESPACE
|