Compare commits

...

320 Commits

Author SHA1 Message Date
mafiesto4 b3a18883ca Fix iOS startup 2023-11-25 21:46:22 +01:00
mafiesto4 98b42d3e2e Add .NET SDK version 7 as forced to be used during game cooking (compatibility with) 2023-11-25 18:14:21 +01:00
mafiesto4 71f30f18a6 Add support for including global configs in engine configuration options 2023-11-25 18:08:34 +01:00
mafiesto4 9e74f3ae22 Update engine assets 2023-11-25 17:54:50 +01:00
mafiesto4 f4f49f63bc Remove debug logs from 3fc0a3dc84 2023-11-25 14:19:30 +01:00
mafiesto4 eaabd56cae Add manual dotnet versions search on windows 2023-11-25 13:03:22 +01:00
mafiesto4 3fc0a3dc84 Add test debug log for broken ci build debug 2023-11-25 12:46:21 +01:00
mafiesto4 cf155a4df4 Update build scripts to use .NET SDK 7 for engine 2023-11-25 12:20:42 +01:00
mafiesto4 40d6e18e7e Add -dotnet=ver command arg to Flax.Build to specify .NET SDK version to use for build 2023-11-25 12:16:13 +01:00
mafiesto4 2cef368282 Update missing unmanaged function callback error message 2023-11-24 21:45:59 +01:00
mafiesto4 40d8d3b972 Update build number 2023-11-24 17:54:44 +01:00
mafiesto4 6eb738bc58 Merge branch 'HydrogenC-master' 2023-11-24 15:00:39 +01:00
mafiesto4 91629d7a28 Merge branch 'master' of https://github.com/HydrogenC/FlaxEngine into HydrogenC-master 2023-11-24 15:00:34 +01:00
mafiesto4 cfef59d851 Merge branch 'nothingTVatYT-master' 2023-11-24 15:00:25 +01:00
mafiesto4 5f3fc38de2 Merge branch 'master' of https://github.com/nothingTVatYT/FlaxEngine into nothingTVatYT-master 2023-11-24 15:00:21 +01:00
mafiesto4 49bc7d3dcc Fix BehaviorTree node UI after adding decorator that was already there 2023-11-24 14:59:25 +01:00
mafiesto4 d0f7a04c58 Add support for getter-only properties in blackboard selector access 2023-11-24 14:59:07 +01:00
nothingTVatYT 297cdc5bfd Merge branch 'FlaxEngine:master' into master 2023-11-24 11:28:58 +01:00
mafiesto4 f61f35b259 Fix compilation regression 2023-11-24 10:53:07 +01:00
mafiesto4 aa1b779463 Fix Win32CriticalSection to use spin count of 4000 instead of just 100
#1930
2023-11-24 10:25:46 +01:00
mafiesto4 359d4ba8ef More refactoring to 6cf7d49a10 for better assets loading
#1930
2023-11-24 10:25:21 +01:00
mafiesto4 6cf7d49a10 Fix crash during asset loading due to potential threading issue when 2 threads load the same asset
#1930
2023-11-23 17:54:50 +01:00
mafiesto4 d5075d845c Fix content storage usage with relative paths
#1966
2023-11-23 17:37:55 +01:00
mafiesto4 d99a92fd13 Fix generic types including to be recursive in C++ bindings codegen
#1966
2023-11-23 13:46:43 +01:00
ExMatics HydrogenC 5b7a3f9700 Show skeleton when entering skeleton tab 2023-11-22 21:52:07 +08:00
mafiesto4 eba4b9bcc1 Add immediate game viewport sync after aspect ratio change in Editor 2023-11-21 12:34:31 +01:00
mafiesto4 d01990e3bb Fix deadlock in editor when using snap to the group with actor that has empty bounds
#1971
2023-11-21 12:34:06 +01:00
mafiesto4 0db259e300 Add CustomScenes feature to draw a fixed set of scenes within SceneRenderTask 2023-11-21 12:24:55 +01:00
mafiesto4 ce905fbe86 Merge branch 'HydrogenC-master' 2023-11-21 11:27:25 +01:00
mafiesto4 5fb82dd290 Merge branch 'master' of https://github.com/HydrogenC/FlaxEngine into HydrogenC-master 2023-11-21 11:27:18 +01:00
mafiesto4 ea81ac6a71 Fix crash in Multi Blend 2D node in Anim Graph when using single animation on a triangle 2023-11-21 11:10:05 +01:00
mafiesto4 88f751eda7 Merge branch 'Tryibion-submod' 2023-11-21 10:04:38 +01:00
mafiesto4 33115fca0c Merge branch 'submod' of https://github.com/Tryibion/FlaxEngine into Tryibion-submod 2023-11-21 10:04:32 +01:00
mafiesto4 4e37aafe6a Fix BT logic flow when start/stopping behavior 2023-11-21 00:01:46 +01:00
mafiesto4 9a091799fc Fix crash when debugging BT node state while tree is not running 2023-11-21 00:00:43 +01:00
Tryibion b14d88f8f8 Add git submodule init to git cloning. 2023-11-20 07:31:16 -06:00
nothingTVatYT da0dc7f11c Merge branch 'FlaxEngine:master' into master 2023-11-20 11:46:53 +01:00
mafiesto4 98012eb192 Minor improvements 2023-11-20 11:07:45 +01:00
mafiesto4 e9a1be481f Add short delay before auto-selecting editor tab on drag over header
#1934
2023-11-20 11:03:49 +01:00
mafiesto4 5573f5bb4a Merge branch 'GoaLitiuM-dotnet8_validate' 2023-11-20 10:48:35 +01:00
mafiesto4 822c25af7d Merge branch 'dotnet8_validate' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-dotnet8_validate 2023-11-20 10:48:27 +01:00
mafiesto4 70a540da4a Refactor main editor viewport and prefab viewport to share dragging handling code 2023-11-20 10:48:16 +01:00
mafiesto4 201a1f0264 Fix PostFx settings in Graphics Settings to be only used when checked as override 2023-11-19 22:10:11 +01:00
mafiesto4 9aa4421bfd Fix Visual Script parameter setter node to accept multiple input flows 2023-11-19 20:41:24 +01:00
mafiesto4 d90a0aa3f4 Fix missing initialization of scene objects added from prefab
#1924
2023-11-19 20:26:14 +01:00
mafiesto4 fc2d9a745f Fix missing scene dirty state when spawning prefab in scene tree 2023-11-19 20:24:47 +01:00
mafiesto4 4e190c2e3c Add decoding stack trace function names on Apple platforms 2023-11-19 18:04:24 +01:00
nothingTVatYT 6dcfe32979 Merge branch 'FlaxEngine:master' into master 2023-11-19 12:38:03 +01:00
mafiesto4 389bf89e2a Add GetStackFrames on Android 2023-11-19 11:07:44 +01:00
mafiesto4 31aafeb0d1 Add GetStackFrames and IsDebuggerPresent on Linux 2023-11-19 11:04:10 +01:00
mafiesto4 f9799f8ef3 Update old code 2023-11-19 11:00:15 +01:00
GoaLitiuM 017e7cbc60 Validate detected .NET SDK/runtime versions 2023-11-19 11:26:43 +02:00
GoaLitiuM 4eaac4ab2f Fix building Flax.Build with .NET 8 SDK 2023-11-19 11:26:40 +02:00
ExMatics HydrogenC ddcb792767 Improve documentation 2023-11-19 17:07:42 +08:00
ExMatics HydrogenC 8bcb984180 Implement SetNodeTransform 2023-11-19 17:02:07 +08:00
nothingTVatYT 038a4e6f90 Merge branch 'FlaxEngine:master' into master 2023-11-19 00:44:50 +01:00
mafiesto4 3799674b83 Merge branch 'Tryibion-hide-certain-ui' 2023-11-19 00:00:22 +01:00
mafiesto4 25246de791 Merge branch 'hide-certain-ui' of https://github.com/Tryibion/FlaxEngine into Tryibion-hide-certain-ui 2023-11-19 00:00:10 +01:00
mafiesto4 e76fffc95a Improve performance of 06c56d0a4b 2023-11-18 23:59:30 +01:00
mafiesto4 06c56d0a4b Fix bug when spawning new prefab objects during scene load due to regression in async scene init 2023-11-18 23:46:42 +01:00
nothingTVatYT 6c32e4a842 force DeepClone() to use runtime class 2023-11-18 05:34:34 +01:00
Tryibion 84f6e2f90f Hide search window and search nodes from UIControls 2023-11-17 11:25:54 -06:00
mafiesto4 f77f8fbb39 Fix regression from d9b90c9520 2023-11-17 16:15:43 +01:00
mafiesto4 15aaf5043a Fix scenes reload feature to check if can do it, properly use async in play mode and ask for save if scene is modified
#1740
2023-11-17 14:07:33 +01:00
mafiesto4 b7f2196784 Fix missing script replacement if data has object id that doesn't match current parent
#1924
2023-11-17 14:02:40 +01:00
mafiesto4 d9b90c9520 Fix crash in MissingScript if script is still missing after deserialization
#1924
2023-11-17 13:50:18 +01:00
mafiesto4 719498e99b Adjust MissingScriptEditor layout for UI 2023-11-17 13:08:37 +01:00
mafiesto4 0beb389012 Merge branch 'NoriteSC-MathLib' 2023-11-17 12:25:28 +01:00
mafiesto4 e177aec5fa Codestyle 2023-11-17 12:19:54 +01:00
mafiesto4 a1ef635a2c Merge branch 'MathLib' of https://github.com/NoriteSC/FlaxEngineFork into NoriteSC-MathLib 2023-11-17 12:17:11 +01:00
mafiesto4 ca64867f3c Merge branch 'RuanLucasGD-fix-navigation-crash' 2023-11-16 16:26:59 +01:00
mafiesto4 027fcbfd36 6Merge branch 'fix-navigation-crash' of https://github.com/RuanLucasGD/FlaxEngine into RuanLucasGD-fix-navigation-crash 2023-11-16 16:16:07 +01:00
mafiesto4 bec878cc11 Fix crashes in various dictionary usages caused by duplicated keys
#1925 #1924
2023-11-16 15:47:42 +01:00
mafiesto4 f0865c3989 Fix crash in Global Surface Atlas when dirty object is missing 2023-11-16 14:18:29 +01:00
mafiesto4 9738fd4354 Fix crash on hot-reload in Editor due to leftover scripting events in ScriptingEvents::EventsTable
#1925
2023-11-16 14:09:05 +01:00
mafiesto4 d33bf2fa6a Update docs comments based on https://github.com/FlaxEngine/FlaxDocs/pull/127 2023-11-16 13:55:45 +01:00
NoriteSC 307129b4a1 added c++ PingPong and flipped sheer 2023-11-16 11:50:44 +01:00
Mr. Capybara 6aea001e94 Remove unnecessary check 2023-11-15 12:49:20 -03:00
mafiesto4 3a59cfcf20 Change Globals.BuildErrors into BuildException #1673 2023-11-15 11:57:53 +01:00
mafiesto4 385693afff Merge branch 'GoaLitiuM-csharp_vs_build' 2023-11-15 11:44:49 +01:00
mafiesto4 e7ef3ebef2 Merge branch 'csharp_vs_build' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-csharp_vs_build 2023-11-15 11:44:42 +01:00
mafiesto4 c45d606f69 Merge branch 'GoaLitiuM-dotnet8_rollforward_fix' 2023-11-15 11:44:29 +01:00
mafiesto4 2555b07edf Merge branch 'dotnet8_rollforward_fix' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-dotnet8_rollforward_fix 2023-11-15 11:44:21 +01:00
Mr. Capybara d533cf554a Avoid crash when try build navmesh with null scene 2023-11-14 14:47:35 -04:00
mafiesto4 bc3107d1db Fix build warnings on the latest XCode 2023-11-14 19:03:46 +01:00
GoaLitiuM 3f5c92e2fa Improve .NET 8 runtime and SDK detection
Setting the environment variable `DOTNET_ROLL_FORWARD_TO_PRERELEASE=1`
is required to enable runtime support for release candidate builds of
future major .NET releases.
2023-11-14 17:00:51 +02:00
mafiesto4 8d3cb8953c Add casting to variant in large worlds build 2023-11-14 12:41:59 +01:00
mafiesto4 6fd34bf5cc Fix compilation regression 2023-11-14 12:15:51 +01:00
mafiesto4 0360f7786d Fix crash hen readingBehaviorKnowledgeSelector value in C# when type doesn't match exactly 2023-11-14 11:47:44 +01:00
mafiesto4 3320c76e14 Add soft check for null managed object value for unboxing 2023-11-14 11:23:15 +01:00
mafiesto4 e0de6744e2 Add better errors logging to BT nodes in case of issues 2023-11-14 11:22:41 +01:00
mafiesto4 7c53b1e99a Add clearing BT memory in non-release builds to make issues spotting easier 2023-11-14 11:22:17 +01:00
mafiesto4 dd579eb099 Merge branch 'GoaLitiuM-freetype_fontstyle' 2023-11-14 10:39:08 +01:00
mafiesto4 0d8868e5bb Merge branch 'freetype_fontstyle' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-freetype_fontstyle 2023-11-14 10:39:01 +01:00
mafiesto4 c0f0bd87aa Fix error in Tabs.SelectedTab
#1932
2023-11-14 10:33:40 +01:00
mafiesto4 f7fb366233 Minor doc updates 2023-11-14 10:31:11 +01:00
mafiesto4 b2f49e2791 Merge branch 'Tryibion-limit-cloth-brush' 2023-11-14 10:30:46 +01:00
mafiesto4 b848c12802 Merge branch 'limit-cloth-brush' of https://github.com/Tryibion/FlaxEngine into Tryibion-limit-cloth-brush 2023-11-14 10:30:27 +01:00
mafiesto4 45cb4eb66d Merge branch 'RuanLucasGD-WakeUp-Rigidboies' 2023-11-14 10:20:50 +01:00
mafiesto4 a42d54e401 Merge branch 'WakeUp-Rigidboies' of https://github.com/RuanLucasGD/FlaxEngine into RuanLucasGD-WakeUp-Rigidboies 2023-11-14 10:20:43 +01:00
Tryibion ab5534da7f Add limits to cloth brush values. 2023-11-13 20:38:04 -06:00
Mr. Capybara 05ea803582 add check for GetStartAwake 2023-11-13 20:05:05 -04:00
mafiesto4 eaafb72ca9 Optimize some includes and use automatic serializers for platform settings 2023-11-13 23:54:07 +01:00
Mr. Capybara 4ceed361e2 small fix 2023-11-13 14:28:16 -04:00
Mr. Capybara a9e1568edc Auto WakeUp rigidbodies when set "isKinematic" to false 2023-11-13 14:26:42 -04:00
mafiesto4 348ed463fc Merge branch 'Radiangames-LightThemeTweaks' 2023-11-13 17:17:42 +01:00
mafiesto4 618273977c Minor improvements to code style #1541 2023-11-13 17:17:05 +01:00
mafiesto4 13881c7d97 Merge branch 'LightThemeTweaks' of https://github.com/Radiangames/FlaxEngine into Radiangames-LightThemeTweaks 2023-11-13 17:02:12 +01:00
mafiesto4 97a28d4431 Add security lockers for managed typeinfo access 2023-11-13 15:48:12 +01:00
mafiesto4 46f82aabcd Fix ui navigation regression from 2f9343c236 2023-11-13 14:48:40 +01:00
mafiesto4 c328eabd2a Merge branch 'Tryibion-dropdown-improvements' 2023-11-13 14:46:11 +01:00
mafiesto4 422fb34c69 Rename NumberOfItemsToShow to ShowMaxItemsCount #1826 2023-11-13 14:41:33 +01:00
mafiesto4 c7eaed6c65 Merge branch 'dropdown-improvements' of https://github.com/Tryibion/FlaxEngine into Tryibion-dropdown-improvements 2023-11-13 14:36:18 +01:00
mafiesto4 418918920e Add GetSplineSegmentLength to get spline segment length
#1879
2023-11-13 11:38:37 +01:00
mafiesto4 930b1b978c Fix incorrect spline length calculation if first point is not at spline origin
#1876
2023-11-13 10:25:46 +01:00
mafiesto4 95180f4aa9 Merge branch 'SinnersSum-Flax-SSDev' 2023-11-13 09:52:43 +01:00
mafiesto4 0f14672e3b Codestyle formatting and fixes for #1888 2023-11-13 09:45:33 +01:00
mafiesto4 0fe9f6f439 Merge branch 'Flax-SSDev' of https://github.com/SinnersSum/FlaxEngine into SinnersSum-Flax-SSDev 2023-11-12 21:47:45 +01:00
mafiesto4 cc1e98db3c Bump up build number 2023-11-12 01:06:06 +01:00
mafiesto4 31ce41c5a4 Fix marking scene as dirty when creating prefab from existing actor
#1916
2023-11-11 17:57:54 +01:00
mafiesto4 be90f47585 Documentation improvements from https://github.com/FlaxEngine/FlaxDocs/pull/125 2023-11-11 15:37:12 +01:00
mafiesto4 ddaa5f9161 Fix regression in Custom Editor UI from 74bcf7d9e5
#1616 #1911
2023-11-11 14:47:20 +01:00
GoaLitiuM dc7170c51e Expose Freetype font style flags in FontAsset 2023-11-10 21:32:50 +02:00
mafiesto4 43ae0bcd4c Merge branch 'MineBill-fix-rider-detection' 2023-11-10 16:14:48 +01:00
mafiesto4 252bb680fa Merge branch 'fix-rider-detection' of https://github.com/MineBill/FlaxEngine into MineBill-fix-rider-detection 2023-11-10 16:14:38 +01:00
mafiesto4 beab66e42e Merge branch 'RuanLucasGD-rebuild-navigation' 2023-11-10 15:54:13 +01:00
mafiesto4 c2c0ad8067 Merge branch 'rebuild-navigation' of https://github.com/RuanLucasGD/FlaxEngine into RuanLucasGD-rebuild-navigation 2023-11-10 15:08:55 +01:00
mafiesto4 057d1fbcc6 Fix unpacking Float3 and other inbuilt Variant types via Unpack node in Visual Script
#1903
2023-11-10 15:07:37 +01:00
Mr. Capybara 626cde118b Add verification to rebuild navigation 2023-11-10 09:45:46 -03:00
mafiesto4 36daa38e0f Fix CollectionEditor to properly support editing multiple arrays
#1818
2023-11-10 13:23:32 +01:00
MineBill ed69f11121 Don't hardcode appdata path for linux anymore. 2023-11-10 13:58:03 +02:00
mafiesto4 9cd8c02911 Fix NetworkTransform to properly reject local simulation deltas on incoming authoritative transform data
#1907
2023-11-10 11:34:52 +01:00
mafiesto4 7d70a15034 Fix color editing control to properly handle mouse event
#1782
2023-11-10 10:20:21 +01:00
mafiesto4 39a5b8e635 Invert check order 2023-11-10 01:32:24 +01:00
Mr. Capybara 2ae290491e fix build 2023-11-09 14:50:56 -04:00
Mr. Capybara 3c71dc99e0 Rebuild navigation after apply changes in Navigation asset 2023-11-09 14:08:01 -04:00
NoriteSC ea3f02f810 Fix rotacion sheers the UI element 2023-11-09 17:34:51 +01:00
mafiesto4 4ae57e7769 Fix issue with asset loading to be properly canceled when reimporting file
#1894
2023-11-09 14:52:28 +01:00
mafiesto4 22c8ec5342 Fix crash when rigidbody gets deleted during physical collision
#1893
2023-11-09 11:50:48 +01:00
mafiesto4 710b9275fd Fix minor typos https://github.com/FlaxEngine/FlaxDocs/pull/123 2023-11-09 09:13:40 +01:00
mafiesto4 e7844bb5b2 Merge branch 'Menotdan-custom-model-matpv' 2023-11-09 09:10:32 +01:00
mafiesto4 d8a54692f0 Code cleanup #1785 2023-11-09 09:10:25 +01:00
mafiesto4 30ca7d52d0 Merge branch 'custom-model-matpv' of https://github.com/Menotdan/FlaxEngine into Menotdan-custom-model-matpv 2023-11-09 09:06:26 +01:00
mafiesto4 888a8ee7b9 Merge branch 'NoriteSC-Nodes' 2023-11-08 21:30:44 +01:00
mafiesto4 d90b723487 Code cleanup and usability tweaks for #1600 2023-11-08 21:30:31 +01:00
mafiesto4 67c22cf3d4 Merge branch 'Nodes' of https://github.com/NoriteSC/FlaxEngineFork into NoriteSC-Nodes 2023-11-08 21:19:08 +01:00
NoriteSC 6497f3109a Merge branch 'MathLib' of https://github.com/NoriteSC/FlaxEngineFork into MathLib 2023-11-08 18:36:05 +01:00
NoriteSC 6dcadb5131 Compacted UpdateTransform Matrix math 2023-11-08 18:35:27 +01:00
mafiesto4 d6f449820b Merge branch 'RuanLucasGD-ui-usability-improv' 2023-11-08 17:23:23 +01:00
mafiesto4 a6c47ae17b Merge branch 'ui-usability-improv' of https://github.com/RuanLucasGD/FlaxEngine into RuanLucasGD-ui-usability-improv 2023-11-08 17:08:23 +01:00
mafiesto4 b3c15d6562 Merge branch 'Tryibion-center-import' 2023-11-08 15:07:44 +01:00
mafiesto4 0fe46457c6 Merge branch 'center-import' of https://github.com/Tryibion/FlaxEngine into Tryibion-center-import 2023-11-08 15:07:38 +01:00
mafiesto4 bcaa42dda2 Fix crash on negative collection capacity due to int32 maximum value limit
#1886
2023-11-08 15:07:20 +01:00
mafiesto4 22fa7a89ac Merge branch 'Tryibion-anim-slot-speed-fix' 2023-11-08 14:43:08 +01:00
mafiesto4 e572f75b06 Merge branch 'anim-slot-speed-fix' of https://github.com/Tryibion/FlaxEngine into Tryibion-anim-slot-speed-fix 2023-11-08 14:43:03 +01:00
mafiesto4 11b60390b6 Add GetRotationFromTo and FindBetween utilities to C# Quaternion API
#1885
2023-11-08 14:41:36 +01:00
mafiesto4 1a7770fba2 Fix deadlock regression when saving Visual Script in Editor with active instance objects
#1890
2023-11-08 14:33:05 +01:00
mafiesto4 966fb0275b Add SortScore to Visject node archetypes and use it to favor method overrides in Visual Script 2023-11-08 11:52:31 +01:00
mafiesto4 785d3e8648 Fix Output Log window to scroll log on startup properly 2023-11-08 11:40:57 +01:00
mafiesto4 2f9343c236 Add handling ViewLayersMask from camera when rendering UICanvas
#1811
2023-11-08 11:21:29 +01:00
SS 52a1175f96 Seperated out assembly resolution logic to it's own function 2023-11-07 16:30:50 -07:00
SS 77b6a4a68b Fixed issue in NativeInterop
Readded check in current app domain to ExtendedSerializationBinder
2023-11-07 16:03:03 -07:00
mafiesto4 74bcf7d9e5 Fix custom editor layout rebuilding when it has more editors in use
#1616
2023-11-07 18:30:05 +01:00
mafiesto4 22d754e797 Fix error during new json asset creation via ContentContextMenu if the class is missing empty constructor
#1838
2023-11-07 16:21:56 +01:00
mafiesto4 0d85094ebb Fix error during new json asset creation via ContentContextMenu if the class is missing empty constructor
#1838
2023-11-07 16:21:48 +01:00
mafiesto4 7d43a0cc8b Fix various cases of closing window tabs when using Dock Windows in Editor
#1750
2023-11-07 16:14:09 +01:00
mafiesto4 4c413cb146 Merge branch 'MineBill-editor-list-dragging' 2023-11-07 10:54:23 +01:00
mafiesto4 4238c43f27 Format code #1850 2023-11-07 10:54:11 +01:00
mafiesto4 f163edfb7e Move AssetPickerValidator to Editor Content folder
#1850
2023-11-07 10:24:38 +01:00
mafiesto4 fd4a5595c0 Merge branch 'editor-list-dragging' of https://github.com/MineBill/FlaxEngine into MineBill-editor-list-dragging 2023-11-07 10:21:57 +01:00
mafiesto4 f6645e5600 Add debug drawing contact offset for selected collider
#1728
2023-11-07 09:56:33 +01:00
Tryibion b72849eafe Fix anim slot from playing animations more than 1 time based on speed. 2023-11-06 19:52:19 -06:00
SS d6e93a7fab Fixed issue involving stale scripting assemblies in FlaxEngine.Json dynamic type resolution
Added new ExtendedSerializationBinder
Added callback to clear serializer cache on scripting assembly reload
Added low-cost mechanism to invalidate the SerializerCache after domain reload
2023-11-06 18:49:30 -07:00
mafiesto4 6648481d12 Improve various doc comments to be more usable as tooltips in Editor 2023-11-07 00:57:18 +01:00
mafiesto4 87a9dedba4 Refactor default ContactOffset for Collider to be 2 (keep 10 for CharacterController)
#1728
2023-11-07 00:56:55 +01:00
mafiesto4 4fdeb773a5 Add hidding Camera properties based on UsePerspective option
#1858
2023-11-07 00:29:29 +01:00
mafiesto4 a90cf7c28f Add better formatting for automatic tooltips in Editor from xml comments 2023-11-07 00:26:14 +01:00
mafiesto4 4b2595e904 Remove tooltips from Camera and use automatic ones from xml comments 2023-11-07 00:19:02 +01:00
mafiesto4 42e8311736 Add engine version in Editor main window title
#1847
2023-11-07 00:13:13 +01:00
mafiesto4 a685918e10 Add default value for material Sphere Mask node to create blob gradient around UV center
#1830
2023-11-06 23:57:54 +01:00
mafiesto4 47ca4228dd Fix compile warning 2023-11-06 20:50:52 +01:00
mafiesto4 7dc645c114 Update Tracy Profiler to 0.10 2023-11-06 20:50:37 +01:00
mafiesto4 c78ce9697c Fix incorrect tabs selection handling when tab gets removed
#1843
2023-11-06 18:14:16 +01:00
mafiesto4 c3d74b690e Fix editor plugins init regression from #1779 and compact more code 2023-11-06 18:13:06 +01:00
mafiesto4 ae85a94261 Fix memory leak while doing drag&drop with Debug Draw in use
#1723
2023-11-06 17:18:20 +01:00
mafiesto4 e7b1fce3eb Merge DoDragDropJob to hsare the same code for Mac and Windows
#1723
2023-11-06 17:03:03 +01:00
mafiesto4 b47420f232 Compact various source code chunks 2023-11-06 16:56:15 +01:00
mafiesto4 c025b4414c Add support for unlimited window size if MaximumSize is set to Zero
#1824
2023-11-06 14:42:29 +01:00
mafiesto4 51c0a6e100 Fix crash regression on Dictionary and HashSet capacity set to 0 when it contains elements 2023-11-06 14:32:04 +01:00
mafiesto4 9a9e32d4c5 Fix incorrect directional light shadows influence on secondary render views
#1758
2023-11-06 14:20:30 +01:00
mafiesto4 1e9ded55b0 Fix missing xml doc 2023-11-06 14:09:39 +01:00
mafiesto4 e22fa20dc1 Minor fixes to #1740 2023-11-06 14:06:10 +01:00
mafiesto4 fe69a52cf2 Merge branch 'RuanLucasGD-add-reload-scenes-button' 2023-11-06 13:55:48 +01:00
mafiesto4 9eb9294e84 Merge branch 'add-reload-scenes-button' of https://github.com/RuanLucasGD/FlaxEngine into RuanLucasGD-add-reload-scenes-button 2023-11-06 13:55:43 +01:00
mafiesto4 c53fce18a8 Merge branch 'Chikinsupu-MaterialEditor-RemovedUnsupportedParameterTypes' 2023-11-06 13:54:47 +01:00
mafiesto4 8500667817 Merge branch 'MaterialEditor-RemovedUnsupportedParameterTypes' of https://github.com/Chikinsupu/FlaxEngine into Chikinsupu-MaterialEditor-RemovedUnsupportedParameterTypes 2023-11-06 13:54:41 +01:00
mafiesto4 40a3911453 Merge branch 'Tryibion-spawn-scalar' 2023-11-06 13:54:23 +01:00
mafiesto4 e57e86cde1 Fix spawned ui canvas scaller to use the same transform as CanvasScaler
#1819
2023-11-06 13:54:01 +01:00
mafiesto4 ad290d0140 Merge branch 'spawn-scalar' of https://github.com/Tryibion/FlaxEngine into Tryibion-spawn-scalar 2023-11-06 13:36:24 +01:00
Tryibion 0930671e90 Cache main panel, cleanup cached variables. 2023-11-06 06:25:17 -06:00
mafiesto4 855122672f Merge branch 'Chikinsupu-Visject-CommentOrder' 2023-11-06 13:09:29 +01:00
mafiesto4 e68330f5b5 Merge branch 'Visject-CommentOrder' of https://github.com/Chikinsupu/FlaxEngine into Chikinsupu-Visject-CommentOrder 2023-11-06 13:09:21 +01:00
mafiesto4 a0d4714a0f Add always logging unhandled c# exception
#1861
2023-11-06 12:23:17 +01:00
mafiesto4 f703e7de77 Fix compile error 2023-11-06 11:05:31 +01:00
mafiesto4 7e6c8b7b32 Codestyle fix #1779 2023-11-06 10:33:11 +01:00
mafiesto4 a55dcf42da Merge branch 'Tryibion-plugin-order' 2023-11-06 09:37:15 +01:00
mafiesto4 23369c2ff3 Merge branch 'plugin-order' of https://github.com/Tryibion/FlaxEngine into Tryibion-plugin-order 2023-11-06 09:37:09 +01:00
mafiesto4 7855049509 Merge branch 'Chikinsupu-Visject-ConvertConstantToParameter' 2023-11-06 08:41:45 +01:00
mafiesto4 d79dd4aaf7 Add undo for Convert to Parameter connections change in #1671 2023-11-06 08:41:36 +01:00
mafiesto4 2c5a5acf33 Add maintaining new param id in undo #1671 2023-11-05 23:30:39 +01:00
mafiesto4 342360f537 Refactor #1671 2023-11-05 23:21:14 +01:00
mafiesto4 3ba8875121 Merge branch 'Visject-ConvertConstantToParameter' of https://github.com/Chikinsupu/FlaxEngine into Chikinsupu-Visject-ConvertConstantToParameter
# Conflicts:
#	Source/Editor/Surface/Archetypes/Constants.cs
2023-11-05 21:43:16 +01:00
mafiesto4 655afb4b90 Merge branch 'GoaLitiuM-editor_binding_fixes' 2023-11-05 21:40:50 +01:00
mafiesto4 f9a9912895 Merge branch 'editor_binding_fixes' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-editor_binding_fixes 2023-11-05 21:39:24 +01:00
mafiesto4 bc91b1ed44 Merge branch 'MineBill-fix-color-picker-position' 2023-11-05 21:10:56 +01:00
mafiesto4 6fbf7fa07b Merge branch 'fix-color-picker-position' of https://github.com/MineBill/FlaxEngine into MineBill-fix-color-picker-position 2023-11-05 21:09:49 +01:00
mafiesto4 ea48056699 Merge branch 'Tryibion-ensure-no-layer-popup' 2023-11-05 21:04:43 +01:00
mafiesto4 82d5130261 Merge branch 'ensure-no-layer-popup' of https://github.com/Tryibion/FlaxEngine into Tryibion-ensure-no-layer-popup 2023-11-05 21:04:38 +01:00
mafiesto4 b7e0994932 Merge branch 'Chikinsupu-Visject-MoreAlternativeTitles' 2023-11-05 20:54:22 +01:00
mafiesto4 d13b30304a Merge branch 'Visject-MoreAlternativeTitles' of https://github.com/Chikinsupu/FlaxEngine into Chikinsupu-Visject-MoreAlternativeTitles 2023-11-05 20:54:18 +01:00
mafiesto4 abc340b52c Merge branch 'MineBill-honor-xdg_data_home' 2023-11-05 20:51:36 +01:00
mafiesto4 2dd16c1fb0 Merge branch 'honor-xdg_data_home' of https://github.com/MineBill/FlaxEngine into MineBill-honor-xdg_data_home 2023-11-05 20:51:31 +01:00
mafiesto4 77e6aafc79 Fix crash when not clearing Online Platform in Editor before hot-reload
#1873
2023-11-05 19:36:09 +01:00
mafiesto4 c23f8f2b30 Fix loading delay-loaded-dll on Windows when using project plugin with native dependencies
#1873
2023-11-05 19:35:33 +01:00
MineBill 267e8daba5 Honor the XDG_DATA_HOME env var and use the approved default as per specification. 2023-11-05 19:36:01 +02:00
mafiesto4 c5d3954bc8 Add CalculateBoneOffsetMatrices option to fix some animated model skeletons rendering
#1862
2023-11-05 14:11:28 +01:00
mafiesto4 a7bb236344 Fix Mono GC threads suspend to not deadlock when attaching native threads to managed runtime
#1864
2023-11-05 14:07:05 +01:00
mafiesto4 0387f7df8a Add name to Android main thread 2023-11-04 22:21:52 +01:00
mafiesto4 ca2106ff5d Remove SHADOW_MAPS_FORMAT and support fallback formats for shadow maps 2023-11-04 21:27:57 +01:00
mafiesto4 4a10878b45 Refactor GPUResourceProperty 2023-11-04 20:04:40 +01:00
mafiesto4 22e34cb2b4 Fix crash on editor startup without code editor selected
#1872
2023-11-04 19:30:16 +01:00
mafiesto4 585b6bacad Simplify #1807 2023-11-04 19:26:46 +01:00
mafiesto4 f736aae75d Merge branch 'Tryibion-limit-rename-popup' 2023-11-04 19:23:38 +01:00
mafiesto4 880e13865f Merge branch 'limit-rename-popup' of https://github.com/Tryibion/FlaxEngine into Tryibion-limit-rename-popup 2023-11-04 19:23:32 +01:00
mafiesto4 7072839254 Merge branch 'MineBill-find-interfaces' 2023-11-04 19:22:29 +01:00
mafiesto4 45060721e7 Merge branch 'find-interfaces' of https://github.com/MineBill/FlaxEngine into MineBill-find-interfaces 2023-11-04 19:22:23 +01:00
mafiesto4 87d67a78f4 Merge branch 'RuanLucasGD-add-extended-buttons-linux' 2023-11-04 19:20:45 +01:00
mafiesto4 0ab43dd301 Merge branch 'add-extended-buttons-linux' of https://github.com/RuanLucasGD/FlaxEngine into RuanLucasGD-add-extended-buttons-linux 2023-11-04 19:19:29 +01:00
mafiesto4 8c34fe7933 Reduce LargeWorlds::ChunkSize to 8192
#1854
2023-11-04 19:18:21 +01:00
mafiesto4 fe3f64f06a Fix iOS build 2023-11-04 19:15:37 +01:00
mafiesto4 8af3cfd90b Merge remote-tracking branch 'origin/master' 2023-11-04 19:14:55 +01:00
mafiesto4 3bf7b57dbd Fix BitArray::SetAll() when the item is not multiple of 8
#1863
2023-11-04 19:14:45 +01:00
mafiesto4 19752e4f3b Add storing shader asset includes paths in compact format for portability 2023-11-04 15:26:18 +01:00
mafiesto4 50bcbf980e Add SetThreadAffinityMask and SetThreadPriority and thread name for Apple platforms 2023-11-04 14:08:53 +01:00
mafiesto4 236e5772ce Fix CultureInfo to handle missing country code and fallback to outer language code 2023-11-04 13:49:30 +01:00
mafiesto4 6ddf241ea4 Minor improvements to reference properties 2023-11-03 22:40:18 +01:00
mafiesto4 e429e85aae Continue Delegate refactor to use single memory allocation and atomic operations for data access 2023-11-03 22:27:58 +01:00
mafiesto4 224e43ea55 Use soft asset ref to graphics settings
#1852
2023-11-03 19:23:38 +01:00
mafiesto4 6f1ee382b5 Fix regression from 087cfd7a8c on hashset item duplicate re-add 2023-11-03 19:07:16 +01:00
mafiesto4 da72dd4806 Add unit test for HashSet and Dictionary collection types 2023-11-02 19:59:27 +01:00
mafiesto4 087cfd7a8c Refactor HashSet and Dictionary collections capacity to handle rehashing when too many elements were deleted 2023-11-02 19:59:01 +01:00
MineBill 151c6bc6c3 Fix color picker dialog not staying inside the current screen. 2023-11-01 20:07:58 +02:00
mafiesto4 c0a8d29453 Improve Cloth usage 2023-11-01 10:46:47 +01:00
mafiesto4 1a254afd4f Fix crash when creating empty cloth 2023-11-01 10:29:44 +01:00
MineBill f6e9d0431b Implement drag and drop for list collection. 2023-11-01 01:31:42 +02:00
Mr. Capybara 6cfc8c1b1a Add extended buttons support for linux 2023-10-31 14:52:09 -04:00
mafiesto4 536be6c6cf Merge branch 'master' of https://gitlab.flaxengine.com/flax/flaxengine 2023-10-31 16:11:15 +01:00
mafiesto4 b0fe99f1ec Disable mono thread attach to fix current freeze on GC STW event 2023-10-31 16:11:09 +01:00
MineBill df5dc0c284 Extract validation/item handling of AssetPicker in a separate class. 2023-10-31 16:32:57 +02:00
mafiesto4 f9614a4879 Disable capacity alloc on delegate creation 2023-10-31 15:31:40 +01:00
mafiesto4 4e2ee897bc Fix missing codesign for macOS game binaries 2023-10-31 15:22:14 +01:00
MineBill 357148f973 Include interfaces in FindScript. 2023-10-30 08:07:46 +02:00
Tryibion 1fa03a0de2 Fix focus issues to allow panel scroll bar to be clicked and used. 2023-10-28 11:25:14 -05:00
Tryibion 590f3f7493 Fix Dropdown scaling with CanvasScalar. Add limiting number of items to show in the dropdown. 2023-10-28 10:29:39 -05:00
Tryibion 90642b8862 Spawn canvas scalar on canvas creation. 2023-10-27 13:25:50 -05:00
Ari Vuollet 900e6338d6 Fix wrong variable name
Co-authored-by: NoriteSC <53096989+NoriteSC@users.noreply.github.com>
2023-10-27 19:21:21 +03:00
Tryibion 18c119c155 Ensure layer confirmation does not popup in play mode. 2023-10-25 16:25:26 -05:00
Tryibion 8c6ced4bb9 Limit the scene tree and prefab tree rename popup to only go to panel right edge. 2023-10-25 11:38:14 -05:00
Tryibion 66a709f09e small fixes 2023-10-25 10:46:04 -05:00
Tryibion bfaae46c7e remove not needed variable. 2023-10-25 10:35:12 -05:00
Tryibion b8921fd990 clean up 2023-10-25 09:58:02 -05:00
Tryibion 73694cba6c Add being able to set origin of mesh to the local mesh origin. fix centering several meshes. 2023-10-25 09:57:51 -05:00
Nils Hausfeld 1f8da14780 - Alternative titles for comparisons 2023-10-25 11:53:43 +02:00
Nils Hausfeld cfe717969b Merge branch 'master' into Visject-MoreAlternativeTitles 2023-10-25 11:46:09 +02:00
NoriteSC 210c5a5bb2 Merge branch 'FlaxEngine:master' into Nodes 2023-10-25 07:03:46 +02:00
NoriteSC 137c82a387 Update Material.cs 2023-10-25 06:21:19 +02:00
Mr. Capybara b2db1330c0 copy old control data to new control when set UIControl type 2023-10-24 21:45:00 -04:00
GoaLitiuM 06f37794c2 Add input bindings for game window mouse unlock and toggle fullscreen 2023-10-24 22:27:12 +03:00
GoaLitiuM 081648ef06 Fix common tooltips with hardcoded keybindings 2023-10-24 21:47:18 +03:00
Menotdan 8982961254 Add custom material option to Material Preview. 2023-10-23 22:10:17 -04:00
Tryibion 2e85ff0fb3 Simplify code 2023-10-22 22:19:51 -05:00
Tryibion fbaf14b6fa Add to be able to specify order of plugin initialization and deinitialization. 2023-10-22 21:58:20 -05:00
Nils Hausfeld ea00a448ef - Minor cleanup 2023-10-22 12:54:14 +02:00
Nils Hausfeld 7b2058d1b2 - Added alternative titles to some nodes 2023-10-22 12:37:51 +02:00
Nils Hausfeld ba31627ae0 Merge remote-tracking branch 'upstream/master' into Visject-CommentOrder 2023-10-21 16:06:44 +02:00
Nils Hausfeld ec7840f36b - New comments now get spawned on top of other comments
- Commenting other comments now puts the spawned comment below the child comments
- Added Order Value to comments to serialize order
- Added backwards compatiblity to older editor versions
- Cleanup
- XML Comments
2023-10-21 16:06:28 +02:00
Nils Hausfeld fa8b92a456 Adding the ability to order comments in visject 2023-10-21 14:18:30 +02:00
Nils Hausfeld 432f6d5402 Merge branch 'master' into Visject-ConvertConstantToParameter 2023-10-21 13:11:51 +02:00
Nils Hausfeld 571f8febf4 - Moved convertible node file out of archetypes folder into surface folder to be more in line of the project structure (other special nodes like surfacecomment are also just in the surface folder)
- Cleanup
2023-10-21 13:11:42 +02:00
Nils Hausfeld c371a5b78c - Removed Quaternion and Transform from material parameter types since they are not supported 2023-10-20 12:55:54 +02:00
Mr. Capybara 70ccc79d54 change button order 2023-10-19 12:33:23 -04:00
Nils Hausfeld 7cb4d27979 - Minor cleanup and comments 2023-10-19 17:23:34 +02:00
Nils Hausfeld fdda42e504 Merge remote-tracking branch 'upstream/master' into Visject-ConvertConstantToParameter 2023-10-19 17:09:49 +02:00
Nils Hausfeld 4efbed91a4 - Fixed a bug where the wrong boxes got connected
- Cleanup
2023-10-19 14:34:10 +02:00
Nils Hausfeld ad6affc863 - More cleanup 2023-10-19 14:17:28 +02:00
Nils Hausfeld aafdc64b68 - Cleanup
- Typo
2023-10-19 14:14:51 +02:00
Nils Hausfeld 41a7aff6d7 - Converting to parameter now also works in Particle and Visual Scripting editor 2023-10-19 14:10:10 +02:00
Nils Hausfeld 9bd002ea33 Merge remote-tracking branch 'upstream/master' into Visject-ConvertConstantToParameter 2023-10-19 14:03:10 +02:00
Nils Hausfeld 3afb6cc88e - Renamed ConstantNode to ConvertableNode
- Moved ConvertableNode into it's own class
- Added support for custom conversion code (currently only used by rotation)
- Added support for Texture, Normal Map, Cube Texture, Uint, Double, String, Quaternion/Rotation
2023-10-19 14:02:46 +02:00
Mr. Capybara b2ba40b082 Add button to reload scenes 2023-10-18 20:34:39 -04:00
Nils Hausfeld 2537855aa3 Merge branch 'master' into Visject-ConvertConstantToParameter 2023-10-18 18:33:08 +02:00
Nils Hausfeld 447030f53a - Spawned get parameter node now reconnects to all boxes from the converted node 2023-10-16 20:19:18 +02:00
Nils Hausfeld a96445d8bb Merge branch 'master' into Visject-ConvertConstantToParameter 2023-10-16 19:34:22 +02:00
GoaLitiuM bcdd6c0551 Fix FlaxEngine C#-project getting built twice in engine solution 2023-10-15 16:16:53 +03:00
GoaLitiuM ff7e6d82f8 Hide exception when build errors occurs in referenced targets 2023-10-15 16:16:53 +03:00
GoaLitiuM 5b3e09baec Build C# projects in VS/Rider solution configurations
Rider's solution wide analysis does not work properly when projects
are not included in the active configuration for build.
2023-10-15 16:16:53 +03:00
GoaLitiuM 0d7e7c30ca Run Flax.Build when building main C# project 2023-10-15 16:16:53 +03:00
Nils Hausfeld dcec847d50 - Basic constants can now be converted to parameters 2023-10-11 20:01:56 +02:00
NoriteSC 004e2ab5e8 Update Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp
Co-authored-by: stefnotch <stefnotch@users.noreply.github.com>
2023-10-06 23:07:19 +02:00
NoriteSC d7095957d0 Update Source/Editor/Surface/Archetypes/Material.cs
Co-authored-by: stefnotch <stefnotch@users.noreply.github.com>
2023-10-06 23:07:00 +02:00
NoriteSC 4e2870e90c Update Source/Editor/Surface/Archetypes/Material.cs
Co-authored-by: stefnotch <stefnotch@users.noreply.github.com>
2023-10-06 22:56:16 +02:00
NoriteSC 1736aaeb6a Update Source/Editor/Surface/Archetypes/Material.cs
Co-authored-by: stefnotch <stefnotch@users.noreply.github.com>
2023-10-06 22:54:26 +02:00
NoriteSC d5c0ad0487 Merge branch 'FlaxEngine:master' into Nodes 2023-10-06 22:15:35 +02:00
NoriteSC d07a5e9823 Merge branch 'FlaxEngine:master' into Nodes 2023-10-06 17:03:32 +02:00
NoriteSC 329910ae0d missing input fix 2023-10-04 13:18:42 +02:00
NoriteSC d7b9056d94 added AAStep and resolved stefnotch reviewe 2023-10-04 13:15:17 +02:00
NoriteSC 367eaf2f89 adjustment to nodes size 2023-10-04 10:28:48 +02:00
NoriteSC 70ca1996c5 added Ratangle Mask and FWidth 2023-10-04 10:00:47 +02:00
Luke Schneider b7b8213179 Some additional fixes to light theme support
Fixed some issues with light theme support:

1) Icons in content tree nodes (Folder icons) now use the foreground color.  I did not find a case where the content tree is used for other icons.

2) The asset picker now uses the Background Normal color (instead of a very transparent dark gray) for the background, and Orange for the text.  Did not seem like it warranted adding a new color, and Orange works in both dark and light styles.

3) The platform selector icons are now hard-coded instead of based on the style.  This may sound odd, but the icons are colored, so they should always use White as the fully active color.  Previously they worked with a dark theme because the Foreground was set to white.

4) Fixed the CollectionBackgroundColor in the light theme being dark gray instead of light gray like it should be.  This fixes certain lists of things having a dark background in the light theme.
2023-09-29 07:43:59 -05:00
Luke Schneider ad28a3fdbf Better light theme (Style) support, and a Default light theme (as a secondary option)
1) Added ForegroundViewport as a new color.  It is used in the main game viewport (ViewportWidgetButton), and the viewport for rendering of particles and materials.  It is needed because the default foreground in a Light theme is black, but black does not work well in a viewport.  A new color seemed appropriate.

2) Fixed the profiler window to use the Foreground color in multiple text elements, instead of Color.White (or no default TitleColor).  This includes  the Row class, Asset class, SingleChart class, Timeline Class, and more.

3) Added a second theme/Style (DefaultLight) to include with the engine.  It uses RGB float values because those were easier to transfer from the saved values that I had created (and they're easier for me to edit if necessary).  I tried to emulate how the Default theme is created/loaded/etc as closely as possible.
2023-09-27 21:54:34 -05:00
336 changed files with 9209 additions and 3900 deletions
+1 -1
View File
@@ -33,4 +33,4 @@ jobs:
git lfs pull
- name: Build
run: |
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -arch=ARM64 -platform=Android -configuration=Release -buildtargets=FlaxGame
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -dotnet=7 -arch=ARM64 -platform=Android -configuration=Release -buildtargets=FlaxGame
+1 -1
View File
@@ -33,4 +33,4 @@ jobs:
git lfs pull
- name: Build
run: |
./Development/Scripts/Mac/CallBuildTool.sh -build -log -arch=ARM64 -platform=iOS -configuration=Release -buildtargets=FlaxGame
./Development/Scripts/Mac/CallBuildTool.sh -build -log -dotnet=7 -arch=ARM64 -platform=iOS -configuration=Release -buildtargets=FlaxGame
+2 -2
View File
@@ -36,7 +36,7 @@ jobs:
git lfs pull
- name: Build
run: |
./Development/Scripts/Linux/CallBuildTool.sh -build -log -printSDKs -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxEditor
./Development/Scripts/Linux/CallBuildTool.sh -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxEditor
# Game
game-linux:
@@ -64,4 +64,4 @@ jobs:
git lfs pull
- name: Build
run: |
./Development/Scripts/Linux/CallBuildTool.sh -build -log -printSDKs -arch=x64 -platform=Linux -configuration=Release -buildtargets=FlaxGame
./Development/Scripts/Linux/CallBuildTool.sh -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Linux -configuration=Release -buildtargets=FlaxGame
+2 -2
View File
@@ -30,7 +30,7 @@ jobs:
git lfs pull
- name: Build
run: |
./Development/Scripts/Mac/CallBuildTool.sh -build -log -printSDKs -arch=x64 -platform=Mac -configuration=Development -buildtargets=FlaxEditor
./Development/Scripts/Mac/CallBuildTool.sh -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Mac -configuration=Development -buildtargets=FlaxEditor
# Game
game-mac:
@@ -55,4 +55,4 @@ jobs:
git lfs pull
- name: Build
run: |
./Development/Scripts/Mac/CallBuildTool.sh -build -log -printSDKs -arch=x64 -platform=Mac -configuration=Release -buildtargets=FlaxGame
./Development/Scripts/Mac/CallBuildTool.sh -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Mac -configuration=Release -buildtargets=FlaxGame
+2 -2
View File
@@ -30,7 +30,7 @@ jobs:
git lfs pull
- name: Build
run: |
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxEditor
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxEditor
# Game
game-windows:
@@ -55,4 +55,4 @@ jobs:
git lfs pull
- name: Build
run: |
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -arch=x64 -platform=Windows -configuration=Release -buildtargets=FlaxGame
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Windows -configuration=Release -buildtargets=FlaxGame
+5 -5
View File
@@ -34,8 +34,8 @@ jobs:
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
- name: Build
run: |
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs
./Development/Scripts/Linux/CallBuildTool.sh -build -log -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs -dotnet=7
./Development/Scripts/Linux/CallBuildTool.sh -build -log -dotnet=7 -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget
dotnet msbuild Source/Tools/Flax.Build.Tests/Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
dotnet msbuild Source/Tools/Flax.Build.Tests/Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
- name: Test
@@ -48,7 +48,7 @@ jobs:
dotnet test -f net7.0 Binaries/Tests/FlaxEngine.CSharp.dll
- name: Test UseLargeWorlds
run: |
./Development/Scripts/Linux/CallBuildTool.sh -build -log -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget -UseLargeWorlds=true
./Development/Scripts/Linux/CallBuildTool.sh -build -log -dotnet=7 -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget -UseLargeWorlds=true
${GITHUB_WORKSPACE}/Binaries/Editor/Linux/Development/FlaxTests
# Tests on Windows
@@ -72,8 +72,8 @@ jobs:
git lfs pull
- name: Build
run: |
.\GenerateProjectFiles.bat -vs2022 -log -verbose -printSDKs
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxTestsTarget
.\GenerateProjectFiles.bat -vs2022 -log -verbose -printSDKs -dotnet=7
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -dotnet=7 -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxTestsTarget
dotnet msbuild Source\Tools\Flax.Build.Tests\Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
- name: Test
run: |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2 -2
View File
@@ -3,8 +3,8 @@
"Version": {
"Major": 1,
"Minor": 7,
"Revision": 0,
"Build": 6404
"Revision": 1,
"Build": 6406
},
"Company": "Flax",
"Copyright": "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.",
+1 -1
View File
@@ -7,7 +7,7 @@ pushd
echo Performing the full package...
rem Run the build tool.
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployEditor -deployPlatforms -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployEditor -deployPlatforms -dotnet=7 -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
if errorlevel 1 goto BuildToolFailed
popd
+1 -1
View File
@@ -7,7 +7,7 @@ pushd
echo Building and packaging Flax Editor...
rem Run the build tool.
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployEditor -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployEditor -dotnet=7 -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
if errorlevel 1 goto BuildToolFailed
popd
+1 -1
View File
@@ -9,4 +9,4 @@ echo Building and packaging Flax Editor...
cd "`dirname "$0"`"
# Run Flax.Build (also pass the arguments)
bash ./Development/Scripts/Mac/CallBuildTool.sh --deploy --deployEditor --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
bash ./Development/Scripts/Mac/CallBuildTool.sh --deploy --deployEditor --dotnet=7 --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
+1 -1
View File
@@ -9,4 +9,4 @@ echo Building and packaging Flax Editor...
cd "`dirname "$0"`"
# Run Flax.Build (also pass the arguments)
bash ./Development/Scripts/Linux/CallBuildTool.sh --deploy --deployEditor --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
bash ./Development/Scripts/Linux/CallBuildTool.sh --deploy --deployEditor --dotnet=7 --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
+1 -1
View File
@@ -7,7 +7,7 @@ pushd
echo Building and packaging platforms data...
rem Run the build tool.
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployPlatforms -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployPlatforms -dotnet=7 -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
if errorlevel 1 goto BuildToolFailed
popd
+1 -1
View File
@@ -9,4 +9,4 @@ echo Building and packaging platforms data...
cd "`dirname "$0"`"
# Run Flax.Build (also pass the arguments)
bash ./Development/Scripts/Mac/CallBuildTool.sh --deploy --deployPlatforms --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
bash ./Development/Scripts/Mac/CallBuildTool.sh --deploy --deployPlatforms --dotnet=7 --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
+1 -1
View File
@@ -9,4 +9,4 @@ echo Building and packaging platforms data...
cd "`dirname "$0"`"
# Run Flax.Build (also pass the arguments)
bash ./Development/Scripts/Linux/CallBuildTool.sh --deploy --deployPlatforms --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
bash ./Development/Scripts/Linux/CallBuildTool.sh --deploy --deployPlatforms --dotnet=7 --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
@@ -0,0 +1,292 @@
using System;
using System.IO;
using FlaxEditor.Scripting;
using FlaxEngine;
using FlaxEngine.Utilities;
namespace FlaxEditor.Content;
/// <summary>
/// Manages and converts the selected content item to the appropriate types. Useful for drag operations.
/// </summary>
public class AssetPickerValidator : IContentItemOwner
{
private Asset _selected;
private ContentItem _selectedItem;
private ScriptType _type;
private string _fileExtension;
/// <summary>
/// Gets or sets the selected item.
/// </summary>
public ContentItem SelectedItem
{
get => _selectedItem;
set
{
if (_selectedItem == value)
return;
if (value == null)
{
if (_selected == null && _selectedItem is SceneItem)
{
// Deselect scene reference
_selectedItem.RemoveReference(this);
_selectedItem = null;
_selected = null;
OnSelectedItemChanged();
return;
}
// Deselect
_selectedItem?.RemoveReference(this);
_selectedItem = null;
_selected = null;
OnSelectedItemChanged();
}
else if (value is SceneItem item)
{
if (_selectedItem == item)
return;
if (!IsValid(item))
item = null;
// Change value to scene reference (cannot load asset because scene can be already loaded - duplicated ID issue)
_selectedItem?.RemoveReference(this);
_selectedItem = item;
_selected = null;
_selectedItem?.AddReference(this);
OnSelectedItemChanged();
}
else if (value is AssetItem assetItem)
{
SelectedAsset = FlaxEngine.Content.LoadAsync(assetItem.ID);
}
else
{
// Change value
_selectedItem?.RemoveReference(this);
_selectedItem = value;
_selected = null;
OnSelectedItemChanged();
}
}
}
/// <summary>
/// Gets or sets the selected asset identifier.
/// </summary>
public Guid SelectedID
{
get
{
if (_selected != null)
return _selected.ID;
if (_selectedItem is AssetItem assetItem)
return assetItem.ID;
return Guid.Empty;
}
set => SelectedItem = Editor.Instance.ContentDatabase.FindAsset(value);
}
/// <summary>
/// Gets or sets the selected content item path.
/// </summary>
public string SelectedPath
{
get
{
string path = _selectedItem?.Path ?? _selected?.Path;
if (path != null)
{
// Convert into path relative to the project (cross-platform)
var projectFolder = Globals.ProjectFolder;
if (path.StartsWith(projectFolder))
path = path.Substring(projectFolder.Length + 1);
}
return path;
}
set
{
if (string.IsNullOrEmpty(value))
{
SelectedItem = null;
}
else
{
var path = StringUtils.IsRelative(value) ? Path.Combine(Globals.ProjectFolder, value) : value;
SelectedItem = Editor.Instance.ContentDatabase.Find(path);
}
}
}
/// <summary>
/// Gets or sets the selected asset object.
/// </summary>
public Asset SelectedAsset
{
get => _selected;
set
{
// Check if value won't change
if (value == _selected)
return;
// Find item from content database and check it
var item = value ? Editor.Instance.ContentDatabase.FindAsset(value.ID) : null;
if (item != null && !IsValid(item))
item = null;
// Change value
_selectedItem?.RemoveReference(this);
_selectedItem = item;
_selected = value;
_selectedItem?.AddReference(this);
OnSelectedItemChanged();
}
}
/// <summary>
/// Gets or sets the assets types that this picker accepts (it supports types derived from the given type). Use <see cref="ScriptType.Null"/> for generic file picker.
/// </summary>
public ScriptType AssetType
{
get => _type;
set
{
if (_type != value)
{
_type = value;
// Auto deselect if the current value is invalid
if (_selectedItem != null && !IsValid(_selectedItem))
SelectedItem = null;
}
}
}
/// <summary>
/// Gets or sets the content items extensions filter. Null if unused.
/// </summary>
public string FileExtension
{
get => _fileExtension;
set
{
if (_fileExtension != value)
{
_fileExtension = value;
// Auto deselect if the current value is invalid
if (_selectedItem != null && !IsValid(_selectedItem))
SelectedItem = null;
}
}
}
/// <summary>
/// Occurs when selected item gets changed.
/// </summary>
public event Action SelectedItemChanged;
/// <summary>
/// The custom callback for assets validation. Cane be used to implement a rule for assets to pick.
/// </summary>
public Func<ContentItem, bool> CheckValid;
/// <summary>
/// Returns whether item is valid.
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public bool IsValid(ContentItem item)
{
if (_fileExtension != null && !item.Path.EndsWith(_fileExtension))
return false;
if (CheckValid != null && !CheckValid(item))
return false;
if (_type == ScriptType.Null)
return true;
if (item is AssetItem assetItem)
{
// Faster path for binary items (in-built)
if (assetItem is BinaryAssetItem binaryItem)
return _type.IsAssignableFrom(new ScriptType(binaryItem.Type));
// Type filter
var type = TypeUtils.GetType(assetItem.TypeName);
if (_type.IsAssignableFrom(type))
return true;
// Json assets can contain any type of the object defined by the C# type (data oriented design)
if (assetItem is JsonAssetItem && (_type.Type == typeof(JsonAsset) || _type.Type == typeof(Asset)))
return true;
// Special case for scene asset references
if (_type.Type == typeof(SceneReference) && assetItem is SceneItem)
return true;
}
return false;
}
/// <summary>
/// Initializes a new instance of the <see cref="AssetPickerValidator"/> class.
/// </summary>
public AssetPickerValidator()
: this(new ScriptType(typeof(Asset)))
{
}
/// <summary>
/// Initializes a new instance of the <see cref="AssetPickerValidator"/> class.
/// </summary>
/// <param name="assetType">The assets types that this picker accepts.</param>
public AssetPickerValidator(ScriptType assetType)
{
_type = assetType;
}
/// <summary>
/// Called when selected item gets changed.
/// </summary>
protected virtual void OnSelectedItemChanged()
{
SelectedItemChanged?.Invoke();
}
/// <inheritdoc />
public void OnItemDeleted(ContentItem item)
{
// Deselect item
SelectedItem = null;
}
/// <inheritdoc />
public void OnItemRenamed(ContentItem item)
{
}
/// <inheritdoc />
public void OnItemReimported(ContentItem item)
{
}
/// <inheritdoc />
public void OnItemDispose(ContentItem item)
{
// Deselect item
SelectedItem = null;
}
/// <summary>
/// Call to remove reference from the selected item.
/// </summary>
public void OnDestroy()
{
_selectedItem?.RemoveReference(this);
_selectedItem = null;
_selected = null;
}
}
@@ -86,6 +86,7 @@ namespace FlaxEditor.Content
Folder.ParentFolder = parent.Folder;
Parent = parent;
}
IconColor = Style.Current.Foreground;
}
/// <summary>
+7
View File
@@ -12,6 +12,13 @@
class GameCooker;
class PlatformTools;
#if OFFICIAL_BUILD
// Use the fixed .NET SDK version in packaged builds for compatibility (FlaxGame is precompiled with it)
#define GAME_BUILD_DOTNET_VER TEXT("-dotnet=7")
#else
#define GAME_BUILD_DOTNET_VER TEXT("")
#endif
/// <summary>
/// Game building options. Used as flags.
/// </summary>
@@ -280,17 +280,25 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
const Char* gradlew = TEXT("gradlew");
#endif
#if PLATFORM_LINUX
Platform::RunProcess(String::Format(TEXT("chmod +x \"{0}/gradlew\""), data.OriginalOutputPath), data.OriginalOutputPath, Dictionary<String, String>(), true);
{
CreateProcessSettings procSettings;
procSettings.FileName = String::Format(TEXT("chmod +x \"{0}/gradlew\""), data.OriginalOutputPath);
procSettings.WorkingDirectory = data.OriginalOutputPath;
procSettings.HiddenWindow = true;
Platform::CreateProcess(procSettings);
}
#endif
const bool distributionPackage = buildSettings->ForDistribution;
CreateProcessSettings procSettings;
procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug"));
procSettings.WorkingDirectory = data.OriginalOutputPath;
const int32 result = Platform::CreateProcess(procSettings);
if (result != 0)
{
data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result));
return true;
CreateProcessSettings procSettings;
procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug"));
procSettings.WorkingDirectory = data.OriginalOutputPath;
const int32 result = Platform::CreateProcess(procSettings);
if (result != 0)
{
data.Error(String::Format(TEXT("Failed to build Gradle project into package (result code: {0}). See log for more info."), result));
return true;
}
}
// Copy result package
@@ -188,8 +188,8 @@ bool CompileScriptsStep::Perform(CookingData& data)
LOG(Info, "Starting scripts compilation for game...");
const String logFile = data.CacheDirectory / TEXT("CompileLog.txt");
auto args = String::Format(
TEXT("-log -logfile=\"{4}\" -build -mutex -buildtargets={0} -platform={1} -arch={2} -configuration={3} -aotMode={5}"),
target, platform, architecture, configuration, logFile, ToString(data.Tools->UseAOT()));
TEXT("-log -logfile=\"{4}\" -build -mutex -buildtargets={0} -platform={1} -arch={2} -configuration={3} -aotMode={5} {6}"),
target, platform, architecture, configuration, logFile, ToString(data.Tools->UseAOT()), GAME_BUILD_DOTNET_VER);
#if PLATFORM_WINDOWS
if (data.Platform == BuildPlatform::LinuxX64)
#elif PLATFORM_LINUX
@@ -87,7 +87,7 @@ bool DeployDataStep::Perform(CookingData& data)
{
// Ask Flax.Build to provide .Net SDK location for the current platform
String sdks;
bool failed = ScriptsBuilder::RunBuildTool(TEXT("-log -logMessagesOnly -logFileWithConsole -logfile=SDKs.txt -printSDKs"), data.CacheDirectory);
bool failed = ScriptsBuilder::RunBuildTool(String::Format(TEXT("-log -logMessagesOnly -logFileWithConsole -logfile=SDKs.txt -printSDKs {}"), GAME_BUILD_DOTNET_VER), data.CacheDirectory);
failed |= File::ReadAllText(data.CacheDirectory / TEXT("SDKs.txt"), sdks);
int32 idx = sdks.Find(TEXT("DotNetSdk, "), StringSearchCase::CaseSensitive);
if (idx != -1)
@@ -168,7 +168,7 @@ bool DeployDataStep::Perform(CookingData& data)
String sdks;
const Char *platformName, *archName;
data.GetBuildPlatformName(platformName, archName);
String args = String::Format(TEXT("-log -logMessagesOnly -logFileWithConsole -logfile=SDKs.txt -printDotNetRuntime -platform={} -arch={}"), platformName, archName);
String args = String::Format(TEXT("-log -logMessagesOnly -logFileWithConsole -logfile=SDKs.txt -printDotNetRuntime -platform={} -arch={} {}"), platformName, archName, GAME_BUILD_DOTNET_VER);
bool failed = ScriptsBuilder::RunBuildTool(args, data.CacheDirectory);
failed |= File::ReadAllText(data.CacheDirectory / TEXT("SDKs.txt"), sdks);
Array<String> parts;
@@ -269,8 +269,8 @@ bool DeployDataStep::Perform(CookingData& data)
LOG(Info, "Optimizing .NET class library size to include only used assemblies");
const String logFile = data.CacheDirectory / TEXT("StripDotnetLibs.txt");
String args = String::Format(
TEXT("-log -logfile=\"{}\" -runDotNetClassLibStripping -mutex -binaries=\"{}\""),
logFile, data.DataOutputPath);
TEXT("-log -logfile=\"{}\" -runDotNetClassLibStripping -mutex -binaries=\"{}\" {}"),
logFile, data.DataOutputPath, GAME_BUILD_DOTNET_VER);
for (const String& define : data.CustomDefines)
{
args += TEXT(" -D");
@@ -67,8 +67,8 @@ bool PrecompileAssembliesStep::Perform(CookingData& data)
data.GetBuildPlatformName(platform, architecture);
const String logFile = data.CacheDirectory / TEXT("AOTLog.txt");
String args = String::Format(
TEXT("-log -logfile=\"{}\" -runDotNetAOT -mutex -platform={} -arch={} -configuration={} -aotMode={} -binaries=\"{}\" -intermediate=\"{}\""),
logFile, platform, architecture, configuration, ToString(aotMode), data.DataOutputPath, data.ManagedCodeOutputPath);
TEXT("-log -logfile=\"{}\" -runDotNetAOT -mutex -platform={} -arch={} -configuration={} -aotMode={} -binaries=\"{}\" -intermediate=\"{}\" {}"),
logFile, platform, architecture, configuration, ToString(aotMode), data.DataOutputPath, data.ManagedCodeOutputPath, GAME_BUILD_DOTNET_VER);
if (!buildSettings.SkipUnusedDotnetLibsPackaging)
args += TEXT(" -skipUnusedDotnetLibs=false"); // Run AOT on whole class library (not just used libs)
for (const String& define : data.CustomDefines)
@@ -157,6 +157,12 @@ namespace FlaxEditor.CustomEditors
var values = _values;
var presenter = _presenter;
var layout = _layout;
if (layout.Editors.Count > 1)
{
// There are more editors using the same layout so rebuild parent editor to prevent removing others editors
_parent?.RebuildLayout();
return;
}
var control = layout.ContainerControl;
var parent = _parent;
var parentScrollV = (_presenter?.Panel.Parent as Panel)?.VScrollBar?.Value ?? -1;
@@ -225,8 +225,15 @@ namespace FlaxEditor.CustomEditors.Dedicated
}
_actor = actor;
var showActorPicker = actor == null || ParentEditor.Values.All(x => x is not Cloth);
if (showActorPicker)
if (ParentEditor.Values.Any(x => x is Cloth))
{
// Cloth always picks the parent model mesh
if (actor == null)
{
layout.Label("Cloth needs to be added as a child to model actor.");
}
}
else
{
// Actor reference picker
_actorPicker = layout.Custom<FlaxObjectRefPickerControl>();
@@ -242,7 +249,10 @@ namespace FlaxEditor.CustomEditors.Dedicated
{
var model = staticModel.Model;
if (model == null || model.WaitForLoaded())
{
layout.Label("No model.");
return;
}
var materials = model.MaterialSlots;
var lods = model.LODs;
meshNames = new string[lods.Length][];
@@ -267,7 +277,10 @@ namespace FlaxEditor.CustomEditors.Dedicated
{
var skinnedModel = animatedModel.SkinnedModel;
if (skinnedModel == null || skinnedModel.WaitForLoaded())
{
layout.Label("No model.");
return;
}
var materials = skinnedModel.MaterialSlots;
var lods = skinnedModel.LODs;
meshNames = new string[lods.Length][];
@@ -37,41 +37,32 @@ public class MissingScriptEditor : GenericEditor
Parent = _dropPanel,
Height = 64,
};
_replaceScriptButton = new Button
{
Text = "Replace Script",
TooltipText = "Replaces the missing script with a given script type",
AnchorPreset = AnchorPresets.TopCenter,
Width = 240,
Height = 24,
X = -120,
Y = 0,
Bounds = new Rectangle(-120, 0, 240, 24),
Parent = replaceScriptPanel,
};
_replaceScriptButton.Clicked += OnReplaceScriptButtonClicked;
var replaceAllLabel = new Label
{
Text = "Replace all matching missing scripts",
TooltipText = "Whether or not to apply this script change to all scripts missing the same type.",
AnchorPreset = AnchorPresets.BottomCenter,
Y = -34,
Y = -38,
Parent = replaceScriptPanel,
};
replaceAllLabel.X -= FlaxEngine.GUI.Style.Current.FontSmall.MeasureText(replaceAllLabel.Text).X;
_shouldReplaceAllCheckbox = new CheckBox
{
TooltipText = replaceAllLabel.TooltipText,
AnchorPreset = AnchorPresets.BottomCenter,
Y = -34,
Y = -38,
Parent = replaceScriptPanel,
};
float centerDifference = (_shouldReplaceAllCheckbox.Right - replaceAllLabel.Left) / 2;
replaceAllLabel.X += centerDifference;
_shouldReplaceAllCheckbox.X += centerDifference;
_shouldReplaceAllCheckbox.X -= _replaceScriptButton.Width * 0.5f + 0.5f;
replaceAllLabel.X -= 52;
base.Initialize(layout);
}
@@ -695,7 +695,41 @@ namespace FlaxEditor.CustomEditors.Dedicated
private void SetType(ref ScriptType controlType, UIControl uiControl)
{
string previousName = uiControl.Control?.GetType().Name ?? nameof(UIControl);
uiControl.Control = (Control)controlType.CreateInstance();
var oldControlType = (Control)uiControl.Control;
var newControlType = (Control)controlType.CreateInstance();
// copy old control data to new control
if (oldControlType != null)
{
newControlType.Visible = oldControlType.Visible;
newControlType.Enabled = oldControlType.Enabled;
newControlType.AutoFocus = oldControlType.AutoFocus;
newControlType.AnchorMin = oldControlType.AnchorMin;
newControlType.AnchorMax = oldControlType.AnchorMax;
newControlType.Offsets = oldControlType.Offsets;
newControlType.LocalLocation = oldControlType.LocalLocation;
newControlType.Scale = oldControlType.Scale;
newControlType.Bounds = oldControlType.Bounds;
newControlType.Width = oldControlType.Width;
newControlType.Height = oldControlType.Height;
newControlType.Center = oldControlType.Center;
newControlType.PivotRelative = oldControlType.PivotRelative;
newControlType.Pivot = oldControlType.Pivot;
newControlType.Shear = oldControlType.Shear;
newControlType.Rotation = oldControlType.Rotation;
}
if (oldControlType is ContainerControl oldContainer && newControlType is ContainerControl newContainer)
{
newContainer.CullChildren = oldContainer.CullChildren;
newContainer.ClipChildren = oldContainer.ClipChildren;
}
uiControl.Control = newControlType;
if (uiControl.Name.StartsWith(previousName))
{
string newName = controlType.Name + uiControl.Name.Substring(previousName.Length);
@@ -34,7 +34,7 @@ namespace FlaxEditor.CustomEditors.Editors
value = 0;
// If selected is single actor that has children, ask if apply layer to the sub objects as well
if (Values.IsSingleObject && (int)Values[0] != value && ParentEditor.Values[0] is Actor actor && actor.HasChildren)
if (Values.IsSingleObject && (int)Values[0] != value && ParentEditor.Values[0] is Actor actor && actor.HasChildren && !Editor.IsPlayMode)
{
var valueText = comboBox.SelectedItem;
@@ -71,7 +71,7 @@ namespace FlaxEditor.CustomEditors.Editors
{
// Generic file picker
assetType = ScriptType.Null;
Picker.FileExtension = assetReference.TypeName;
Picker.Validator.FileExtension = assetReference.TypeName;
}
else
{
@@ -85,7 +85,7 @@ namespace FlaxEditor.CustomEditors.Editors
}
}
Picker.AssetType = assetType;
Picker.Validator.AssetType = assetType;
Picker.Height = height;
Picker.SelectedItemChanged += OnSelectedItemChanged;
}
@@ -95,15 +95,15 @@ namespace FlaxEditor.CustomEditors.Editors
if (_isRefreshing)
return;
if (typeof(AssetItem).IsAssignableFrom(_valueType.Type))
SetValue(Picker.SelectedItem);
SetValue(Picker.Validator.SelectedItem);
else if (_valueType.Type == typeof(Guid))
SetValue(Picker.SelectedID);
SetValue(Picker.Validator.SelectedID);
else if (_valueType.Type == typeof(SceneReference))
SetValue(new SceneReference(Picker.SelectedID));
SetValue(new SceneReference(Picker.Validator.SelectedID));
else if (_valueType.Type == typeof(string))
SetValue(Picker.SelectedPath);
SetValue(Picker.Validator.SelectedPath);
else
SetValue(Picker.SelectedAsset);
SetValue(Picker.Validator.SelectedAsset);
}
/// <inheritdoc />
@@ -115,15 +115,15 @@ namespace FlaxEditor.CustomEditors.Editors
{
_isRefreshing = true;
if (Values[0] is AssetItem assetItem)
Picker.SelectedItem = assetItem;
Picker.Validator.SelectedItem = assetItem;
else if (Values[0] is Guid guid)
Picker.SelectedID = guid;
Picker.Validator.SelectedID = guid;
else if (Values[0] is SceneReference sceneAsset)
Picker.SelectedItem = Editor.Instance.ContentDatabase.FindAsset(sceneAsset.ID);
Picker.Validator.SelectedItem = Editor.Instance.ContentDatabase.FindAsset(sceneAsset.ID);
else if (Values[0] is string path)
Picker.SelectedPath = path;
Picker.Validator.SelectedPath = path;
else
Picker.SelectedAsset = Values[0] as Asset;
Picker.Validator.SelectedAsset = Values[0] as Asset;
_isRefreshing = false;
}
}
@@ -171,11 +171,13 @@ namespace FlaxEditor.CustomEditors.Editors
tree.Select(typeNode);
if (addItems)
{
var items = GenericEditor.GetItemsForType(type, type.IsClass, true);
var items = GenericEditor.GetItemsForType(type, type.IsClass, true, true);
foreach (var item in items)
{
if (typed && !typed.IsAssignableFrom(item.Info.ValueType))
continue;
if (item.Info.DeclaringType.Type == typeof(FlaxEngine.Object))
continue; // Skip engine internals
var itemPath = typePath + item.Info.Name;
var node = new TreeNode
{
@@ -3,9 +3,12 @@
using System;
using System.Collections;
using System.Linq;
using FlaxEditor.Content;
using FlaxEditor.CustomEditors.Elements;
using FlaxEditor.CustomEditors.GUI;
using FlaxEditor.GUI.ContextMenu;
using FlaxEditor.GUI.Drag;
using FlaxEditor.SceneGraph;
using FlaxEditor.Scripting;
using FlaxEngine;
using FlaxEngine.GUI;
@@ -110,7 +113,7 @@ namespace FlaxEditor.CustomEditors.Editors
public override void Initialize(LayoutElementsContainer layout)
{
// No support for different collections for now
if (HasDifferentValues || HasDifferentTypes)
if (HasDifferentTypes)
return;
var size = Count;
@@ -135,14 +138,43 @@ namespace FlaxEditor.CustomEditors.Editors
spacing = collection.Spacing;
}
var dragArea = layout.CustomContainer<DragAreaControl>();
dragArea.CustomControl.Editor = this;
dragArea.CustomControl.ElementType = ElementType;
// Check for the AssetReferenceAttribute. In JSON assets, it can be used to filter
// which scripts can be dragged over and dropped on this collection editor.
var assetReference = (AssetReferenceAttribute)attributes?.FirstOrDefault(x => x is AssetReferenceAttribute);
if (assetReference != null)
{
if (string.IsNullOrEmpty(assetReference.TypeName))
{
}
else if (assetReference.TypeName.Length > 1 && assetReference.TypeName[0] == '.')
{
dragArea.CustomControl.ElementType = ScriptType.Null;
dragArea.CustomControl.FileExtension = assetReference.TypeName;
}
else
{
var customType = TypeUtils.GetType(assetReference.TypeName);
if (customType != ScriptType.Null)
dragArea.CustomControl.ElementType = customType;
else if (!Content.Settings.GameSettings.OptionalPlatformSettings.Contains(assetReference.TypeName))
Debug.LogWarning(string.Format("Unknown asset type '{0}' to use for drag and drop filter.", assetReference.TypeName));
else
dragArea.CustomControl.ElementType = ScriptType.Void;
}
}
// Size
if (_readOnly || (NotNullItems && size == 0))
{
layout.Label("Size", size.ToString());
dragArea.Label("Size", size.ToString());
}
else
{
_size = layout.IntegerValue("Size");
_size = dragArea.IntegerValue("Size");
_size.IntValue.MinValue = 0;
_size.IntValue.MaxValue = ushort.MaxValue;
_size.IntValue.Value = size;
@@ -152,7 +184,7 @@ namespace FlaxEditor.CustomEditors.Editors
// Elements
if (size > 0)
{
var panel = layout.VerticalPanel();
var panel = dragArea.VerticalPanel();
panel.Panel.BackgroundColor = _background;
var elementType = ElementType;
@@ -212,37 +244,33 @@ namespace FlaxEditor.CustomEditors.Editors
// Add/Remove buttons
if (!_readOnly)
{
var area = layout.Space(20);
var addButton = new Button(area.ContainerControl.Width - (16 + 16 + 2 + 2), 2, 16, 16)
{
Text = "+",
TooltipText = "Add new item",
AnchorPreset = AnchorPresets.TopRight,
Parent = area.ContainerControl,
Enabled = !NotNullItems || size > 0,
};
addButton.Clicked += () =>
{
if (IsSetBlocked)
return;
var panel = dragArea.HorizontalPanel();
panel.Panel.Size = new Float2(0, 20);
panel.Panel.Margin = new Margin(2);
Resize(Count + 1);
};
var removeButton = new Button(addButton.Right + 2, addButton.Y, 16, 16)
{
Text = "-",
TooltipText = "Remove last item",
AnchorPreset = AnchorPresets.TopRight,
Parent = area.ContainerControl,
Enabled = size > 0,
};
removeButton.Clicked += () =>
var removeButton = panel.Button("-", "Remove last item");
removeButton.Button.Size = new Float2(16, 16);
removeButton.Button.Enabled = size > 0;
removeButton.Button.AnchorPreset = AnchorPresets.TopRight;
removeButton.Button.Clicked += () =>
{
if (IsSetBlocked)
return;
Resize(Count - 1);
};
var addButton = panel.Button("+", "Add new item");
addButton.Button.Size = new Float2(16, 16);
addButton.Button.Enabled = !NotNullItems || size > 0;
addButton.Button.AnchorPreset = AnchorPresets.TopRight;
addButton.Button.Clicked += () =>
{
if (IsSetBlocked)
return;
Resize(Count + 1);
};
}
}
@@ -369,5 +397,232 @@ namespace FlaxEditor.CustomEditors.Editors
}
return base.OnDirty(editor, value, token);
}
private class DragAreaControl : VerticalPanel
{
private DragItems _dragItems;
private DragActors _dragActors;
private DragHandlers _dragHandlers;
private AssetPickerValidator _pickerValidator;
public ScriptType ElementType
{
get => _pickerValidator?.AssetType ?? ScriptType.Null;
set => _pickerValidator = new AssetPickerValidator(value);
}
public CollectionEditor Editor { get; set; }
public string FileExtension
{
set => _pickerValidator.FileExtension = value;
}
/// <inheritdoc />
public override void Draw()
{
if (_dragHandlers is { HasValidDrag: true })
{
var area = new Rectangle(Float2.Zero, Size);
Render2D.FillRectangle(area, Color.Orange * 0.5f);
Render2D.DrawRectangle(area, Color.Black);
}
base.Draw();
}
public override void OnDestroy()
{
_pickerValidator.OnDestroy();
}
private bool ValidateActors(ActorNode node)
{
return node.Actor.GetScript(ElementType.Type) || ElementType.Type.IsAssignableTo(typeof(Actor));
}
/// <inheritdoc />
public override DragDropEffect OnDragEnter(ref Float2 location, DragData data)
{
var result = base.OnDragEnter(ref location, data);
if (result != DragDropEffect.None)
return result;
if (_dragHandlers == null)
{
_dragItems = new DragItems(_pickerValidator.IsValid);
_dragActors = new DragActors(ValidateActors);
_dragHandlers = new DragHandlers
{
_dragActors,
_dragItems
};
}
return _dragHandlers.OnDragEnter(data);
}
/// <inheritdoc />
public override DragDropEffect OnDragMove(ref Float2 location, DragData data)
{
var result = base.OnDragMove(ref location, data);
if (result != DragDropEffect.None)
return result;
return _dragHandlers.Effect;
}
/// <inheritdoc />
public override void OnDragLeave()
{
_dragHandlers.OnDragLeave();
base.OnDragLeave();
}
/// <inheritdoc />
public override DragDropEffect OnDragDrop(ref Float2 location, DragData data)
{
var result = base.OnDragDrop(ref location, data);
if (result != DragDropEffect.None)
{
_dragHandlers.OnDragDrop(null);
return result;
}
if (_dragHandlers.HasValidDrag)
{
if (_dragItems.HasValidDrag)
{
var list = Editor.CloneValues();
if (list == null)
{
if (Editor.Values.Type.IsArray)
{
list = TypeUtils.CreateArrayInstance(Editor.Values.Type.GetElementType(), 0);
}
else
{
list = Editor.Values.Type.CreateInstance() as IList;
}
}
if (list.IsFixedSize)
{
var oldSize = list.Count;
var newSize = list.Count + _dragItems.Objects.Count;
var type = Editor.Values.Type.GetElementType();
var array = TypeUtils.CreateArrayInstance(type, newSize);
list.CopyTo(array, 0);
for (var i = oldSize; i < newSize; i++)
{
var validator = new AssetPickerValidator
{
FileExtension = _pickerValidator.FileExtension,
AssetType = _pickerValidator.AssetType,
SelectedItem = _dragItems.Objects[i - oldSize],
};
if (typeof(AssetItem).IsAssignableFrom(ElementType.Type))
array.SetValue(validator.SelectedItem, i);
else if (ElementType.Type == typeof(Guid))
array.SetValue(validator.SelectedID, i);
else if (ElementType.Type == typeof(SceneReference))
array.SetValue(new SceneReference(validator.SelectedID), i);
else if (ElementType.Type == typeof(string))
array.SetValue(validator.SelectedPath, i);
else
array.SetValue(validator.SelectedAsset, i);
validator.OnDestroy();
}
Editor.SetValue(array);
}
else
{
foreach (var item in _dragItems.Objects)
{
var validator = new AssetPickerValidator
{
FileExtension = _pickerValidator.FileExtension,
AssetType = _pickerValidator.AssetType,
SelectedItem = item,
};
if (typeof(AssetItem).IsAssignableFrom(ElementType.Type))
list.Add(validator.SelectedItem);
else if (ElementType.Type == typeof(Guid))
list.Add(validator.SelectedID);
else if (ElementType.Type == typeof(SceneReference))
list.Add(new SceneReference(validator.SelectedID));
else if (ElementType.Type == typeof(string))
list.Add(validator.SelectedPath);
else
list.Add(validator.SelectedAsset);
validator.OnDestroy();
}
Editor.SetValue(list);
}
}
else if (_dragActors.HasValidDrag)
{
var list = Editor.CloneValues();
if (list == null)
{
if (Editor.Values.Type.IsArray)
{
list = TypeUtils.CreateArrayInstance(Editor.Values.Type.GetElementType(), 0);
}
else
{
list = Editor.Values.Type.CreateInstance() as IList;
}
}
if (list.IsFixedSize)
{
var oldSize = list.Count;
var newSize = list.Count + _dragActors.Objects.Count;
var type = Editor.Values.Type.GetElementType();
var array = TypeUtils.CreateArrayInstance(type, newSize);
list.CopyTo(array, 0);
for (var i = oldSize; i < newSize; i++)
{
var actor = _dragActors.Objects[i - oldSize].Actor;
if (ElementType.Type.IsAssignableTo(typeof(Actor)))
{
array.SetValue(actor, i);
}
else
{
array.SetValue(actor.GetScript(ElementType.Type), i);
}
}
Editor.SetValue(array);
}
else
{
foreach (var actorNode in _dragActors.Objects)
{
if (ElementType.Type.IsAssignableTo(typeof(Actor)))
{
list.Add(actorNode.Actor);
}
else
{
list.Add(actorNode.Actor.GetScript(ElementType.Type));
}
}
Editor.SetValue(list);
}
}
_dragHandlers.OnDragDrop(null);
}
return result;
}
}
}
}
@@ -247,8 +247,9 @@ namespace FlaxEditor.CustomEditors.Editors
/// <param name="type">The type.</param>
/// <param name="useProperties">True if use type properties.</param>
/// <param name="useFields">True if use type fields.</param>
/// <param name="usePropertiesWithoutSetter">True if use type properties that have only getter method without setter method (aka read-only).</param>
/// <returns>The items.</returns>
public static List<ItemInfo> GetItemsForType(ScriptType type, bool useProperties, bool useFields)
public static List<ItemInfo> GetItemsForType(ScriptType type, bool useProperties, bool useFields, bool usePropertiesWithoutSetter = false)
{
var items = new List<ItemInfo>();
@@ -264,7 +265,7 @@ namespace FlaxEditor.CustomEditors.Editors
var showInEditor = attributes.Any(x => x is ShowInEditorAttribute);
// Skip properties without getter or setter
if (!p.HasGet || (!p.HasSet && !showInEditor))
if (!p.HasGet || (!p.HasSet && !showInEditor && !usePropertiesWithoutSetter))
continue;
// Skip hidden fields, handle special attributes
@@ -28,14 +28,16 @@ namespace FlaxEditor.CustomEditors.Editors
var group = layout.Group("Entry");
_group = group;
if (ParentEditor == null)
if (ParentEditor == null || HasDifferentTypes)
return;
var entry = (ModelInstanceEntry)Values[0];
var entryIndex = ParentEditor.ChildrenEditors.IndexOf(this);
var materialLabel = new PropertyNameLabel("Material");
materialLabel.TooltipText = "The mesh surface material used for the rendering.";
if (ParentEditor.ParentEditor?.Values[0] is ModelInstanceActor modelInstance)
var parentEditorValues = ParentEditor.ParentEditor?.Values;
if (parentEditorValues?[0] is ModelInstanceActor modelInstance)
{
// TODO: store _modelInstance and _material in array for each selected model instance actor
_entryIndex = entryIndex;
_modelInstance = modelInstance;
var slots = modelInstance.MaterialSlots;
@@ -56,6 +58,8 @@ namespace FlaxEditor.CustomEditors.Editors
// Create material picker
var materialValue = new CustomValueContainer(new ScriptType(typeof(MaterialBase)), _material, (instance, index) => _material, (instance, index, value) => _material = value as MaterialBase);
for (var i = 1; i < parentEditorValues.Count; i++)
materialValue.Add(_material);
var materialEditor = (AssetRefEditor)_group.Property(materialLabel, materialValue);
materialEditor.Values.SetDefaultValue(defaultValue);
materialEditor.RefreshDefaultValue();
@@ -72,14 +76,14 @@ namespace FlaxEditor.CustomEditors.Editors
return;
_isRefreshing = true;
var slots = _modelInstance.MaterialSlots;
var material = _materialEditor.Picker.SelectedAsset as MaterialBase;
var material = _materialEditor.Picker.Validator.SelectedAsset as MaterialBase;
var defaultMaterial = GPUDevice.Instance.DefaultMaterial;
var value = (ModelInstanceEntry)Values[0];
var prevMaterial = value.Material;
if (!material)
{
// Fallback to default material
_materialEditor.Picker.SelectedAsset = defaultMaterial;
_materialEditor.Picker.Validator.SelectedAsset = defaultMaterial;
value.Material = defaultMaterial;
}
else if (material == slots[_entryIndex].Material)
+40 -264
View File
@@ -5,6 +5,7 @@ using System.IO;
using FlaxEditor.Content;
using FlaxEditor.GUI.Drag;
using FlaxEditor.Scripting;
using FlaxEditor.Utilities;
using FlaxEngine;
using FlaxEngine.GUI;
using FlaxEngine.Utilities;
@@ -17,189 +18,21 @@ namespace FlaxEditor.GUI
/// <seealso cref="Control" />
/// <seealso cref="IContentItemOwner" />
[HideInEditor]
public class AssetPicker : Control, IContentItemOwner
public class AssetPicker : Control
{
private const float DefaultIconSize = 64;
private const float ButtonsOffset = 2;
private const float ButtonsSize = 12;
private Asset _selected;
private ContentItem _selectedItem;
private ScriptType _type;
private string _fileExtension;
private bool _isMouseDown;
private Float2 _mouseDownPos;
private Float2 _mousePos;
private DragItems _dragOverElement;
/// <summary>
/// Gets or sets the selected item.
/// The asset validator. Used to ensure only appropriate items can be picked.
/// </summary>
public ContentItem SelectedItem
{
get => _selectedItem;
set
{
if (_selectedItem == value)
return;
if (value == null)
{
if (_selected == null && _selectedItem is SceneItem)
{
// Deselect scene reference
_selectedItem.RemoveReference(this);
_selectedItem = null;
_selected = null;
OnSelectedItemChanged();
return;
}
// Deselect
_selectedItem?.RemoveReference(this);
_selectedItem = null;
_selected = null;
OnSelectedItemChanged();
}
else if (value is SceneItem item)
{
if (_selectedItem == item)
return;
if (!IsValid(item))
item = null;
// Change value to scene reference (cannot load asset because scene can be already loaded - duplicated ID issue)
_selectedItem?.RemoveReference(this);
_selectedItem = item;
_selected = null;
_selectedItem?.AddReference(this);
OnSelectedItemChanged();
}
else if (value is AssetItem assetItem)
{
SelectedAsset = FlaxEngine.Content.LoadAsync(assetItem.ID);
}
else
{
// Change value
_selectedItem?.RemoveReference(this);
_selectedItem = value;
_selected = null;
OnSelectedItemChanged();
}
}
}
/// <summary>
/// Gets or sets the selected asset identifier.
/// </summary>
public Guid SelectedID
{
get
{
if (_selected != null)
return _selected.ID;
if (_selectedItem is AssetItem assetItem)
return assetItem.ID;
return Guid.Empty;
}
set => SelectedItem = Editor.Instance.ContentDatabase.FindAsset(value);
}
/// <summary>
/// Gets or sets the selected content item path.
/// </summary>
public string SelectedPath
{
get
{
string path = _selectedItem?.Path ?? _selected?.Path;
if (path != null)
{
// Convert into path relative to the project (cross-platform)
var projectFolder = Globals.ProjectFolder;
if (path.StartsWith(projectFolder))
path = path.Substring(projectFolder.Length + 1);
}
return path;
}
set
{
if (string.IsNullOrEmpty(value))
{
SelectedItem = null;
}
else
{
var path = StringUtils.IsRelative(value) ? Path.Combine(Globals.ProjectFolder, value) : value;
SelectedItem = Editor.Instance.ContentDatabase.Find(path);
}
}
}
/// <summary>
/// Gets or sets the selected asset object.
/// </summary>
public Asset SelectedAsset
{
get => _selected;
set
{
// Check if value won't change
if (value == _selected)
return;
// Find item from content database and check it
var item = value ? Editor.Instance.ContentDatabase.FindAsset(value.ID) : null;
if (item != null && !IsValid(item))
item = null;
// Change value
_selectedItem?.RemoveReference(this);
_selectedItem = item;
_selected = value;
_selectedItem?.AddReference(this);
OnSelectedItemChanged();
}
}
/// <summary>
/// Gets or sets the assets types that this picker accepts (it supports types derived from the given type). Use <see cref="ScriptType.Null"/> for generic file picker.
/// </summary>
public ScriptType AssetType
{
get => _type;
set
{
if (_type != value)
{
_type = value;
// Auto deselect if the current value is invalid
if (_selectedItem != null && !IsValid(_selectedItem))
SelectedItem = null;
}
}
}
/// <summary>
/// Gets or sets the content items extensions filter. Null if unused.
/// </summary>
public string FileExtension
{
get => _fileExtension;
set
{
if (_fileExtension != value)
{
_fileExtension = value;
// Auto deselect if the current value is invalid
if (_selectedItem != null && !IsValid(_selectedItem))
SelectedItem = null;
}
}
}
public AssetPickerValidator Validator { get; }
/// <summary>
/// Occurs when selected item gets changed.
@@ -216,38 +49,6 @@ namespace FlaxEditor.GUI
/// </summary>
public bool CanEdit = true;
private bool IsValid(ContentItem item)
{
if (_fileExtension != null && !item.Path.EndsWith(_fileExtension))
return false;
if (CheckValid != null && !CheckValid(item))
return false;
if (_type == ScriptType.Null)
return true;
if (item is AssetItem assetItem)
{
// Faster path for binary items (in-built)
if (assetItem is BinaryAssetItem binaryItem)
return _type.IsAssignableFrom(new ScriptType(binaryItem.Type));
// Type filter
var type = TypeUtils.GetType(assetItem.TypeName);
if (_type.IsAssignableFrom(type))
return true;
// Json assets can contain any type of the object defined by the C# type (data oriented design)
if (assetItem is JsonAssetItem && (_type.Type == typeof(JsonAsset) || _type.Type == typeof(Asset)))
return true;
// Special case for scene asset references
if (_type.Type == typeof(SceneReference) && assetItem is SceneItem)
return true;
}
return false;
}
/// <summary>
/// Initializes a new instance of the <see cref="AssetPicker"/> class.
/// </summary>
@@ -264,7 +65,8 @@ namespace FlaxEditor.GUI
public AssetPicker(ScriptType assetType, Float2 location)
: base(location, new Float2(DefaultIconSize + ButtonsOffset + ButtonsSize, DefaultIconSize))
{
_type = assetType;
Validator = new AssetPickerValidator(assetType);
Validator.SelectedItemChanged += OnSelectedItemChanged;
_mousePos = Float2.Minimum;
}
@@ -275,10 +77,10 @@ namespace FlaxEditor.GUI
{
// Update tooltip
string tooltip;
if (_selectedItem is AssetItem assetItem)
if (Validator.SelectedItem is AssetItem assetItem)
tooltip = assetItem.NamePath;
else
tooltip = SelectedPath;
tooltip = Validator.SelectedPath;
TooltipText = tooltip;
SelectedItemChanged?.Invoke();
@@ -289,37 +91,13 @@ namespace FlaxEditor.GUI
// Do the drag drop operation if has selected element
if (new Rectangle(Float2.Zero, Size).Contains(ref _mouseDownPos))
{
if (_selected != null)
DoDragDrop(DragAssets.GetDragData(_selected));
else if (_selectedItem != null)
DoDragDrop(DragItems.GetDragData(_selectedItem));
if (Validator.SelectedAsset != null)
DoDragDrop(DragAssets.GetDragData(Validator.SelectedAsset));
else if (Validator.SelectedItem != null)
DoDragDrop(DragItems.GetDragData(Validator.SelectedItem));
}
}
/// <inheritdoc />
public void OnItemDeleted(ContentItem item)
{
// Deselect item
SelectedItem = null;
}
/// <inheritdoc />
public void OnItemRenamed(ContentItem item)
{
}
/// <inheritdoc />
public void OnItemReimported(ContentItem item)
{
}
/// <inheritdoc />
public void OnItemDispose(ContentItem item)
{
// Deselect item
SelectedItem = null;
}
private Rectangle IconRect => new Rectangle(0, 0, Height, Height);
private Rectangle Button1Rect => new Rectangle(Height + ButtonsOffset, 0, ButtonsSize, ButtonsSize);
@@ -341,10 +119,10 @@ namespace FlaxEditor.GUI
if (CanEdit)
Render2D.DrawSprite(style.ArrowDown, button1Rect, button1Rect.Contains(_mousePos) ? style.Foreground : style.ForegroundGrey);
if (_selectedItem != null)
if (Validator.SelectedItem != null)
{
// Draw item preview
_selectedItem.DrawThumbnail(ref iconRect);
Validator.SelectedItem.DrawThumbnail(ref iconRect);
// Draw buttons
if (CanEdit)
@@ -363,7 +141,7 @@ namespace FlaxEditor.GUI
{
Render2D.DrawText(
style.FontSmall,
_selectedItem.ShortName,
Validator.SelectedItem.ShortName,
new Rectangle(button1Rect.Right + 2, 0, sizeForTextLeft, ButtonsSize),
style.Foreground,
TextAlignment.Near,
@@ -371,7 +149,7 @@ namespace FlaxEditor.GUI
}
}
// Check if has no item but has an asset (eg. virtual asset)
else if (_selected)
else if (Validator.SelectedAsset)
{
// Draw remove button
Render2D.DrawSprite(style.Cross, button3Rect, button3Rect.Contains(_mousePos) ? style.Foreground : style.ForegroundGrey);
@@ -380,8 +158,8 @@ namespace FlaxEditor.GUI
float sizeForTextLeft = Width - button1Rect.Right;
if (sizeForTextLeft > 30)
{
var name = _selected.GetType().Name;
if (_selected.IsVirtual)
var name = Validator.SelectedAsset.GetType().Name;
if (Validator.SelectedAsset.IsVirtual)
name += " (virtual)";
Render2D.DrawText(
style.FontSmall,
@@ -395,8 +173,8 @@ namespace FlaxEditor.GUI
else
{
// No element selected
Render2D.FillRectangle(iconRect, new Color(0.2f));
Render2D.DrawText(style.FontMedium, "No asset\nselected", iconRect, Color.Wheat, TextAlignment.Center, TextAlignment.Center, TextWrapping.NoWrap, 1.0f, Height / DefaultIconSize);
Render2D.FillRectangle(iconRect, style.BackgroundNormal);
Render2D.DrawText(style.FontMedium, "No asset\nselected", iconRect, Color.Orange, TextAlignment.Center, TextAlignment.Center, TextWrapping.NoWrap, 1.0f, Height / DefaultIconSize);
}
// Check if drag is over
@@ -407,9 +185,7 @@ namespace FlaxEditor.GUI
/// <inheritdoc />
public override void OnDestroy()
{
_selectedItem?.RemoveReference(this);
_selectedItem = null;
_selected = null;
Validator.OnDestroy();
base.OnDestroy();
}
@@ -463,57 +239,57 @@ namespace FlaxEditor.GUI
// Buttons logic
if (!CanEdit)
{
if (Button1Rect.Contains(location) && _selectedItem != null)
if (Button1Rect.Contains(location) && Validator.SelectedItem != null)
{
// Select asset
Editor.Instance.Windows.ContentWin.Select(_selectedItem);
Editor.Instance.Windows.ContentWin.Select(Validator.SelectedItem);
}
}
else if (Button1Rect.Contains(location))
{
Focus();
if (_type != ScriptType.Null)
if (Validator.AssetType != ScriptType.Null)
{
// Show asset picker popup
var popup = AssetSearchPopup.Show(this, Button1Rect.BottomLeft, IsValid, item =>
var popup = AssetSearchPopup.Show(this, Button1Rect.BottomLeft, Validator.IsValid, item =>
{
SelectedItem = item;
Validator.SelectedItem = item;
RootWindow.Focus();
Focus();
});
if (_selected != null)
if (Validator.SelectedAsset != null)
{
var selectedAssetName = Path.GetFileNameWithoutExtension(_selected.Path);
var selectedAssetName = Path.GetFileNameWithoutExtension(Validator.SelectedAsset.Path);
popup.ScrollToAndHighlightItemByName(selectedAssetName);
}
}
else
{
// Show content item picker popup
var popup = ContentSearchPopup.Show(this, Button1Rect.BottomLeft, IsValid, item =>
var popup = ContentSearchPopup.Show(this, Button1Rect.BottomLeft, Validator.IsValid, item =>
{
SelectedItem = item;
Validator.SelectedItem = item;
RootWindow.Focus();
Focus();
});
if (_selectedItem != null)
if (Validator.SelectedItem != null)
{
popup.ScrollToAndHighlightItemByName(_selectedItem.ShortName);
popup.ScrollToAndHighlightItemByName(Validator.SelectedItem.ShortName);
}
}
}
else if (_selected != null || _selectedItem != null)
else if (Validator.SelectedAsset != null || Validator.SelectedItem != null)
{
if (Button2Rect.Contains(location) && _selectedItem != null)
if (Button2Rect.Contains(location) && Validator.SelectedItem != null)
{
// Select asset
Editor.Instance.Windows.ContentWin.Select(_selectedItem);
Editor.Instance.Windows.ContentWin.Select(Validator.SelectedItem);
}
else if (Button3Rect.Contains(location))
{
// Deselect asset
Focus();
SelectedItem = null;
Validator.SelectedItem = null;
}
}
}
@@ -540,10 +316,10 @@ namespace FlaxEditor.GUI
{
Focus();
if (_selectedItem != null && IconRect.Contains(location))
if (Validator.SelectedItem != null && IconRect.Contains(location))
{
// Open it
Editor.Instance.ContentEditing.Open(_selectedItem);
Editor.Instance.ContentEditing.Open(Validator.SelectedItem);
}
// Handled
@@ -557,7 +333,7 @@ namespace FlaxEditor.GUI
// Check if drop asset
if (_dragOverElement == null)
_dragOverElement = new DragItems(IsValid);
_dragOverElement = new DragItems(Validator.IsValid);
if (CanEdit && _dragOverElement.OnDragEnter(data))
{
}
@@ -590,7 +366,7 @@ namespace FlaxEditor.GUI
if (CanEdit && _dragOverElement.HasValidDrag)
{
// Select element
SelectedItem = _dragOverElement.Objects[0];
Validator.SelectedItem = _dragOverElement.Objects[0];
}
// Clear cache
+5
View File
@@ -39,6 +39,11 @@ namespace FlaxEditor.GUI.Dialogs
/// </summary>
public DialogResult Result => _result;
/// <summary>
/// Returns the size of the dialog.
/// </summary>
public Float2 DialogSize => _dialogSize;
/// <summary>
/// Initializes a new instance of the <see cref="Dialog"/> class.
/// </summary>
+39 -30
View File
@@ -465,36 +465,47 @@ namespace FlaxEditor.GUI.Docking
{
if (Parent.Parent is SplitPanel splitter)
{
// Check if has any child panels
var childPanel = new List<DockPanel>(_childPanels);
for (int i = 0; i < childPanel.Count; i++)
// Check if there is another nested dock panel inside this dock panel and extract it here
var childPanels = _childPanels.ToArray();
if (childPanels.Length != 0)
{
// Undock all tabs
var panel = childPanel[i];
int count = panel.TabsCount;
while (count-- > 0)
// Move tabs from child panels into this one
DockWindow selectedTab = null;
foreach (var childPanel in childPanels)
{
panel.GetTab(0).Close();
var childPanelTabs = childPanel.Tabs.ToArray();
for (var i = 0; i < childPanelTabs.Length; i++)
{
var childPanelTab = childPanelTabs[i];
if (selectedTab == null && childPanelTab.IsSelected)
selectedTab = childPanelTab;
childPanel.UndockWindow(childPanelTab);
AddTab(childPanelTab, false);
}
}
if (selectedTab != null)
SelectTab(selectedTab);
}
// Unlink splitter
var splitterParent = splitter.Parent;
Assert.IsNotNull(splitterParent);
splitter.Parent = null;
// Move controls from second split panel to the split panel parent
var scrPanel = Parent == splitter.Panel2 ? splitter.Panel1 : splitter.Panel2;
var srcPanelChildrenCount = scrPanel.ChildrenCount;
for (int i = srcPanelChildrenCount - 1; i >= 0 && scrPanel.ChildrenCount > 0; i--)
else
{
scrPanel.GetChild(i).Parent = splitterParent;
}
Assert.IsTrue(scrPanel.ChildrenCount == 0);
Assert.IsTrue(splitterParent.ChildrenCount == srcPanelChildrenCount);
// Unlink splitter
var splitterParent = splitter.Parent;
Assert.IsNotNull(splitterParent);
splitter.Parent = null;
// Delete
splitter.Dispose();
// Move controls from second split panel to the split panel parent
var scrPanel = Parent == splitter.Panel2 ? splitter.Panel1 : splitter.Panel2;
var srcPanelChildrenCount = scrPanel.ChildrenCount;
for (int i = srcPanelChildrenCount - 1; i >= 0 && scrPanel.ChildrenCount > 0; i--)
{
scrPanel.GetChild(i).Parent = splitterParent;
}
Assert.IsTrue(scrPanel.ChildrenCount == 0);
Assert.IsTrue(splitterParent.ChildrenCount == srcPanelChildrenCount);
// Delete
splitter.Dispose();
}
}
else if (!IsMaster)
{
@@ -582,19 +593,17 @@ namespace FlaxEditor.GUI.Docking
/// Adds the tab.
/// </summary>
/// <param name="window">The window to insert as a tab.</param>
protected virtual void AddTab(DockWindow window)
/// <param name="autoSelect">True if auto-select newly added tab.</param>
protected virtual void AddTab(DockWindow window, bool autoSelect = true)
{
// Dock
_tabs.Add(window);
window.ParentDockPanel = this;
// Select tab
SelectTab(window);
if (autoSelect)
SelectTab(window);
}
private void CreateTabsProxy()
{
// Check if has no tabs proxy created
if (_tabsProxy == null)
{
// Create proxy and make set simple full dock
+23 -14
View File
@@ -13,6 +13,7 @@ namespace FlaxEditor.GUI.Docking
public class DockPanelProxy : ContainerControl
{
private DockPanel _panel;
private double _dragEnterTime = -1;
/// <summary>
/// The is mouse down flag (left button).
@@ -256,8 +257,8 @@ namespace FlaxEditor.GUI.Docking
else
{
tabColor = style.BackgroundHighlighted;
Render2D.DrawLine(tabRect.BottomLeft - new Float2(0 , 1), tabRect.UpperLeft, tabColor);
Render2D.DrawLine(tabRect.BottomRight - new Float2(0 , 1), tabRect.UpperRight, tabColor);
Render2D.DrawLine(tabRect.BottomLeft - new Float2(0, 1), tabRect.UpperLeft, tabColor);
Render2D.DrawLine(tabRect.BottomRight - new Float2(0, 1), tabRect.UpperRight, tabColor);
}
if (tab.Icon.IsValid)
@@ -477,11 +478,7 @@ namespace FlaxEditor.GUI.Docking
var result = base.OnDragEnter(ref location, data);
if (result != DragDropEffect.None)
return result;
if (TrySelectTabUnderLocation(ref location))
return DragDropEffect.Move;
return DragDropEffect.None;
return TrySelectTabUnderLocation(ref location);
}
/// <inheritdoc />
@@ -490,11 +487,15 @@ namespace FlaxEditor.GUI.Docking
var result = base.OnDragMove(ref location, data);
if (result != DragDropEffect.None)
return result;
return TrySelectTabUnderLocation(ref location);
}
if (TrySelectTabUnderLocation(ref location))
return DragDropEffect.Move;
/// <inheritdoc />
public override void OnDragLeave()
{
_dragEnterTime = -1;
return DragDropEffect.None;
base.OnDragLeave();
}
/// <inheritdoc />
@@ -503,17 +504,25 @@ namespace FlaxEditor.GUI.Docking
rect = new Rectangle(0, DockPanel.DefaultHeaderHeight, Width, Height - DockPanel.DefaultHeaderHeight);
}
private bool TrySelectTabUnderLocation(ref Float2 location)
private DragDropEffect TrySelectTabUnderLocation(ref Float2 location)
{
var tab = GetTabAtPos(location, out _);
if (tab != null)
{
// Auto-select tab only if drag takes some time
var time = Platform.TimeSeconds;
if (_dragEnterTime < 0)
_dragEnterTime = time;
if (time - _dragEnterTime < 0.3f)
return DragDropEffect.Link;
_dragEnterTime = -1;
_panel.SelectTab(tab);
Update(0); // Fake update
return true;
return DragDropEffect.Move;
}
return false;
_dragEnterTime = -1;
return DragDropEffect.None;
}
private void ShowContextMenu(DockWindow tab, ref Float2 location)
@@ -72,7 +72,7 @@ namespace FlaxEditor.GUI.Docking
settings.Size = size;
settings.Position = location;
settings.MinimumSize = new Float2(1);
settings.MaximumSize = new Float2(4096);
settings.MaximumSize = Float2.Zero; // Unlimited size
settings.Fullscreen = false;
settings.HasBorder = true;
settings.SupportsTransparency = false;
+15 -2
View File
@@ -14,6 +14,8 @@ namespace FlaxEditor.GUI.Input
[HideInEditor]
public class ColorValueBox : Control
{
private bool _isMouseDown;
/// <summary>
/// Delegate function used for the color picker events handling.
/// </summary>
@@ -134,11 +136,22 @@ namespace FlaxEditor.GUI.Input
Render2D.DrawRectangle(r, IsMouseOver || IsNavFocused ? style.BackgroundSelected : Color.Black);
}
/// <inheritdoc />
public override bool OnMouseDown(Float2 location, MouseButton button)
{
_isMouseDown = true;
return base.OnMouseDown(location, button);
}
/// <inheritdoc />
public override bool OnMouseUp(Float2 location, MouseButton button)
{
Focus();
OnSubmit();
if (_isMouseDown)
{
_isMouseDown = false;
Focus();
OnSubmit();
}
return true;
}
+4 -3
View File
@@ -100,9 +100,10 @@ namespace FlaxEditor.GUI
AutoResize = true;
Offsets = new Margin(0, 0, 0, IconSize);
_mouseOverColor = style.Foreground;
_selectedColor = style.Foreground;
_defaultColor = style.ForegroundGrey;
// Ignoring style on purpose (style would make sense if the icons were white, but they are colored)
_mouseOverColor = new Color(0.8f, 0.8f, 0.8f, 1f);
_selectedColor = Color.White;
_defaultColor = new Color(0.7f, 0.7f, 0.7f, 0.5f);
for (int i = 0; i < platforms.Length; i++)
{
+1 -1
View File
@@ -98,7 +98,7 @@ namespace FlaxEditor.GUI
rect.Width -= leftDepthMargin;
Render2D.PushClip(rect);
Render2D.DrawText(style.FontMedium, text, rect, Color.White, column.CellAlignment, TextAlignment.Center);
Render2D.DrawText(style.FontMedium, text, rect, style.Foreground, column.CellAlignment, TextAlignment.Center);
Render2D.PopClip();
x += width;
+22
View File
@@ -13,6 +13,8 @@ namespace FlaxEditor.GUI.Tabs
[HideInEditor]
public class Tab : ContainerControl
{
internal Tabs _selectedInTabs;
/// <summary>
/// Gets or sets the text.
/// </summary>
@@ -86,5 +88,25 @@ namespace FlaxEditor.GUI.Tabs
{
return new Tabs.TabHeader((Tabs)Parent, this);
}
/// <inheritdoc />
protected override void OnParentChangedInternal()
{
if (_selectedInTabs != null)
_selectedInTabs.SelectedTab = null;
base.OnParentChangedInternal();
}
/// <inheritdoc />
public override void OnDestroy()
{
if (IsDisposing)
return;
if (_selectedInTabs != null)
_selectedInTabs.SelectedTab = null;
base.OnDestroy();
}
}
}
+13 -3
View File
@@ -239,7 +239,7 @@ namespace FlaxEditor.GUI.Tabs
/// </summary>
public Tab SelectedTab
{
get => _selectedIndex == -1 && Children.Count > _selectedIndex + 1 ? null : Children[_selectedIndex + 1] as Tab;
get => _selectedIndex < 0 || Children.Count <= _selectedIndex ? null : Children[_selectedIndex + 1] as Tab;
set => SelectedTabIndex = value != null ? Children.IndexOf(value) - 1 : -1;
}
@@ -263,7 +263,12 @@ namespace FlaxEditor.GUI.Tabs
// Check if index will change
if (_selectedIndex != index)
{
SelectedTab?.OnDeselected();
var prev = SelectedTab;
if (prev != null)
{
prev._selectedInTabs = null;
prev.OnDeselected();
}
_selectedIndex = index;
PerformLayout();
OnSelectedTabChanged();
@@ -342,8 +347,13 @@ namespace FlaxEditor.GUI.Tabs
/// </summary>
protected virtual void OnSelectedTabChanged()
{
var selectedTab = SelectedTab;
SelectedTabChanged?.Invoke(this);
SelectedTab?.OnSelected();
if (selectedTab != null)
{
selectedTab._selectedInTabs = this;
selectedTab.OnSelected();
}
}
/// <inheritdoc />
+5 -4
View File
@@ -627,10 +627,11 @@ namespace FlaxEditor.GUI.Timeline
Parent = this
};
var style = Style.Current;
var headerTopArea = new ContainerControl
{
AutoFocus = false,
BackgroundColor = Style.Current.LightBackground,
BackgroundColor = style.LightBackground,
AnchorPreset = AnchorPresets.HorizontalStretchTop,
Offsets = new Margin(0, 0, 0, HeaderTopAreaHeight),
Parent = _splitter.Panel1
@@ -683,7 +684,7 @@ namespace FlaxEditor.GUI.Timeline
{
AutoFocus = false,
ClipChildren = false,
BackgroundColor = Style.Current.LightBackground,
BackgroundColor = style.LightBackground,
AnchorPreset = AnchorPresets.HorizontalStretchBottom,
Offsets = new Margin(0, 0, -playbackButtonsSize, playbackButtonsSize),
Parent = _splitter.Panel1
@@ -845,7 +846,7 @@ namespace FlaxEditor.GUI.Timeline
_timeIntervalsHeader = new TimeIntervalsHeader(this)
{
AutoFocus = false,
BackgroundColor = Style.Current.Background.RGBMultiplied(0.9f),
BackgroundColor = style.Background.RGBMultiplied(0.9f),
AnchorPreset = AnchorPresets.HorizontalStretchTop,
Offsets = new Margin(0, 0, 0, HeaderTopAreaHeight),
Parent = _splitter.Panel2
@@ -854,7 +855,7 @@ namespace FlaxEditor.GUI.Timeline
{
AutoFocus = false,
ClipChildren = false,
BackgroundColor = Style.Current.Background.RGBMultiplied(0.7f),
BackgroundColor = style.Background.RGBMultiplied(0.7f),
AnchorPreset = AnchorPresets.StretchAll,
Offsets = new Margin(0, 0, HeaderTopAreaHeight, 0),
Parent = _splitter.Panel2
@@ -39,7 +39,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
if (AssetID == value?.ID)
return;
AssetID = value?.ID ?? Guid.Empty;
_picker.SelectedAsset = value;
_picker.Validator.SelectedAsset = value;
OnAssetChanged();
Timeline?.MarkAsEdited();
}
@@ -63,10 +63,10 @@ namespace FlaxEditor.GUI.Timeline.Tracks
private void OnPickerSelectedItemChanged()
{
if (Asset == (TAsset)_picker.SelectedAsset)
if (Asset == (TAsset)_picker.Validator.SelectedAsset)
return;
using (new TrackUndoBlock(this))
Asset = (TAsset)_picker.SelectedAsset;
Asset = (TAsset)_picker.Validator.SelectedAsset;
}
/// <summary>
+6
View File
@@ -106,5 +106,11 @@ namespace FlaxEditor.Gizmo
/// </summary>
/// <param name="nodes">The nodes to select</param>
void Select(List<SceneGraph.SceneGraphNode> nodes);
/// <summary>
/// Spawns the actor in the viewport hierarchy.
/// </summary>
/// <param name="actor">The new actor to spawn.</param>
void Spawn(Actor actor);
}
}
+2 -1
View File
@@ -111,7 +111,8 @@ namespace FlaxEditor.Gizmo
if (isSelected)
{
GetSelectedObjectsBounds(out var selectionBounds, out _);
ray.Position = ray.GetPoint(selectionBounds.Size.Y * 0.5f);
var offset = Mathf.Max(selectionBounds.Size.Y * 0.5f, 1.0f);
ray.Position = ray.GetPoint(offset);
continue;
}
+6 -4
View File
@@ -330,14 +330,15 @@ bool ManagedEditor::CanReloadScripts()
bool ManagedEditor::CanAutoBuildCSG()
{
if (!ManagedEditorOptions.AutoRebuildCSG)
return false;
// Skip calls from non-managed thread (eg. physics worker)
if (!MCore::Thread::IsAttached())
return false;
if (!HasManagedInstance())
return false;
if (!ManagedEditorOptions.AutoRebuildCSG)
return false;
if (Internal_CanAutoBuildCSG == nullptr)
{
Internal_CanAutoBuildCSG = GetClass()->GetMethod("Internal_CanAutoBuildCSG");
@@ -348,14 +349,15 @@ bool ManagedEditor::CanAutoBuildCSG()
bool ManagedEditor::CanAutoBuildNavMesh()
{
if (!ManagedEditorOptions.AutoRebuildNavMesh)
return false;
// Skip calls from non-managed thread (eg. physics worker)
if (!MCore::Thread::IsAttached())
return false;
if (!HasManagedInstance())
return false;
if (!ManagedEditorOptions.AutoRebuildNavMesh)
return false;
if (Internal_CanAutoBuildNavMesh == nullptr)
{
Internal_CanAutoBuildNavMesh = GetClass()->GetMethod("Internal_CanAutoBuildNavMesh");
+1
View File
@@ -124,6 +124,7 @@ namespace FlaxEditor.Modules
if (!Editor.StateMachine.CurrentState.CanEditScene)
return;
undo = Editor.Undo;
Editor.Scene.MarkSceneEdited(actor.Scene);
}
// Record undo for prefab creating (backend links the target instance with the prefab)
+23 -4
View File
@@ -242,7 +242,6 @@ namespace FlaxEditor.Modules
/// <param name="additive">True if don't close opened scenes and just add new scene to them, otherwise will release current scenes and load single one.</param>
public void OpenScene(Guid sceneId, bool additive = false)
{
// Check if cannot change scene now
if (!Editor.StateMachine.CurrentState.CanChangeScene)
return;
@@ -266,13 +265,35 @@ namespace FlaxEditor.Modules
Editor.StateMachine.ChangingScenesState.LoadScene(sceneId, additive);
}
/// <summary>
/// Reload all loaded scenes.
/// </summary>
public void ReloadScenes()
{
if (!Editor.StateMachine.CurrentState.CanChangeScene)
return;
if (!Editor.IsPlayMode)
{
if (CheckSaveBeforeClose())
return;
}
// Reload scenes
foreach (var scene in Level.Scenes)
{
var sceneId = scene.ID;
Level.UnloadScene(scene);
Level.LoadScene(sceneId);
}
}
/// <summary>
/// Closes scene (async).
/// </summary>
/// <param name="scene">The scene.</param>
public void CloseScene(Scene scene)
{
// Check if cannot change scene now
if (!Editor.StateMachine.CurrentState.CanChangeScene)
return;
@@ -296,7 +317,6 @@ namespace FlaxEditor.Modules
/// </summary>
public void CloseAllScenes()
{
// Check if cannot change scene now
if (!Editor.StateMachine.CurrentState.CanChangeScene)
return;
@@ -321,7 +341,6 @@ namespace FlaxEditor.Modules
/// <param name="scene">The scene to not close.</param>
public void CloseAllScenesExcept(Scene scene)
{
// Check if cannot change scene now
if (!Editor.StateMachine.CurrentState.CanChangeScene)
return;
@@ -147,6 +147,17 @@ namespace FlaxEditor.Modules.SourceCodeEditing
}
if (key != null)
xml.TryGetValue(key, out text);
// Customize tooltips for properties to be more human-readable in UI
if (text != null && memberType.HasFlag(MemberTypes.Property) && text.StartsWith("Gets or sets ", StringComparison.Ordinal))
{
text = text.Substring(13);
unsafe
{
fixed (char* e = text)
e[0] = char.ToUpper(e[0]);
}
}
}
}
+7 -4
View File
@@ -39,6 +39,7 @@ namespace FlaxEditor.Modules
ContextMenuSingleSelectGroup<int> _numberOfClientsGroup = new ContextMenuSingleSelectGroup<int>();
private ContextMenuButton _menuFileSaveScenes;
private ContextMenuButton _menuFileReloadScenes;
private ContextMenuButton _menuFileCloseScenes;
private ContextMenuButton _menuFileOpenScriptsProject;
private ContextMenuButton _menuFileGenerateScriptsProjectFiles;
@@ -470,13 +471,13 @@ namespace FlaxEditor.Modules
// Place dialog nearby the target control
var targetControlDesktopCenter = targetControl.PointToScreen(targetControl.Size * 0.5f);
var desktopSize = Platform.GetMonitorBounds(targetControlDesktopCenter);
var pos = targetControlDesktopCenter + new Float2(10.0f, -dialog.Height * 0.5f);
var dialogEnd = pos + dialog.Size;
var pos = targetControlDesktopCenter + new Float2(10.0f, -dialog.DialogSize.Y * 0.5f);
var dialogEnd = pos + dialog.DialogSize;
var desktopEnd = desktopSize.BottomRight - new Float2(10.0f);
if (dialogEnd.X >= desktopEnd.X || dialogEnd.Y >= desktopEnd.Y)
pos = targetControl.PointToScreen(Float2.Zero) - new Float2(10.0f + dialog.Width, dialog.Height);
pos = targetControl.PointToScreen(Float2.Zero) - new Float2(10.0f + dialog.DialogSize.X, dialog.DialogSize.Y);
var desktopBounds = Platform.VirtualDesktopBounds;
pos = Float2.Clamp(pos, desktopBounds.UpperLeft, desktopBounds.BottomRight - dialog.Size);
pos = Float2.Clamp(pos, desktopBounds.UpperLeft, desktopBounds.BottomRight - dialog.DialogSize);
dialog.RootWindow.Window.Position = pos;
// Register for context menu (prevent auto-closing context menu when selecting color)
@@ -527,6 +528,7 @@ namespace FlaxEditor.Modules
_menuFileSaveAll = cm.AddButton("Save All", inputOptions.Save, Editor.SaveAll);
_menuFileSaveScenes = cm.AddButton("Save scenes", inputOptions.SaveScenes, Editor.Scene.SaveScenes);
_menuFileCloseScenes = cm.AddButton("Close scenes", inputOptions.CloseScenes, Editor.Scene.CloseAllScenes);
_menuFileReloadScenes = cm.AddButton("Reload scenes", Editor.Scene.ReloadScenes);
cm.AddSeparator();
_menuFileOpenScriptsProject = cm.AddButton("Open scripts project", inputOptions.OpenScriptsProject, Editor.CodeEditing.OpenSolution);
_menuFileGenerateScriptsProjectFiles = cm.AddButton("Generate scripts project files", inputOptions.GenerateScriptsProject, Editor.ProgressReporting.GenerateScriptsProjectFiles.RunAsync);
@@ -830,6 +832,7 @@ namespace FlaxEditor.Modules
_menuFileSaveScenes.Enabled = hasOpenedScene;
_menuFileCloseScenes.Enabled = hasOpenedScene;
_menuFileReloadScenes.Enabled = hasOpenedScene;
_menuFileGenerateScriptsProjectFiles.Enabled = !Editor.ProgressReporting.GenerateScriptsProjectFiles.IsActive;
c.PerformLayout();
+7 -7
View File
@@ -171,9 +171,13 @@ namespace FlaxEditor.Modules
var mainWindow = MainWindow;
if (mainWindow)
{
var projectPath = Globals.ProjectFolder.Replace('/', '\\');
var platformBit = Platform.Is64BitApp ? "64" : "32";
var title = string.Format("Flax Editor - \'{0}\' ({1}-bit)", projectPath, platformBit);
var projectPath = Globals.ProjectFolder;
#if PLATFORM_WINDOWS
projectPath = projectPath.Replace('/', '\\');
#endif
var engineVersion = Editor.EngineProject.Version;
var engineVersionText = engineVersion.Revision > 0 ? $"{engineVersion.Major}.{engineVersion.Minor}.{engineVersion.Revision}" : $"{engineVersion.Major}.{engineVersion.Minor}";
var title = $"Flax Editor {engineVersionText} - \'{projectPath}\'";
mainWindow.Title = title;
}
}
@@ -735,7 +739,6 @@ namespace FlaxEditor.Modules
settings.Size = Platform.DesktopSize * 0.75f;
settings.StartPosition = WindowStartPosition.CenterScreen;
settings.ShowAfterFirstPaint = true;
#if PLATFORM_WINDOWS
if (!Editor.Instance.Options.Options.Interface.UseNativeWindowSystem)
{
@@ -747,12 +750,9 @@ namespace FlaxEditor.Modules
#elif PLATFORM_LINUX
settings.HasBorder = false;
#endif
MainWindow = Platform.CreateWindow(ref settings);
if (MainWindow == null)
{
// Error
Editor.LogError("Failed to create editor main window!");
return;
}
+11 -3
View File
@@ -76,6 +76,10 @@ namespace FlaxEditor.Options
[EditorDisplay("Common"), EditorOrder(230)]
public InputBinding RotateSelection = new InputBinding(KeyboardKeys.R);
[DefaultValue(typeof(InputBinding), "F11")]
[EditorDisplay("Common"), EditorOrder(240)]
public InputBinding ToggleFullscreen = new InputBinding(KeyboardKeys.F11);
#endregion
#region File
@@ -208,16 +212,20 @@ namespace FlaxEditor.Options
[EditorDisplay("Debugger", "Continue"), EditorOrder(810)]
public InputBinding DebuggerContinue = new InputBinding(KeyboardKeys.F5);
[DefaultValue(typeof(InputBinding), "Shift+F11")]
[EditorDisplay("Debugger", "Unlock mouse in Play Mode"), EditorOrder(820)]
public InputBinding DebuggerUnlockMouse = new InputBinding(KeyboardKeys.F11, KeyboardKeys.Shift);
[DefaultValue(typeof(InputBinding), "F10")]
[EditorDisplay("Debugger", "Step Over"), EditorOrder(820)]
[EditorDisplay("Debugger", "Step Over"), EditorOrder(830)]
public InputBinding DebuggerStepOver = new InputBinding(KeyboardKeys.F10);
[DefaultValue(typeof(InputBinding), "F11")]
[EditorDisplay("Debugger", "Step Into"), EditorOrder(830)]
[EditorDisplay("Debugger", "Step Into"), EditorOrder(840)]
public InputBinding DebuggerStepInto = new InputBinding(KeyboardKeys.F11);
[DefaultValue(typeof(InputBinding), "Shift+F11")]
[EditorDisplay("Debugger", "Step Out"), EditorOrder(840)]
[EditorDisplay("Debugger", "Step Out"), EditorOrder(850)]
public InputBinding DebuggerStepOut = new InputBinding(KeyboardKeys.F11, KeyboardKeys.Shift);
#endregion
+61 -3
View File
@@ -208,13 +208,20 @@ namespace FlaxEditor.Options
// If a non-default style was chosen, switch to that style
string styleName = themeOptions.SelectedStyle;
if (styleName != "Default" && themeOptions.Styles.TryGetValue(styleName, out var style) && style != null)
if (styleName != ThemeOptions.DefaultName && styleName != ThemeOptions.LightDefault && themeOptions.Styles.TryGetValue(styleName, out var style) && style != null)
{
Style.Current = style;
}
else
{
Style.Current = CreateDefaultStyle();
if (styleName == ThemeOptions.LightDefault)
{
Style.Current = CreateLightStyle();
}
else
{
Style.Current = CreateDefaultStyle();
}
}
}
@@ -224,7 +231,6 @@ namespace FlaxEditor.Options
/// <returns>The style object.</returns>
public Style CreateDefaultStyle()
{
// Metro Style colors
var options = Options;
var style = new Style
{
@@ -233,6 +239,7 @@ namespace FlaxEditor.Options
Foreground = Color.FromBgra(0xFFFFFFFF),
ForegroundGrey = Color.FromBgra(0xFFA9A9B3),
ForegroundDisabled = Color.FromBgra(0xFF787883),
ForegroundViewport = Color.FromBgra(0xFFFFFFFF),
BackgroundHighlighted = Color.FromBgra(0xFF54545C),
BorderHighlighted = Color.FromBgra(0xFF6A6A75),
BackgroundSelected = Color.FromBgra(0xFF007ACC),
@@ -274,7 +281,58 @@ namespace FlaxEditor.Options
SharedTooltip = new Tooltip(),
};
style.DragWindow = style.BackgroundSelected * 0.7f;
return style;
}
/// <summary>
/// Creates the light style (2nd default).
/// </summary>
/// <returns>The style object.</returns>
public Style CreateLightStyle()
{
var options = Options;
var style = new Style
{
Background = new Color(0.92f, 0.92f, 0.92f, 1f),
LightBackground = new Color(0.84f, 0.84f, 0.88f, 1f),
DragWindow = new Color(0.0f, 0.26f, 0.43f, 0.70f),
Foreground = new Color(0.0f, 0.0f, 0.0f, 1f),
ForegroundGrey = new Color(0.30f, 0.30f, 0.31f, 1f),
ForegroundDisabled = new Color(0.45f, 0.45f, 0.49f, 1f),
ForegroundViewport = new Color(1.0f, 1.0f, 1.0f, 1f),
BackgroundHighlighted = new Color(0.59f, 0.59f, 0.64f, 1f),
BorderHighlighted = new Color(0.50f, 0.50f, 0.55f, 1f),
BackgroundSelected = new Color(0.00f, 0.46f, 0.78f, 0.78f),
BorderSelected = new Color(0.11f, 0.57f, 0.88f, 0.65f),
BackgroundNormal = new Color(0.67f, 0.67f, 0.75f, 1f),
BorderNormal = new Color(0.59f, 0.59f, 0.64f, 1f),
TextBoxBackground = new Color(0.75f, 0.75f, 0.81f, 1f),
TextBoxBackgroundSelected = new Color(0.73f, 0.73f, 0.80f, 1f),
CollectionBackgroundColor = new Color(0.85f, 0.85f, 0.88f, 1f),
ProgressNormal = new Color(0.03f, 0.65f, 0.12f, 1f),
// Fonts
FontTitle = options.Interface.TitleFont.GetFont(),
FontLarge = options.Interface.LargeFont.GetFont(),
FontMedium = options.Interface.MediumFont.GetFont(),
FontSmall = options.Interface.SmallFont.GetFont(),
// Icons
ArrowDown = Editor.Icons.ArrowDown12,
ArrowRight = Editor.Icons.ArrowRight12,
Search = Editor.Icons.Search12,
Settings = Editor.Icons.Settings12,
Cross = Editor.Icons.Cross12,
CheckBoxIntermediate = Editor.Icons.CheckBoxIntermediate12,
CheckBoxTick = Editor.Icons.CheckBoxTick12,
StatusBarSizeGrip = Editor.Icons.WindowDrag12,
Translate = Editor.Icons.Translate32,
Rotate = Editor.Icons.Rotate32,
Scale = Editor.Icons.Scale32,
Scalar = Editor.Icons.Scalar32,
SharedTooltip = new Tooltip(),
};
return style;
}
+7 -3
View File
@@ -15,6 +15,9 @@ namespace FlaxEditor.Options
[CustomEditor(typeof(ThemeOptionsEditor))]
public sealed class ThemeOptions
{
internal const string DefaultName = "Default";
internal const string LightDefault = "LightDefault";
internal class ThemeOptionsEditor : Editor<ThemeOptions>
{
private LabelElement _infoLabel;
@@ -63,13 +66,14 @@ namespace FlaxEditor.Options
private void ReloadOptions(ComboBox obj)
{
var themeOptions = (ThemeOptions)ParentEditor.Values[0];
var options = new string[themeOptions.Styles.Count + 1];
options[0] = "Default";
var options = new string[themeOptions.Styles.Count + 2];
options[0] = DefaultName;
options[1] = LightDefault;
int i = 0;
foreach (var styleName in themeOptions.Styles.Keys)
{
options[i + 1] = styleName;
options[i + 2] = styleName;
i++;
}
_combobox.ComboBox.SetItems(options);
@@ -25,7 +25,6 @@ namespace FlaxEditor.Progress.Handlers
ScriptsBuilder.ScriptsReloadCalled += () => OnUpdate(0.8f, "Reloading scripts...");
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
ScriptsBuilder.ScriptsReloadEnd += OnScriptsReloadEnd;
ScriptsBuilder.ScriptsReload += OnScriptsReload;
}
private void OnScriptsReloadBegin()
@@ -38,14 +37,6 @@ namespace FlaxEditor.Progress.Handlers
Editor.Instance.Scene.ClearRefsToSceneObjects(true);
}
private void OnScriptsReload()
{
#if !USE_NETCORE
// Clear types cache
Newtonsoft.Json.JsonSerializer.ClearCache();
#endif
}
private void OnCompilationFailed()
{
OnFail("Scripts compilation failed");
@@ -7,6 +7,7 @@ using Real = System.Single;
#endif
using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.SceneGraph.Actors
{
@@ -30,6 +31,13 @@ namespace FlaxEditor.SceneGraph.Actors
// Rotate to match the space (GUI uses upper left corner as a root)
Actor.LocalOrientation = Quaternion.Euler(0, -180, -180);
var uiControl = new UIControl
{
Name = "Canvas Scalar",
Transform = Actor.Transform,
Control = new CanvasScaler()
};
Root.Spawn(uiControl, Actor);
}
/// <inheritdoc />
@@ -266,7 +266,7 @@ namespace FlaxEditor.SceneGraph.GUI
/// <summary>
/// Starts the actor renaming action.
/// </summary>
public void StartRenaming(EditorWindow window)
public void StartRenaming(EditorWindow window, Panel treePanel = null)
{
// Block renaming during scripts reload
if (Editor.Instance.ProgressReporting.CompileScripts.IsActive)
@@ -281,7 +281,13 @@ namespace FlaxEditor.SceneGraph.GUI
(window as PrefabWindow).ScrollingOnTreeView(false);
// Start renaming the actor
var dialog = RenamePopup.Show(this, TextRect, _actorNode.Name, false);
var rect = TextRect;
if (treePanel != null)
{
treePanel.ScrollViewTo(this, true);
rect.Size = new Float2(treePanel.Width - TextRect.Location.X, TextRect.Height);
}
var dialog = RenamePopup.Show(this, rect, _actorNode.Name, false);
dialog.Renamed += OnRenamed;
dialog.Closed += popup =>
{
@@ -207,9 +207,9 @@ void RiderCodeEditor::FindEditors(Array<CodeEditor*>* output)
FileSystem::GetChildDirectories(subDirectories, TEXT("/opt/"));
// Versions installed via JetBrains Toolbox
SearchDirectory(&installations, localAppDataPath / TEXT(".local/share/JetBrains/Toolbox/apps/rider/"));
FileSystem::GetChildDirectories(subDirectories, localAppDataPath / TEXT(".local/share/JetBrains/Toolbox/apps/Rider/ch-0"));
FileSystem::GetChildDirectories(subDirectories, localAppDataPath / TEXT(".local/share/JetBrains/Toolbox/apps/Rider/ch-1")); // Beta versions
SearchDirectory(&installations, localAppDataPath / TEXT("JetBrains/Toolbox/apps/rider/"));
FileSystem::GetChildDirectories(subDirectories, localAppDataPath / TEXT("JetBrains/Toolbox/apps/Rider/ch-0"));
FileSystem::GetChildDirectories(subDirectories, localAppDataPath / TEXT("JetBrains/Toolbox/apps/Rider/ch-1")); // Beta versions
// Detect Flatpak installations
SearchDirectory(&installations,
@@ -78,7 +78,10 @@ void VisualStudioCodeEditor::FindEditors(Array<CodeEditor*>* output)
// Detect Flatpak installations
{
if (Platform::RunProcess(TEXT("/bin/bash -c \"flatpak list --app --columns=application | grep com.visualstudio.code -c\""), String::Empty) == 0)
CreateProcessSettings procSettings;
procSettings.FileName = TEXT("/bin/bash -c \"flatpak list --app --columns=application | grep com.visualstudio.code -c\"");
procSettings.HiddenWindow = true;
if (Platform::CreateProcess(procSettings) == 0)
{
const String runPath(TEXT("flatpak run com.visualstudio.code"));
output->Add(New<VisualStudioCodeEditor>(runPath, false));
+5 -3
View File
@@ -56,12 +56,14 @@ namespace FlaxEditor.States
else if (Editor.Options.Options.General.ForceScriptCompilationOnStartup && !skipCompile)
{
// Generate project files when Cache is missing or was cleared previously
if (!Directory.Exists(Path.Combine(Editor.GameProject?.ProjectFolderPath, "Cache", "Intermediate")) ||
!Directory.Exists(Path.Combine(Editor.GameProject?.ProjectFolderPath, "Cache", "Projects")))
var projectFolderPath = Editor.GameProject?.ProjectFolderPath;
if (!Directory.Exists(Path.Combine(projectFolderPath, "Cache", "Intermediate")) ||
!Directory.Exists(Path.Combine(projectFolderPath, "Cache", "Projects")))
{
var customArgs = Editor.Instance.CodeEditing.SelectedEditor.GenerateProjectCustomArgs;
var customArgs = Editor.CodeEditing.SelectedEditor?.GenerateProjectCustomArgs;
ScriptsBuilder.GenerateProject(customArgs);
}
// Compile scripts before loading any scenes, then we load them and can open scenes
ScriptsBuilder.Compile();
}
@@ -1,7 +1,6 @@
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using FlaxEngine;
using FlaxEditor.Utilities;
using FlaxEngine.Utilities;
namespace FlaxEditor.States
@@ -465,7 +465,7 @@ namespace FlaxEditor.Surface.Archetypes
if (selectedIndex != -1)
{
var index = 5 + selectedIndex * 2;
SetValue(index, _animationPicker.SelectedID);
SetValue(index, _animationPicker.Validator.SelectedID);
}
}
@@ -495,7 +495,7 @@ namespace FlaxEditor.Surface.Archetypes
{
if (isValid)
{
_animationPicker.SelectedID = data1;
_animationPicker.Validator.SelectedID = data1;
_animationSpeed.Value = data0.W;
var path = string.Empty;
@@ -505,7 +505,7 @@ namespace FlaxEditor.Surface.Archetypes
}
else
{
_animationPicker.SelectedID = Guid.Empty;
_animationPicker.Validator.SelectedID = Guid.Empty;
_animationSpeed.Value = 1.0f;
}
_animationPicker.Enabled = isValid;
@@ -288,6 +288,9 @@ namespace FlaxEditor.Surface.Archetypes
}
}
SetValue(2, ids);
// Force refresh UI
ResizeAuto();
}
}
+1 -1
View File
@@ -60,7 +60,7 @@ namespace FlaxEditor.Surface.Archetypes
Op1(1, "Bitwise NOT", "Negates the value using bitwise operation", new[] { "!", "~" }),
Op2(2, "Bitwise AND", "Performs a bitwise conjunction on two values", new[] { "&" }),
Op2(3, "Bitwise OR", "", new[] { "|" }),
Op2(4, "Bitwise XOR", ""),
Op2(4, "Bitwise XOR", "", new[] { "^" }),
};
}
}
+1 -1
View File
@@ -60,7 +60,7 @@ namespace FlaxEditor.Surface.Archetypes
Op1(1, "Boolean NOT", "Negates the boolean value", new[] { "!", "~" }),
Op2(2, "Boolean AND", "Performs a logical conjunction on two values", new[] { "&&" }),
Op2(3, "Boolean OR", "Returns true if either (or both) of its operands is true", new[] { "||" }),
Op2(4, "Boolean XOR", ""),
Op2(4, "Boolean XOR", "", new [] { "^" } ),
Op2(5, "Boolean NOR", ""),
Op2(6, "Boolean NAND", ""),
};
@@ -14,7 +14,7 @@ namespace FlaxEditor.Surface.Archetypes
[HideInEditor]
public static class Comparisons
{
private static NodeArchetype Op(ushort id, string title, string desc)
private static NodeArchetype Op(ushort id, string title, string desc, string[] altTitles = null)
{
return new NodeArchetype
{
@@ -22,6 +22,7 @@ namespace FlaxEditor.Surface.Archetypes
Title = title,
Description = desc,
Flags = NodeFlags.AllGraphs,
AlternativeTitles = altTitles,
ConnectionsHints = ConnectionsHint.Value,
Size = new Float2(100, 40),
IndependentBoxes = new[]
@@ -170,12 +171,12 @@ namespace FlaxEditor.Surface.Archetypes
/// </summary>
public static NodeArchetype[] Nodes =
{
Op(1, "==", "Determines whether two values are equal"),
Op(2, "!=", "Determines whether two values are not equal"),
Op(3, ">", "Determines whether the first value is greater than the other"),
Op(4, "<", "Determines whether the first value is less than the other"),
Op(5, "<=", "Determines whether the first value is less or equal to the other"),
Op(6, ">=", "Determines whether the first value is greater or equal to the other"),
Op(1, "==", "Determines whether two values are equal", new[] { "equals" }),
Op(2, "!=", "Determines whether two values are not equal", new[] { "not equals" }),
Op(3, ">", "Determines whether the first value is greater than the other", new[] { "greater than", "larger than", "bigger than" }),
Op(4, "<", "Determines whether the first value is less than the other", new[] { "less than", "smaller than" }),
Op(5, "<=", "Determines whether the first value is less or equal to the other", new[] { "less equals than", "smaller equals than" }),
Op(6, ">=", "Determines whether the first value is greater or equal to the other", new[] { "greater equals than", "larger equals than", "bigger equals than" }),
new NodeArchetype
{
TypeID = 7,
+121 -1
View File
@@ -7,11 +7,12 @@ using Real = System.Single;
#endif
using System;
using System.Reflection;
using System.Linq;
using FlaxEditor.CustomEditors.Editors;
using FlaxEditor.GUI;
using FlaxEditor.Scripting;
using FlaxEditor.Surface.Elements;
using FlaxEditor.Surface.Undo;
using FlaxEngine;
using FlaxEngine.GUI;
using FlaxEngine.Utilities;
@@ -24,6 +25,109 @@ namespace FlaxEditor.Surface.Archetypes
[HideInEditor]
public static class Constants
{
/// <summary>
/// A special type of node that adds the functionality to convert nodes to parameters.
/// </summary>
internal class ConvertToParameterNode : SurfaceNode
{
private readonly ScriptType _type;
private readonly Func<object[], object> _convertFunction;
/// <inheritdoc />
public ConvertToParameterNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch, ScriptType type, Func<object[], object> convertFunction = null)
: base(id, context, nodeArch, groupArch)
{
_type = type;
_convertFunction = convertFunction;
}
/// <inheritdoc />
public override void OnShowSecondaryContextMenu(FlaxEditor.GUI.ContextMenu.ContextMenu menu, Float2 location)
{
base.OnShowSecondaryContextMenu(menu, location);
menu.AddSeparator();
menu.AddButton("Convert to Parameter", OnConvertToParameter);
}
private void OnConvertToParameter()
{
if (Surface.Owner is not IVisjectSurfaceWindow window)
throw new Exception("Surface owner is not a Visject Surface Window");
Asset asset = Surface.Owner.SurfaceAsset;
if (asset == null || !asset.IsLoaded)
{
Editor.LogError("Asset is null or not loaded");
return;
}
// Add parameter to editor
var paramIndex = Surface.Parameters.Count;
var initValue = _convertFunction == null ? Values[0] : _convertFunction.Invoke(Values);
var paramAction = new AddRemoveParamAction
{
Window = window,
IsAdd = true,
Name = Utilities.Utils.IncrementNameNumber("New parameter", OnParameterRenameValidate),
Type = _type,
Index = paramIndex,
InitValue = initValue,
};
paramAction.Do();
Surface.AddBatchedUndoAction(paramAction);
// Spawn Get Parameter Node based on the added parameter
Guid parameterGuid = Surface.Parameters[paramIndex].ID;
bool undoEnabled = Surface.Undo.Enabled;
Surface.Undo.Enabled = false;
NodeArchetype arch = Surface.GetParameterGetterNodeArchetype(out var groupId);
SurfaceNode node = Surface.Context.SpawnNode(groupId, arch.TypeID, Location, new object[] { parameterGuid });
Surface.Undo.Enabled = undoEnabled;
if (node is not Parameters.SurfaceNodeParamsGet getNode)
throw new Exception("Node is not a ParamsGet node!");
Surface.AddBatchedUndoAction(new AddRemoveNodeAction(getNode, true));
// Recreate connections of constant node
// Constant nodes and parameter nodes should have the same ports, so we can just iterate through the connections
var editConnectionsAction1 = new EditNodeConnections(Context, this);
var editConnectionsAction2 = new EditNodeConnections(Context, node);
var boxes = GetBoxes();
for (int i = 0; i < boxes.Count; i++)
{
Box box = boxes[i];
if (!box.HasAnyConnection)
continue;
if (!getNode.TryGetBox(box.ID, out Box paramBox))
continue;
// Iterating backwards, because the CreateConnection method deletes entries from the box connections when target box IsSingle is set to true
for (int k = box.Connections.Count - 1; k >= 0; k--)
{
Box connectedBox = box.Connections[k];
paramBox.CreateConnection(connectedBox);
}
}
editConnectionsAction1.End();
editConnectionsAction2.End();
Surface.AddBatchedUndoAction(editConnectionsAction1);
Surface.AddBatchedUndoAction(editConnectionsAction2);
// Add undo actions and remove constant node
var removeConstantAction = new AddRemoveNodeAction(this, false);
Surface.AddBatchedUndoAction(removeConstantAction);
removeConstantAction.Do();
Surface.MarkAsEdited();
}
private bool OnParameterRenameValidate(string value)
{
if (Surface.Owner is not IVisjectSurfaceWindow window)
throw new Exception("Surface owner is not a Visject Surface Window");
return !string.IsNullOrWhiteSpace(value) && window.VisjectSurface.Parameters.All(x => x.Name != value);
}
}
private class EnumNode : SurfaceNode
{
private EnumComboBox _picker;
@@ -356,6 +460,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 1,
Title = "Bool",
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(bool))),
Description = "Constant boolean value",
Flags = NodeFlags.AllGraphs,
Size = new Float2(110, 20),
@@ -388,6 +493,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 2,
Title = "Integer",
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(int))),
Description = "Constant integer value",
Flags = NodeFlags.AllGraphs,
Size = new Float2(110, 20),
@@ -415,6 +521,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 3,
Title = "Float",
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(float))),
Description = "Constant floating point",
Flags = NodeFlags.AllGraphs,
Size = new Float2(110, 20),
@@ -442,6 +549,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 4,
Title = "Float2",
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Float2))),
Description = "Constant Float2",
Flags = NodeFlags.AllGraphs,
Size = new Float2(130, 60),
@@ -472,6 +580,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 5,
Title = "Float3",
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Float3))),
Description = "Constant Float3",
Flags = NodeFlags.AllGraphs,
Size = new Float2(130, 80),
@@ -504,6 +613,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 6,
Title = "Float4",
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Float4))),
Description = "Constant Float4",
Flags = NodeFlags.AllGraphs,
Size = new Float2(130, 100),
@@ -538,6 +648,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 7,
Title = "Color",
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Color))),
Description = "RGBA color",
Flags = NodeFlags.AllGraphs,
Size = new Float2(70, 100),
@@ -570,6 +681,8 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 8,
Title = "Rotation",
Create = (id, context, arch, groupArch) =>
new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Quaternion)), values => Quaternion.Euler((float)values[0], (float)values[1], (float)values[2])),
Description = "Euler angle rotation",
Flags = NodeFlags.AnimGraph | NodeFlags.VisualScriptGraph | NodeFlags.ParticleEmitterGraph,
Size = new Float2(110, 60),
@@ -594,6 +707,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 9,
Title = "String",
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(string))),
Description = "Text",
Flags = NodeFlags.VisualScriptGraph | NodeFlags.AnimGraph,
Size = new Float2(200, 20),
@@ -644,6 +758,8 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 12,
Title = "Unsigned Integer",
AlternativeTitles = new[] { "UInt", "U Int" },
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(uint))),
Description = "Constant unsigned integer value",
Flags = NodeFlags.AllGraphs,
Size = new Float2(170, 20),
@@ -683,6 +799,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 15,
Title = "Double",
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(double))),
Description = "Constant floating point",
Flags = NodeFlags.AllGraphs,
Size = new Float2(110, 20),
@@ -700,6 +817,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 16,
Title = "Vector2",
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Vector2))),
Description = "Constant Vector2",
Flags = NodeFlags.AllGraphs,
Size = new Float2(130, 60),
@@ -720,6 +838,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 17,
Title = "Vector3",
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Vector3))),
Description = "Constant Vector3",
Flags = NodeFlags.AllGraphs,
Size = new Float2(130, 80),
@@ -742,6 +861,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 18,
Title = "Vector4",
Create = (id, context, arch, groupArch) => new ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Vector4))),
Description = "Constant Vector4",
Flags = NodeFlags.AllGraphs,
Size = new Float2(130, 100),
+4 -3
View File
@@ -95,7 +95,7 @@ namespace FlaxEditor.Surface.Archetypes
private void OnAssetPickerSelectedItemChanged()
{
SetValue(0, _assetPicker.SelectedID);
SetValue(0, _assetPicker.Validator.SelectedID);
}
private void TryRestoreConnections(Box box, Box[] prevBoxes, ref NodeElementArchetype arch)
@@ -133,7 +133,7 @@ namespace FlaxEditor.Surface.Archetypes
var prevOutputs = _outputs;
// Extract function signature parameters (inputs and outputs packed)
_asset = LoadSignature(_assetPicker.SelectedID, out var typeNames, out var names);
_asset = LoadSignature(_assetPicker.Validator.SelectedID, out var typeNames, out var names);
if (typeNames != null && names != null)
{
var types = new Type[typeNames.Length];
@@ -174,7 +174,7 @@ namespace FlaxEditor.Surface.Archetypes
_outputs[i] = box;
}
Title = _assetPicker.SelectedItem.ShortName;
Title = _assetPicker.Validator.SelectedItem.ShortName;
}
else
{
@@ -2470,6 +2470,7 @@ namespace FlaxEditor.Surface.Archetypes
Title = string.Empty,
Description = "Overrides the base class method with custom implementation",
Flags = NodeFlags.VisualScriptGraph | NodeFlags.NoSpawnViaGUI | NodeFlags.NoSpawnViaPaste,
SortScore = 10,
IsInputCompatible = MethodOverrideNode.IsInputCompatible,
IsOutputCompatible = MethodOverrideNode.IsOutputCompatible,
Size = new Float2(240, 60),
@@ -882,6 +882,60 @@ namespace FlaxEditor.Surface.Archetypes
NodeElementArchetype.Factory.Output(1, "Inv Size", typeof(Float2), 1),
}
},
new NodeArchetype
{
TypeID = 40,
Title = "Rectangle Mask",
Description = "Creates a rectangle mask",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(150, 40),
ConnectionsHints = ConnectionsHint.Vector,
DefaultValues = new object[]
{
new Float2(0.5f, 0.5f),
},
Elements = new[]
{
NodeElementArchetype.Factory.Input(0, "UV", true, typeof(Float2), 0),
NodeElementArchetype.Factory.Input(1, "Rectangle", true, typeof(Float2), 1, 0),
NodeElementArchetype.Factory.Output(0, string.Empty, typeof(float), 2),
}
},
new NodeArchetype
{
TypeID = 41,
Title = "FWidth",
Description = "Creates a partial derivative (fwidth)",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(150, 20),
ConnectionsHints = ConnectionsHint.Numeric,
IndependentBoxes = new[] { 0 },
DependentBoxes = new[] { 1 },
Elements = new[]
{
NodeElementArchetype.Factory.Input(0, "Value", true, null, 0),
NodeElementArchetype.Factory.Output(0, string.Empty, null, 1),
}
},
new NodeArchetype
{
TypeID = 42,
Title = "AA Step",
Description = "Smooth version of step function with less aliasing",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(150, 40),
ConnectionsHints = ConnectionsHint.Vector,
DefaultValues = new object[]
{
0.5f
},
Elements = new[]
{
NodeElementArchetype.Factory.Input(0, "Value", true, typeof(float), 0),
NodeElementArchetype.Factory.Input(1, "Gradient", true, typeof(float), 1, 0),
NodeElementArchetype.Factory.Output(0, string.Empty, typeof(float), 2),
}
},
};
}
}
+11 -3
View File
@@ -13,6 +13,11 @@ namespace FlaxEditor.Surface.Archetypes
public static class Math
{
private static NodeArchetype Op1(ushort id, string title, string desc, ConnectionsHint hints = ConnectionsHint.Numeric, Type type = null)
{
return Op1(id, title, desc, null, hints, type);
}
private static NodeArchetype Op1(ushort id, string title, string desc, string[] altTitles, ConnectionsHint hints = ConnectionsHint.Numeric, Type type = null)
{
return new NodeArchetype
{
@@ -20,6 +25,7 @@ namespace FlaxEditor.Surface.Archetypes
Title = title,
Description = desc,
Flags = NodeFlags.AllGraphs,
AlternativeTitles = altTitles,
Size = new Float2(110, 20),
DefaultType = new ScriptType(type),
ConnectionsHints = hints,
@@ -92,6 +98,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 11,
Title = "Length",
AlternativeTitles = new[] { "Magnitude", "Mag" },
Description = "Returns the length of A vector",
Flags = NodeFlags.AllGraphs,
Size = new Float2(110, 20),
@@ -107,10 +114,10 @@ namespace FlaxEditor.Surface.Archetypes
Op1(13, "Round", "Rounds A to the nearest integer"),
Op1(14, "Saturate", "Clamps A to the range [0, 1]"),
Op1(15, "Sine", "Returns sine of A"),
Op1(16, "Sqrt", "Returns square root of A"),
Op1(16, "Sqrt", "Returns square root of A", new [] { "Square Root", "Square", "Root" }),
Op1(17, "Tangent", "Returns tangent of A"),
Op2(18, "Cross", "Returns the cross product of A and B", ConnectionsHint.None, typeof(Float3)),
Op2(19, "Distance", "Returns a distance scalar between A and B", ConnectionsHint.Vector, null, typeof(float), false),
Op2(19, "Distance", "Returns a distance scalar between A and B", new [] { "Magnitude", "Mag", "Length" }, ConnectionsHint.Vector, null, typeof(float), false),
Op2(20, "Dot", "Returns the dot product of A and B", ConnectionsHint.Vector, null, typeof(float), false),
Op2(21, "Max", "Selects the greater of A and B"),
Op2(22, "Min", "Selects the lesser of A and B"),
@@ -185,7 +192,7 @@ namespace FlaxEditor.Surface.Archetypes
}
},
//
Op1(27, "Negate", "Returns opposite value"),
Op1(27, "Negate", "Returns opposite value", new [] { "Invert" }),
Op1(28, "One Minus", "Returns 1 - value"),
//
new NodeArchetype
@@ -225,6 +232,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 31,
Title = "Mad",
AlternativeTitles = new [] { "Multiply", "Add", "*+" },
Description = "Performs value multiplication and addition at once",
Flags = NodeFlags.AllGraphs,
Size = new Float2(160, 60),
@@ -1084,7 +1084,7 @@ namespace FlaxEditor.Surface.Archetypes
},
Elements = new[]
{
NodeElementArchetype.Factory.Input(0, string.Empty, true, typeof(void), 0),
NodeElementArchetype.Factory.Input(0, string.Empty, false, typeof(void), 0),
NodeElementArchetype.Factory.Input(1, string.Empty, true, ScriptType.Null, 1, 1),
NodeElementArchetype.Factory.Output(0, string.Empty, typeof(void), 2, true),
NodeElementArchetype.Factory.ComboBox(2 + 20, 0, 116)
@@ -3,6 +3,7 @@
using System;
using FlaxEditor.Content.Settings;
using FlaxEditor.GUI;
using FlaxEditor.Scripting;
using FlaxEngine;
namespace FlaxEditor.Surface.Archetypes
@@ -95,6 +96,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 1,
Title = "Texture",
Create = (id, context, arch, groupArch) => new Constants.ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(Texture))),
Description = "Two dimensional texture object",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(140, 120),
@@ -131,6 +133,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 3,
Title = "Cube Texture",
Create = (id, context, arch, groupArch) => new Constants.ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(CubeTexture))),
Description = "Set of 6 textures arranged in a cube",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(140, 120),
@@ -154,6 +157,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 4,
Title = "Normal Map",
Create = (id, context, arch, groupArch) => new Constants.ConvertToParameterNode(id, context, arch, groupArch, new ScriptType(typeof(NormalMap))),
Description = "Two dimensional texture object sampled as a normal map",
Flags = NodeFlags.MaterialGraph,
Size = new Float2(140, 120),
+3 -1
View File
@@ -1483,7 +1483,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 11,
Title = "Comment",
AlternativeTitles = new[] { "//" },
AlternativeTitles = new[] { "//" , "Group" },
TryParseText = (string filterText, out object[] data) =>
{
data = null;
@@ -1510,6 +1510,7 @@ namespace FlaxEditor.Surface.Archetypes
"Comment", // Title
new Color(1.0f, 1.0f, 1.0f, 0.2f), // Color
new Float2(400.0f, 400.0f), // Size
-1, // Order
},
},
CurveNode<float>.GetArchetype(12, "Curve", typeof(float), 0.0f, 1.0f),
@@ -1638,6 +1639,7 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 22,
Title = "As",
AlternativeTitles = new [] { "Cast" },
Create = (id, context, arch, groupArch) => new AsNode(id, context, arch, groupArch),
Description = "Casts the object to a different type. Returns null if cast fails.",
Flags = NodeFlags.VisualScriptGraph | NodeFlags.AnimGraph,
@@ -78,6 +78,7 @@ namespace FlaxEditor.Surface.ContextMenu
if (!Visible)
return;
SortScore += _archetype.SortScore;
if (selectedBox != null && CanConnectTo(selectedBox))
SortScore += 1;
if (Data != null)
@@ -38,13 +38,13 @@ namespace FlaxEditor.Surface.Elements
private void OnNodeValuesChanged()
{
SelectedID = (Guid)ParentNode.Values[Archetype.ValueIndex];
Validator.SelectedID = (Guid)ParentNode.Values[Archetype.ValueIndex];
}
/// <inheritdoc />
protected override void OnSelectedItemChanged()
{
var selectedId = SelectedID;
var selectedId = Validator.SelectedID;
if (ParentNode != null && (Guid)ParentNode.Values[Archetype.ValueIndex] != selectedId)
{
ParentNode.SetValue(Archetype.ValueIndex, selectedId);
+9 -1
View File
@@ -149,6 +149,11 @@ namespace FlaxEditor.Surface
/// </summary>
public object Tag;
/// <summary>
/// Custom score value to use when sorting node archetypes in Editor. If positive (eg. 1, 2) can be used to add more importance for a specific node type.
/// </summary>
public float SortScore;
/// <summary>
/// Default node values. This array supports types: bool, int, float, Vector2, Vector3, Vector4, Color, Rectangle, Guid, string, Matrix and byte[].
/// </summary>
@@ -204,14 +209,17 @@ namespace FlaxEditor.Surface
Size = Size,
Flags = Flags,
Title = Title,
Description = Title,
SubTitle = SubTitle,
Description = Description,
AlternativeTitles = (string[])AlternativeTitles?.Clone(),
Tag = Tag,
SortScore = SortScore,
DefaultValues = (object[])DefaultValues?.Clone(),
DefaultType = DefaultType,
ConnectionsHints = ConnectionsHints,
IndependentBoxes = (int[])IndependentBoxes?.Clone(),
DependentBoxes = (int[])DependentBoxes?.Clone(),
DependentBoxFilter = DependentBoxFilter,
Elements = (NodeElementArchetype[])Elements?.Clone(),
TryParseText = TryParseText,
};
@@ -93,7 +93,7 @@ namespace FlaxEditor.Surface
}
/// <inheritdoc />
protected override NodeArchetype GetParameterGetterNodeArchetype(out ushort groupId)
protected internal override NodeArchetype GetParameterGetterNodeArchetype(out ushort groupId)
{
groupId = 6;
return Archetypes.Parameters.Nodes[1];
+57
View File
@@ -2,6 +2,7 @@
using System;
using FlaxEditor.GUI;
using FlaxEditor.GUI.ContextMenu;
using FlaxEditor.GUI.Input;
using FlaxEngine;
using FlaxEngine.GUI;
@@ -52,6 +53,12 @@ namespace FlaxEditor.Surface
set => SetValue(2, value, false);
}
private int OrderValue
{
get => (int)Values[3];
set => SetValue(3, value, false);
}
/// <inheritdoc />
public SurfaceComment(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch)
: base(id, context, nodeArch, groupArch)
@@ -67,6 +74,19 @@ namespace FlaxEditor.Surface
Title = TitleValue;
Color = ColorValue;
Size = SizeValue;
// Order
// Backwards compatibility - When opening with an older version send the old comments to the back
if (Values.Length < 4)
{
if (IndexInParent > 0)
IndexInParent = 0;
OrderValue = IndexInParent;
}
else if(OrderValue != -1)
{
IndexInParent = OrderValue;
}
}
/// <inheritdoc />
@@ -76,6 +96,10 @@ namespace FlaxEditor.Surface
// Randomize color
Color = ColorValue = Color.FromHSV(new Random().NextFloat(0, 360), 0.7f, 0.25f, 0.8f);
if(OrderValue == -1)
OrderValue = Context.CommentCount - 1;
IndexInParent = OrderValue;
}
/// <inheritdoc />
@@ -314,5 +338,38 @@ namespace FlaxEditor.Surface
Color = ColorValue = color;
Surface.MarkAsEdited(false);
}
/// <inheritdoc />
public override void OnShowSecondaryContextMenu(FlaxEditor.GUI.ContextMenu.ContextMenu menu, Float2 location)
{
base.OnShowSecondaryContextMenu(menu, location);
menu.AddSeparator();
ContextMenuChildMenu cmOrder = menu.AddChildMenu("Order");
{
cmOrder.ContextMenu.AddButton("Bring Forward", () =>
{
if(IndexInParent < Context.CommentCount-1)
IndexInParent++;
OrderValue = IndexInParent;
});
cmOrder.ContextMenu.AddButton("Bring to Front", () =>
{
IndexInParent = Context.CommentCount-1;
OrderValue = IndexInParent;
});
cmOrder.ContextMenu.AddButton("Send Backward", () =>
{
if(IndexInParent > 0)
IndexInParent--;
OrderValue = IndexInParent;
});
cmOrder.ContextMenu.AddButton("Send to Back", () =>
{
IndexInParent = 0;
OrderValue = IndexInParent;
});
}
}
}
}
+1 -20
View File
@@ -3,7 +3,6 @@
using System;
using FlaxEditor.Scripting;
using FlaxEngine;
using FlaxEngine.Utilities;
namespace FlaxEditor.Surface
{
@@ -27,7 +26,7 @@ namespace FlaxEditor.Surface
/// <summary>
/// Parameter unique ID
/// </summary>
public Guid ID;
public Guid ID = Guid.Empty;
/// <summary>
/// Parameter name
@@ -49,23 +48,5 @@ namespace FlaxEditor.Surface
/// </summary>
[NoSerialize, HideInEditor]
public readonly SurfaceMeta Meta = new SurfaceMeta();
/// <summary>
/// Creates the new parameter of the given type.
/// </summary>
/// <param name="type">The type.</param>
/// <param name="name">The name.</param>
/// <returns>The created parameter.</returns>
public static SurfaceParameter Create(ScriptType type, string name)
{
return new SurfaceParameter
{
ID = Guid.NewGuid(),
IsPublic = true,
Name = name,
Type = type,
Value = TypeUtils.GetDefaultValue(type),
};
}
}
}
@@ -151,7 +151,7 @@ namespace FlaxEditor.Surface
/// </summary>
/// <param name="groupId">The group ID.</param>
/// <returns>The node archetype.</returns>
protected virtual NodeArchetype GetParameterGetterNodeArchetype(out ushort groupId)
protected internal virtual NodeArchetype GetParameterGetterNodeArchetype(out ushort groupId)
{
groupId = 6;
return Archetypes.Parameters.Nodes[0];
+12 -1
View File
@@ -716,7 +716,18 @@ namespace FlaxEditor.Surface
return null;
Rectangle surfaceArea = GetNodesBounds(selection).MakeExpanded(80.0f);
return _context.CreateComment(ref surfaceArea, string.IsNullOrEmpty(text) ? "Comment" : text, new Color(1.0f, 1.0f, 1.0f, 0.2f));
// Order below other selected comments
bool hasCommentsSelected = false;
int lowestCommentOrder = int.MaxValue;
for (int i = 0; i < selection.Count; i++)
{
if (selection[i] is not SurfaceComment || selection[i].IndexInParent >= lowestCommentOrder)
continue;
hasCommentsSelected = true;
lowestCommentOrder = selection[i].IndexInParent;
}
return _context.CreateComment(ref surfaceArea, string.IsNullOrEmpty(text) ? "Comment" : text, new Color(1.0f, 1.0f, 1.0f, 0.2f), hasCommentsSelected ? lowestCommentOrder : -1);
}
private static Rectangle GetNodesBounds(List<SurfaceNode> nodes)
@@ -920,12 +920,6 @@ namespace FlaxEditor.Surface
// Link control
control.OnLoaded(action);
control.Parent = RootControl;
if (control is SurfaceComment)
{
// Move comments to the background
control.IndexInParent = 0;
}
}
/// <summary>
+27 -3
View File
@@ -85,6 +85,27 @@ namespace FlaxEditor.Surface
}
}
/// <summary>
/// Gets the amount of surface comments
/// </summary>
/// <remarks>
/// This is used as an alternative to <see cref="Comments"/>, if only the amount of comments is important.
/// Is faster and doesn't allocate as much memory
/// </remarks>
public int CommentCount
{
get
{
int count = 0;
for (int i = 0; i < RootControl.Children.Count; i++)
{
if (RootControl.Children[i] is SurfaceComment)
count++;
}
return count;
}
}
/// <summary>
/// Gets a value indicating whether this context is modified (needs saving and flushing with surface data context source).
/// </summary>
@@ -285,14 +306,16 @@ namespace FlaxEditor.Surface
/// <param name="surfaceArea">The surface area to create comment.</param>
/// <param name="title">The comment title.</param>
/// <param name="color">The comment color.</param>
/// <param name="customOrder">The comment order or -1 to use default.</param>
/// <returns>The comment object</returns>
public virtual SurfaceComment SpawnComment(ref Rectangle surfaceArea, string title, Color color)
public virtual SurfaceComment SpawnComment(ref Rectangle surfaceArea, string title, Color color, int customOrder = -1)
{
var values = new object[]
{
title, // Title
color, // Color
surfaceArea.Size, // Size
customOrder, // Order
};
return (SurfaceComment)SpawnNode(7, 11, surfaceArea.Location, values);
}
@@ -303,11 +326,12 @@ namespace FlaxEditor.Surface
/// <param name="surfaceArea">The surface area to create comment.</param>
/// <param name="title">The comment title.</param>
/// <param name="color">The comment color.</param>
/// <param name="customOrder">The comment order or -1 to use default.</param>
/// <returns>The comment object</returns>
public SurfaceComment CreateComment(ref Rectangle surfaceArea, string title, Color color)
public SurfaceComment CreateComment(ref Rectangle surfaceArea, string title, Color color, int customOrder = -1)
{
// Create comment
var comment = SpawnComment(ref surfaceArea, title, color);
var comment = SpawnComment(ref surfaceArea, title, color, customOrder);
if (comment == null)
{
Editor.LogWarning("Failed to create comment.");
+24 -5
View File
@@ -17,6 +17,7 @@ using FlaxEditor.Viewport.Previews;
using FlaxEditor.Windows.Assets;
using FlaxEngine;
using FlaxEngine.GUI;
using FlaxEngine.Utilities;
namespace FlaxEditor.Surface
{
@@ -258,6 +259,11 @@ namespace FlaxEditor.Surface
/// </summary>
public IVisjectSurfaceWindow Window;
/// <summary>
/// The identifier of the parameter. Empty to auto generate it.
/// </summary>
public Guid Id = Guid.NewGuid();
/// <summary>
/// True if adding, false if removing parameter.
/// </summary>
@@ -278,6 +284,11 @@ namespace FlaxEditor.Surface
/// </summary>
public ScriptType Type;
/// <summary>
/// The value to initialize the parameter with. Can be null to use default one for the parameter type.
/// </summary>
public object InitValue;
/// <inheritdoc />
public string ActionString => IsAdd ? "Add parameter" : "Remove parameter";
@@ -304,7 +315,14 @@ namespace FlaxEditor.Surface
var type = Type;
if (IsAdd && type.Type == typeof(NormalMap))
type = new ScriptType(typeof(Texture));
var param = SurfaceParameter.Create(type, Name);
var param = new SurfaceParameter
{
ID = Id,
IsPublic = true,
Name = Name,
Type = type,
Value = InitValue ?? TypeUtils.GetDefaultValue(type),
};
if (IsAdd && Type.Type == typeof(NormalMap))
param.Value = FlaxEngine.Content.LoadAsyncInternal<Texture>("Engine/Textures/NormalTexture");
Window.VisjectSurface.Parameters.Insert(Index, param);
@@ -725,6 +743,8 @@ namespace FlaxEditor.Surface
protected VisjectSurfaceWindow(Editor editor, AssetItem item, bool useTabs = false)
: base(editor, item)
{
var inputOptions = Editor.Options.Options.Input;
// Undo
_undo = new FlaxEditor.Undo();
_undo.UndoDone += OnUndoRedo;
@@ -775,10 +795,10 @@ namespace FlaxEditor.Surface
// Toolstrip
_saveButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Save64, Save).LinkTooltip("Save");
_toolstrip.AddSeparator();
_undoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Undo64, _undo.PerformUndo).LinkTooltip("Undo (Ctrl+Z)");
_redoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Redo64, _undo.PerformRedo).LinkTooltip("Redo (Ctrl+Y)");
_undoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Undo64, _undo.PerformUndo).LinkTooltip($"Undo ({inputOptions.Undo})");
_redoButton = (ToolStripButton)_toolstrip.AddButton(Editor.Icons.Redo64, _undo.PerformRedo).LinkTooltip($"Redo ({inputOptions.Redo})");
_toolstrip.AddSeparator();
_toolstrip.AddButton(Editor.Icons.Search64, Editor.ContentFinding.ShowSearch).LinkTooltip("Open content search tool (Ctrl+F)");
_toolstrip.AddButton(Editor.Icons.Search64, Editor.ContentFinding.ShowSearch).LinkTooltip($"Open content search tool ({inputOptions.Search})");
_toolstrip.AddButton(editor.Icons.CenterView64, ShowWholeGraph).LinkTooltip("Show whole graph");
// Setup input actions
@@ -1058,7 +1078,6 @@ namespace FlaxEditor.Surface
public virtual void OnParamRemoveUndo()
{
_refreshPropertiesOnLoad = true;
//_propertiesEditor.BuildLayoutOnUpdate();
_propertiesEditor.BuildLayout();
}
+1 -1
View File
@@ -144,7 +144,7 @@ namespace FlaxEditor.Surface
}
/// <inheritdoc />
protected override NodeArchetype GetParameterGetterNodeArchetype(out ushort groupId)
protected internal override NodeArchetype GetParameterGetterNodeArchetype(out ushort groupId)
{
groupId = 6;
return Archetypes.Parameters.Nodes[2];
+7 -2
View File
@@ -18,21 +18,25 @@ namespace FlaxEngine.Tools
/// <summary>
/// Brush radius (world-space).
/// </summary>
[Limit(0)]
public float BrushSize = 50.0f;
/// <summary>
/// Brush paint intensity.
/// </summary>
[Limit(0)]
public float BrushStrength = 2.0f;
/// <summary>
/// Brush paint falloff. Hardens or softens painting.
/// </summary>
[Limit(0)]
public float BrushFalloff = 1.5f;
/// <summary>
/// Value to paint with. Hold Ctrl hey to paint with inverse value (1 - value).
/// </summary>
[Limit(0, 1, 0.01f)]
public float PaintValue = 0.0f;
/// <summary>
@@ -225,6 +229,7 @@ namespace FlaxEngine.Tools
var cloth = _cloth;
if (cloth == null)
return;
var hasPaintInput = Owner.IsLeftMouseButtonDown && !Owner.IsAltKeyDown;
// Perform detailed tracing to find cursor location for the brush
var ray = Owner.MouseRay;
@@ -240,7 +245,7 @@ namespace FlaxEngine.Tools
// Cursor hit other object or nothing
PaintEnd();
if (Owner.IsLeftMouseButtonDown)
if (hasPaintInput)
{
// Select something else
var view = new Ray(Owner.ViewPosition, Owner.ViewDirection);
@@ -253,7 +258,7 @@ namespace FlaxEngine.Tools
}
// Handle painting
if (Owner.IsLeftMouseButtonDown)
if (hasPaintInput)
PaintStart();
else
PaintEnd();
+3 -3
View File
@@ -290,7 +290,7 @@ namespace FlaxEditor.Tools.Terrain
var patchCoord = Gizmo.SelectedPatchCoord;
var chunkCoord = Gizmo.SelectedChunkCoord;
var action = new EditChunkMaterialAction(CarveTab.SelectedTerrain, ref patchCoord, ref chunkCoord, _chunkOverrideMaterial.SelectedAsset as MaterialBase);
var action = new EditChunkMaterialAction(CarveTab.SelectedTerrain, ref patchCoord, ref chunkCoord, _chunkOverrideMaterial.Validator.SelectedAsset as MaterialBase);
action.Do();
CarveTab.Editor.Undo.AddAction(action);
}
@@ -336,12 +336,12 @@ namespace FlaxEditor.Tools.Terrain
_isUpdatingUI = true;
if (terrain.HasPatch(ref patchCoord))
{
_chunkOverrideMaterial.SelectedAsset = terrain.GetChunkOverrideMaterial(ref patchCoord, ref chunkCoord);
_chunkOverrideMaterial.Validator.SelectedAsset = terrain.GetChunkOverrideMaterial(ref patchCoord, ref chunkCoord);
_chunkOverrideMaterial.Enabled = true;
}
else
{
_chunkOverrideMaterial.SelectedAsset = null;
_chunkOverrideMaterial.Validator.SelectedAsset = null;
_chunkOverrideMaterial.Enabled = false;
}
_isUpdatingUI = false;
@@ -86,6 +86,9 @@ namespace FlaxEditor.Viewport
/// <inheritdoc />
public abstract void Select(List<SceneGraphNode> nodes);
/// <inheritdoc />
public abstract void Spawn(Actor actor);
/// <inheritdoc />
protected override bool IsControllingMouse => Gizmos.Active?.IsControllingMouse ?? false;
+23 -252
View File
@@ -5,9 +5,7 @@ using System.Collections.Generic;
using FlaxEditor.Content;
using FlaxEditor.Gizmo;
using FlaxEditor.GUI.ContextMenu;
using FlaxEditor.GUI.Drag;
using FlaxEditor.SceneGraph;
using FlaxEditor.SceneGraph.Actors;
using FlaxEditor.Scripting;
using FlaxEditor.Viewport.Cameras;
using FlaxEditor.Viewport.Modes;
@@ -37,28 +35,8 @@ namespace FlaxEditor.Viewport
private readonly ViewportWidgetButton _rotateSnapping;
private readonly ViewportWidgetButton _scaleSnapping;
private readonly DragAssets<DragDropEventArgs> _dragAssets;
private readonly DragActorType<DragDropEventArgs> _dragActorType = new DragActorType<DragDropEventArgs>(ValidateDragActorType);
private SelectionOutline _customSelectionOutline;
/// <summary>
/// The custom drag drop event arguments.
/// </summary>
/// <seealso cref="FlaxEditor.GUI.Drag.DragEventArgs" />
public class DragDropEventArgs : DragEventArgs
{
/// <summary>
/// The hit.
/// </summary>
public SceneGraphNode Hit;
/// <summary>
/// The hit location.
/// </summary>
public Vector3 HitLocation;
}
/// <summary>
/// The editor sprites rendering effect.
/// </summary>
@@ -137,15 +115,12 @@ namespace FlaxEditor.Viewport
private bool _lockedFocus;
private double _lockedFocusOffset;
private readonly ViewportDebugDrawData _debugDrawData = new ViewportDebugDrawData(32);
private StaticModel _previewStaticModel;
private int _previewModelEntryIndex;
private BrushSurface _previewBrushSurface;
private EditorSpritesRenderer _editorSpritesRenderer;
/// <summary>
/// Drag and drop handlers
/// </summary>
public readonly DragHandlers DragHandlers = new DragHandlers();
public readonly ViewportDragHandlers DragHandlers;
/// <summary>
/// The transform gizmo.
@@ -219,7 +194,7 @@ namespace FlaxEditor.Viewport
: base(Object.New<SceneRenderTask>(), editor.Undo, editor.Scene.Root)
{
_editor = editor;
_dragAssets = new DragAssets<DragDropEventArgs>(ValidateDragItem);
DragHandlers = new ViewportDragHandlers(this, this, ValidateDragItem, ValidateDragActorType);
var inputOptions = editor.Options.Options.Input;
// Prepare rendering task
@@ -408,9 +383,6 @@ namespace FlaxEditor.Viewport
ViewWidgetButtonMenu.AddSeparator();
ViewWidgetButtonMenu.AddButton("Create camera here", CreateCameraAtView);
DragHandlers.Add(_dragActorType);
DragHandlers.Add(_dragAssets);
// Init gizmo modes
{
// Add default modes used by the editor
@@ -430,7 +402,11 @@ namespace FlaxEditor.Viewport
InputActions.Add(options => options.TranslateMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Translate);
InputActions.Add(options => options.RotateMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Rotate);
InputActions.Add(options => options.ScaleMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Scale);
InputActions.Add(options => options.ToggleTransformSpace, () => { OnTransformSpaceToggle(transformSpaceToggle); transformSpaceToggle.Checked = !transformSpaceToggle.Checked; });
InputActions.Add(options => options.ToggleTransformSpace, () =>
{
OnTransformSpaceToggle(transformSpaceToggle);
transformSpaceToggle.Checked = !transformSpaceToggle.Checked;
});
InputActions.Add(options => options.LockFocusSelection, LockFocusSelection);
InputActions.Add(options => options.FocusSelection, FocusSelection);
InputActions.Add(options => options.RotateSelection, RotateSelection);
@@ -530,20 +506,9 @@ namespace FlaxEditor.Viewport
private void OnCollectDrawCalls(ref RenderContext renderContext)
{
if (_previewStaticModel)
{
_debugDrawData.HighlightModel(_previewStaticModel, _previewModelEntryIndex);
}
if (_previewBrushSurface.Brush != null)
{
_debugDrawData.HighlightBrushSurface(_previewBrushSurface);
}
DragHandlers.CollectDrawCalls(_debugDrawData, ref renderContext);
if (ShowNavigation)
{
Editor.Internal_DrawNavMesh();
}
_debugDrawData.OnDraw(ref renderContext);
}
@@ -942,78 +907,14 @@ namespace FlaxEditor.Viewport
base.OnLeftMouseButtonUp();
}
private void GetHitLocation(ref Float2 location, out SceneGraphNode hit, out Vector3 hitLocation, out Vector3 hitNormal)
{
// Get mouse ray and try to hit any object
var ray = ConvertMouseToRay(ref location);
var view = new Ray(ViewPosition, ViewDirection);
var gridPlane = new Plane(Vector3.Zero, Vector3.Up);
var flags = SceneGraphNode.RayCastData.FlagTypes.SkipColliders | SceneGraphNode.RayCastData.FlagTypes.SkipEditorPrimitives;
hit = Editor.Instance.Scene.Root.RayCast(ref ray, ref view, out var closest, out var normal, flags);
if (hit != null)
{
// Use hit location
hitLocation = ray.Position + ray.Direction * closest;
hitNormal = normal;
}
else if (Grid.Enabled && CollisionsHelper.RayIntersectsPlane(ref ray, ref gridPlane, out closest) && closest < 4000.0f)
{
// Use grid location
hitLocation = ray.Position + ray.Direction * closest;
hitNormal = Vector3.Up;
}
else
{
// Use area in front of the viewport
hitLocation = ViewPosition + ViewDirection * 100;
hitNormal = Vector3.Up;
}
}
private void SetDragEffects(ref Float2 location)
{
if (_dragAssets.HasValidDrag && _dragAssets.Objects[0].IsOfType<MaterialBase>())
{
GetHitLocation(ref location, out var hit, out _, out _);
ClearDragEffects();
var material = FlaxEngine.Content.LoadAsync<MaterialBase>(_dragAssets.Objects[0].ID);
if (material.IsDecal)
return;
if (hit is StaticModelNode staticModelNode)
{
_previewStaticModel = (StaticModel)staticModelNode.Actor;
var ray = ConvertMouseToRay(ref location);
_previewStaticModel.IntersectsEntry(ref ray, out _, out _, out _previewModelEntryIndex);
}
else if (hit is BoxBrushNode.SideLinkNode brushSurfaceNode)
{
_previewBrushSurface = brushSurfaceNode.Surface;
}
}
}
private void ClearDragEffects()
{
_previewStaticModel = null;
_previewModelEntryIndex = -1;
_previewBrushSurface = new BrushSurface();
}
/// <inheritdoc />
public override DragDropEffect OnDragEnter(ref Float2 location, DragData data)
{
ClearDragEffects();
DragHandlers.ClearDragEffects();
var result = base.OnDragEnter(ref location, data);
if (result != DragDropEffect.None)
return result;
result = DragHandlers.OnDragEnter(data);
SetDragEffects(ref location);
return result;
return DragHandlers.DragEnter(ref location, data);
}
private bool ValidateDragItem(ContentItem contentItem)
@@ -1042,167 +943,29 @@ namespace FlaxEditor.Viewport
/// <inheritdoc />
public override DragDropEffect OnDragMove(ref Float2 location, DragData data)
{
ClearDragEffects();
DragHandlers.ClearDragEffects();
var result = base.OnDragMove(ref location, data);
if (result != DragDropEffect.None)
return result;
SetDragEffects(ref location);
return DragHandlers.Effect;
return DragHandlers.DragEnter(ref location, data);
}
/// <inheritdoc />
public override void OnDragLeave()
{
ClearDragEffects();
DragHandlers.ClearDragEffects();
DragHandlers.OnDragLeave();
base.OnDragLeave();
}
private Vector3 PostProcessSpawnedActorLocation(Actor actor, ref Vector3 hitLocation)
{
// Refresh actor position to ensure that cached bounds are valid
actor.Position = Vector3.One;
actor.Position = Vector3.Zero;
// Place the object
//var location = hitLocation - (box.Size.Length * 0.5f) * ViewDirection;
var editorBounds = actor.EditorBoxChildren;
var bottomToCenter = actor.Position.Y - editorBounds.Minimum.Y;
var location = hitLocation + new Vector3(0, bottomToCenter, 0);
// Apply grid snapping if enabled
if (UseSnapping || TransformGizmo.TranslationSnapEnable)
{
float snapValue = TransformGizmo.TranslationSnapValue;
location = new Vector3(
(int)(location.X / snapValue) * snapValue,
(int)(location.Y / snapValue) * snapValue,
(int)(location.Z / snapValue) * snapValue);
}
return location;
}
private void Spawn(Actor actor, ref Vector3 hitLocation, ref Vector3 hitNormal)
{
actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation);
var parent = actor.Parent ?? Level.GetScene(0);
actor.Name = Utilities.Utils.IncrementNameNumber(actor.Name, x => parent.GetChild(x) == null);
Editor.Instance.SceneEditing.Spawn(actor);
Focus();
}
private void Spawn(AssetItem item, SceneGraphNode hit, ref Float2 location, ref Vector3 hitLocation, ref Vector3 hitNormal)
{
if (item.IsOfType<MaterialBase>())
{
var material = FlaxEngine.Content.LoadAsync<MaterialBase>(item.ID);
if (material && !material.WaitForLoaded(100) && material.IsDecal)
{
var actor = new Decal
{
Material = material,
LocalOrientation = RootNode.RaycastNormalRotation(ref hitNormal),
Name = item.ShortName
};
DebugDraw.DrawWireArrow(PostProcessSpawnedActorLocation(actor, ref hitNormal), actor.LocalOrientation, 1.0f, Color.Red, 1000000);
Spawn(actor, ref hitLocation, ref hitNormal);
}
else if (hit is StaticModelNode staticModelNode)
{
var staticModel = (StaticModel)staticModelNode.Actor;
var ray = ConvertMouseToRay(ref location);
if (staticModel.IntersectsEntry(ref ray, out _, out _, out var entryIndex))
{
using (new UndoBlock(Undo, staticModel, "Change material"))
staticModel.SetMaterial(entryIndex, material);
}
}
else if (hit is BoxBrushNode.SideLinkNode brushSurfaceNode)
{
using (new UndoBlock(Undo, brushSurfaceNode.Brush, "Change material"))
{
var surface = brushSurfaceNode.Surface;
surface.Material = material;
brushSurfaceNode.Surface = surface;
}
}
return;
}
if (item.IsOfType<SceneAsset>())
{
Editor.Instance.Scene.OpenScene(item.ID, true);
return;
}
{
var actor = item.OnEditorDrop(this);
actor.Name = item.ShortName;
Spawn(actor, ref hitLocation, ref hitNormal);
}
}
private void Spawn(ScriptType item, SceneGraphNode hit, ref Float2 location, ref Vector3 hitLocation, ref Vector3 hitNormal)
{
var actor = item.CreateInstance() as Actor;
if (actor == null)
{
Editor.LogWarning("Failed to spawn actor of type " + item.TypeName);
return;
}
actor.Name = item.Name;
Spawn(actor, ref hitLocation, ref hitNormal);
}
/// <inheritdoc />
public override DragDropEffect OnDragDrop(ref Float2 location, DragData data)
{
ClearDragEffects();
DragHandlers.ClearDragEffects();
var result = base.OnDragDrop(ref location, data);
if (result != DragDropEffect.None)
return result;
// Check if drag sth
Vector3 hitLocation = ViewPosition, hitNormal = -ViewDirection;
SceneGraphNode hit = null;
if (DragHandlers.HasValidDrag)
{
GetHitLocation(ref location, out hit, out hitLocation, out hitNormal);
}
// Drag assets
if (_dragAssets.HasValidDrag)
{
result = _dragAssets.Effect;
// Process items
for (int i = 0; i < _dragAssets.Objects.Count; i++)
{
var item = _dragAssets.Objects[i];
Spawn(item, hit, ref location, ref hitLocation, ref hitNormal);
}
}
// Drag actor type
else if (_dragActorType.HasValidDrag)
{
result = _dragActorType.Effect;
// Process items
for (int i = 0; i < _dragActorType.Objects.Count; i++)
{
var item = _dragActorType.Objects[i];
Spawn(item, hit, ref location, ref hitLocation, ref hitNormal);
}
}
DragHandlers.OnDragDrop(new DragDropEventArgs { Hit = hit, HitLocation = hitLocation });
return result;
return DragHandlers.DragDrop(ref location, data);
}
/// <inheritdoc />
@@ -1211,6 +974,14 @@ namespace FlaxEditor.Viewport
_editor.SceneEditing.Select(nodes);
}
/// <inheritdoc />
public override void Spawn(Actor actor)
{
var parent = actor.Parent ?? Level.GetScene(0);
actor.Name = Utilities.Utils.IncrementNameNumber(actor.Name, x => parent.GetChild(x) == null);
Editor.Instance.SceneEditing.Spawn(actor);
}
/// <inheritdoc />
public override void OnDestroy()
{
+27 -130
View File
@@ -5,9 +5,7 @@ using System.Collections.Generic;
using FlaxEditor.Content;
using FlaxEditor.Gizmo;
using FlaxEditor.GUI.ContextMenu;
using FlaxEditor.GUI.Drag;
using FlaxEditor.SceneGraph;
using FlaxEditor.SceneGraph.Actors;
using FlaxEditor.Scripting;
using FlaxEditor.Viewport.Cameras;
using FlaxEditor.Viewport.Previews;
@@ -56,9 +54,11 @@ namespace FlaxEditor.Viewport
private readonly ViewportDebugDrawData _debugDrawData = new ViewportDebugDrawData(32);
private PrefabSpritesRenderer _spritesRenderer;
private readonly DragAssets _dragAssets;
private readonly DragActorType _dragActorType = new DragActorType(ValidateDragActorType);
private readonly DragHandlers _dragHandlers = new DragHandlers();
/// <summary>
/// Drag and drop handlers
/// </summary>
public readonly ViewportDragHandlers DragHandlers;
/// <summary>
/// The transform gizmo.
@@ -81,7 +81,7 @@ namespace FlaxEditor.Viewport
_window.SelectionChanged += OnSelectionChanged;
Undo = window.Undo;
ViewportCamera = new FPSCamera();
_dragAssets = new DragAssets(ValidateDragItem);
DragHandlers = new ViewportDragHandlers(this, this, ValidateDragItem, ValidateDragActorType);
ShowDebugDraw = true;
ShowEditorPrimitives = true;
Gizmos = new GizmosCollection(this);
@@ -228,14 +228,15 @@ namespace FlaxEditor.Viewport
_gizmoModeScale.Toggled += OnGizmoModeToggle;
gizmoMode.Parent = this;
_dragHandlers.Add(_dragActorType);
_dragHandlers.Add(_dragAssets);
// Setup input actions
InputActions.Add(options => options.TranslateMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Translate);
InputActions.Add(options => options.RotateMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Rotate);
InputActions.Add(options => options.ScaleMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Scale);
InputActions.Add(options => options.ToggleTransformSpace, () => { OnTransformSpaceToggle(transformSpaceToggle); transformSpaceToggle.Checked = !transformSpaceToggle.Checked; });
InputActions.Add(options => options.ToggleTransformSpace, () =>
{
OnTransformSpaceToggle(transformSpaceToggle);
transformSpaceToggle.Checked = !transformSpaceToggle.Checked;
});
InputActions.Add(options => options.FocusSelection, ShowSelectedActors);
SetUpdate(ref _update, OnUpdate);
@@ -267,6 +268,7 @@ namespace FlaxEditor.Viewport
private void OnCollectDrawCalls(ref RenderContext renderContext)
{
DragHandlers.CollectDrawCalls(_debugDrawData, ref renderContext);
_debugDrawData.OnDraw(ref renderContext);
}
@@ -306,6 +308,7 @@ namespace FlaxEditor.Viewport
var orient = ViewOrientation;
((FPSCamera)ViewportCamera).ShowActors(TransformGizmo.SelectedParents, ref orient);
}
/// <inheritdoc />
public EditorViewport Viewport => this;
@@ -354,6 +357,12 @@ namespace FlaxEditor.Viewport
_window.Select(nodes);
}
/// <inheritdoc />
public void Spawn(Actor actor)
{
_window.Spawn(actor);
}
/// <inheritdoc />
protected override bool IsControllingMouse => Gizmos.Active?.IsControllingMouse ?? false;
@@ -669,11 +678,11 @@ namespace FlaxEditor.Viewport
/// <inheritdoc />
public override DragDropEffect OnDragEnter(ref Float2 location, DragData data)
{
DragHandlers.ClearDragEffects();
var result = base.OnDragEnter(ref location, data);
if (result != DragDropEffect.None)
return result;
return _dragHandlers.OnDragEnter(data);
return DragHandlers.DragEnter(ref location, data);
}
private bool ValidateDragItem(ContentItem contentItem)
@@ -685,7 +694,6 @@ namespace FlaxEditor.Viewport
if (assetItem.IsOfType<MaterialBase>())
return true;
}
return false;
}
@@ -697,86 +705,21 @@ namespace FlaxEditor.Viewport
/// <inheritdoc />
public override DragDropEffect OnDragMove(ref Float2 location, DragData data)
{
DragHandlers.ClearDragEffects();
var result = base.OnDragMove(ref location, data);
if (result != DragDropEffect.None)
return result;
return _dragHandlers.Effect;
return DragHandlers.DragEnter(ref location, data);
}
/// <inheritdoc />
public override void OnDragLeave()
{
_dragHandlers.OnDragLeave();
DragHandlers.ClearDragEffects();
DragHandlers.OnDragLeave();
base.OnDragLeave();
}
private Vector3 PostProcessSpawnedActorLocation(Actor actor, ref Vector3 hitLocation)
{
// Place the object
//var location = hitLocation - (box.Size.Length * 0.5f) * ViewDirection;
var location = hitLocation;
// Apply grid snapping if enabled
if (UseSnapping || TransformGizmo.TranslationSnapEnable)
{
float snapValue = TransformGizmo.TranslationSnapValue;
location = new Vector3(
(int)(location.X / snapValue) * snapValue,
(int)(location.Y / snapValue) * snapValue,
(int)(location.Z / snapValue) * snapValue);
}
return location;
}
private void Spawn(AssetItem item, SceneGraphNode hit, ref Float2 location, ref Vector3 hitLocation)
{
if (item is BinaryAssetItem binaryAssetItem)
{
if (typeof(MaterialBase).IsAssignableFrom(binaryAssetItem.Type))
{
if (hit is StaticModelNode staticModelNode)
{
var staticModel = (StaticModel)staticModelNode.Actor;
var ray = ConvertMouseToRay(ref location);
if (staticModel.IntersectsEntry(ref ray, out _, out _, out var entryIndex))
{
var material = FlaxEngine.Content.LoadAsync<MaterialBase>(item.ID);
using (new UndoBlock(Undo, staticModel, "Change material"))
staticModel.SetMaterial(entryIndex, material);
}
}
return;
}
}
{
var actor = item.OnEditorDrop(this);
actor.Name = item.ShortName;
Spawn(actor, ref hitLocation);
}
}
private void Spawn(Actor actor, ref Vector3 hitLocation)
{
actor.Position = PostProcessSpawnedActorLocation(actor, ref hitLocation);
_window.Spawn(actor);
Focus();
}
private void Spawn(ScriptType item, SceneGraphNode hit, ref Vector3 hitLocation)
{
var actor = item.CreateInstance() as Actor;
if (actor == null)
{
Editor.LogWarning("Failed to spawn actor of type " + item.TypeName);
return;
}
actor.Name = item.Name;
Spawn(actor, ref hitLocation);
}
/// <summary>
/// Focuses the viewport on the current selection of the gizmo.
/// </summary>
@@ -814,57 +757,11 @@ namespace FlaxEditor.Viewport
/// <inheritdoc />
public override DragDropEffect OnDragDrop(ref Float2 location, DragData data)
{
DragHandlers.ClearDragEffects();
var result = base.OnDragDrop(ref location, data);
if (result != DragDropEffect.None)
return result;
// Check if drag sth
Vector3 hitLocation = ViewPosition;
SceneGraphNode hit = null;
if (_dragHandlers.HasValidDrag)
{
// Get mouse ray and try to hit any object
var ray = ConvertMouseToRay(ref location);
var view = new Ray(ViewPosition, ViewDirection);
hit = _window.Graph.Root.RayCast(ref ray, ref view, out var closest, SceneGraphNode.RayCastData.FlagTypes.SkipColliders);
if (hit != null)
{
// Use hit location
hitLocation = ray.Position + ray.Direction * closest;
}
else
{
// Use area in front of the viewport
hitLocation = ViewPosition + ViewDirection * 100;
}
}
// Drag assets
if (_dragAssets.HasValidDrag)
{
result = _dragAssets.Effect;
// Process items
for (int i = 0; i < _dragAssets.Objects.Count; i++)
{
var item = _dragAssets.Objects[i];
Spawn(item, hit, ref location, ref hitLocation);
}
}
// Drag actor type
else if (_dragActorType.HasValidDrag)
{
result = _dragActorType.Effect;
// Process items
for (int i = 0; i < _dragActorType.Objects.Count; i++)
{
var item = _dragActorType.Objects[i];
Spawn(item, hit, ref hitLocation);
}
}
return result;
return DragHandlers.DragDrop(ref location, data);
}
/// <inheritdoc />
@@ -7,6 +7,8 @@ using FlaxEngine.GUI;
using FlaxEditor.Viewport.Widgets;
using FlaxEditor.GUI.ContextMenu;
using Object = FlaxEngine.Object;
using FlaxEditor.GUI;
using FlaxEditor.Scripting;
namespace FlaxEditor.Viewport.Previews
{
@@ -49,6 +51,8 @@ namespace FlaxEditor.Viewport.Previews
private Image _guiMaterialControl;
private readonly MaterialBase[] _postFxMaterialsCache = new MaterialBase[1];
private ContextMenu _modelWidgetButtonMenu;
private AssetPicker _customModelPicker;
private Model _customModel;
/// <summary>
/// Gets or sets the material asset to preview. It can be <see cref="FlaxEngine.Material"/> or <see cref="FlaxEngine.MaterialInstance"/>.
@@ -74,15 +78,66 @@ namespace FlaxEditor.Viewport.Previews
get => _selectedModelIndex;
set
{
if (value == -1) // Using Custom Model
return;
if (value < 0 || value > Models.Length)
throw new ArgumentOutOfRangeException();
if (_customModelPicker != null)
_customModelPicker.Validator.SelectedAsset = null;
_selectedModelIndex = value;
_previewModel.Model = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Primitives/" + Models[value]);
_previewModel.Transform = Transforms[value];
}
}
// Used to automatically update which entry is checked.
// TODO: Maybe a better system with predicate bool checks could be used?
private void ResetModelContextMenu()
{
_modelWidgetButtonMenu.ItemsContainer.DisposeChildren();
// Fill out all models
for (int i = 0; i < Models.Length; i++)
{
var index = i;
var button = _modelWidgetButtonMenu.AddButton(Models[index]);
button.ButtonClicked += _ => SelectedModelIndex = index;
button.Checked = SelectedModelIndex == index && _customModel == null;
button.Tag = index;
}
_modelWidgetButtonMenu.AddSeparator();
_customModelPicker = new AssetPicker(new ScriptType(typeof(Model)), Float2.Zero);
// Label button
var customModelPickerLabel = _modelWidgetButtonMenu.AddButton("Custom Model:");
customModelPickerLabel.CloseMenuOnClick = false;
customModelPickerLabel.Checked = _customModel != null;
// Container button
var customModelPickerButton = _modelWidgetButtonMenu.AddButton("");
customModelPickerButton.Height = _customModelPicker.Height + 4;
customModelPickerButton.CloseMenuOnClick = false;
_customModelPicker.Parent = customModelPickerButton;
_customModelPicker.Validator.SelectedAsset = _customModel;
_customModelPicker.SelectedItemChanged += () =>
{
_customModel = _customModelPicker.Validator.SelectedAsset as Model;
if (_customModelPicker.Validator.SelectedAsset == null)
{
SelectedModelIndex = 0;
ResetModelContextMenu();
return;
}
_previewModel.Model = _customModel;
_previewModel.Transform = Transforms[0];
SelectedModelIndex = -1;
ResetModelContextMenu();
};
}
/// <summary>
/// Initializes a new instance of the <see cref="MaterialPreview"/> class.
/// </summary>
@@ -107,17 +162,7 @@ namespace FlaxEditor.Viewport.Previews
{
if (!control.Visible)
return;
_modelWidgetButtonMenu.ItemsContainer.DisposeChildren();
// Fill out all models
for (int i = 0; i < Models.Length; i++)
{
var index = i;
var button = _modelWidgetButtonMenu.AddButton(Models[index]);
button.ButtonClicked += _ => SelectedModelIndex = index;
button.Checked = SelectedModelIndex == index;
button.Tag = index;
}
ResetModelContextMenu();
};
new ViewportWidgetButton("Model", SpriteHandle.Invalid, _modelWidgetButtonMenu)
{

Some files were not shown because too many files have changed in this diff Show More