diff --git a/.github/workflows/build_android.yml b/.github/workflows/build_android.yml index 9b29e46e9..2c99ad118 100644 --- a/.github/workflows/build_android.yml +++ b/.github/workflows/build_android.yml @@ -9,7 +9,7 @@ jobs: runs-on: "windows-2019" steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Vulkan uses: ./.github/actions/vulkan - name: Checkout LFS diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml index 35cf9b828..a860010fd 100644 --- a/.github/workflows/build_linux.yml +++ b/.github/workflows/build_linux.yml @@ -9,7 +9,7 @@ jobs: runs-on: "ubuntu-20.04" steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install dependencies run: | sudo rm -f /etc/apt/sources.list.d/* @@ -32,7 +32,7 @@ jobs: runs-on: "ubuntu-20.04" steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install dependencies run: | sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev diff --git a/.github/workflows/build_mac.yml b/.github/workflows/build_mac.yml index 60263c5d7..33e2668ae 100644 --- a/.github/workflows/build_mac.yml +++ b/.github/workflows/build_mac.yml @@ -9,7 +9,7 @@ jobs: runs-on: "macos-latest" steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Vulkan uses: ./.github/actions/vulkan - name: Checkout LFS @@ -26,7 +26,7 @@ jobs: runs-on: "macos-latest" steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Vulkan uses: ./.github/actions/vulkan - name: Checkout LFS diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build_windows.yml index 1d5c1adbc..ac88b30f4 100644 --- a/.github/workflows/build_windows.yml +++ b/.github/workflows/build_windows.yml @@ -9,7 +9,7 @@ jobs: runs-on: "windows-2019" steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Vulkan uses: ./.github/actions/vulkan - name: Checkout LFS @@ -26,7 +26,7 @@ jobs: runs-on: "windows-2019" steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Vulkan uses: ./.github/actions/vulkan - name: Checkout LFS diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index f5c8726b6..d5149a652 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -12,7 +12,7 @@ jobs: runs-on: "windows-2019" steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout LFS run: | git lfs version @@ -23,12 +23,12 @@ jobs: run: | .\PackageEditor.bat -arch=x64 -platform=Windows -deployOutput=Output - name: Upload - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: Windows-Editor path: Output/Editor.zip - name: Upload - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: Windows-EditorDebugSymbols path: Output/EditorDebugSymbols.zip @@ -37,7 +37,7 @@ jobs: runs-on: "windows-2019" steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout LFS run: | git lfs version @@ -48,7 +48,7 @@ jobs: run: | .\PackagePlatforms.bat -arch=x64 -platform=Windows -deployOutput=Output - name: Upload - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: Windows-Game path: Output/Windows.zip @@ -59,7 +59,7 @@ jobs: runs-on: "ubuntu-20.04" steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout LFS run: | git lfs version @@ -76,7 +76,7 @@ jobs: run: | ./PackageEditor.sh -arch=x64 -platform=Linux -deployOutput=Output - name: Upload - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: Linux-Editor path: Output/FlaxEditorLinux.zip @@ -85,7 +85,7 @@ jobs: runs-on: "ubuntu-20.04" steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout LFS run: | git lfs version @@ -102,7 +102,7 @@ jobs: run: | ./PackagePlatforms.sh -arch=x64 -platform=Linux -deployOutput=Output - name: Upload - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: Linux-Game path: Output/Linux.zip @@ -113,7 +113,7 @@ jobs: runs-on: "macos-latest" steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout LFS run: | git lfs version @@ -124,7 +124,7 @@ jobs: run: | ./PackageEditor.command -arch=x64 -platform=Mac -deployOutput=Output - name: Upload - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: Mac-Editor path: Output/FlaxEditorMac.zip @@ -133,7 +133,7 @@ jobs: runs-on: "macos-latest" steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout LFS run: | git lfs version @@ -144,7 +144,7 @@ jobs: run: | ./PackagePlatforms.command -arch=x64 -platform=Mac -deployOutput=Output - name: Upload - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: Mac-Game path: Output/Mac.zip diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ecf58ac89..e326fa28d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -9,7 +9,7 @@ jobs: runs-on: "ubuntu-20.04" steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Checkout LFS run: | git lfs version diff --git a/README.md b/README.md index f37a11d19..4ef31c91c 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,9 @@ Flax Visual Studio extension provides better programming workflow, C# scripts de ## Windows * Install Visual Studio 2015 or newer -* Install Windows 8.1 SDK or newer -* Install Microsoft Visual C++ 2015 v140 toolset or newer +* Install Windows 8.1 SDK or newer (via Visual Studio Installer) +* Install Microsoft Visual C++ 2015 v140 toolset or newer (via Visual Studio Installer) +* Install .Net Framework 4.5.2 SDK/Targeting Pack (via Visual Studio Installer) * Clone repo (with LFS) * Run **GenerateProjectFiles.bat** * Open `Flax.sln` and set solution configuration to **Editor.Development** and solution platform to **Win64** diff --git a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs index 91c8c1a92..1d10ef687 100644 --- a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs +++ b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs @@ -9,6 +9,8 @@ using FlaxEditor.GUI.Drag; using FlaxEditor.GUI.Tree; using FlaxEditor.Scripting; using FlaxEditor.Utilities; +using FlaxEditor.Windows; +using FlaxEditor.Windows.Assets; using FlaxEngine; using FlaxEngine.GUI; using Object = FlaxEngine.Object; @@ -266,7 +268,7 @@ namespace FlaxEditor.SceneGraph.GUI /// /// Starts the actor renaming action. /// - public void StartRenaming() + public void StartRenaming(EditorWindow window) { // Block renaming during scripts reload if (Editor.Instance.ProgressReporting.CompileScripts.IsActive) @@ -274,16 +276,22 @@ namespace FlaxEditor.SceneGraph.GUI Select(); - // Disable scrolling of scene view - Editor.Instance.Windows.SceneWin.ScrollingOnSceneTreeView(false); + // Disable scrolling of view + if (window is SceneTreeWindow) + (window as SceneTreeWindow).ScrollingOnSceneTreeView(false); + else if (window is PrefabWindow) + (window as PrefabWindow).ScrollingOnTreeView(false); // Start renaming the actor var dialog = RenamePopup.Show(this, HeaderRect, _actorNode.Name, false); dialog.Renamed += OnRenamed; dialog.Closed += popup => { - // Enable scrolling of scene view - Editor.Instance.Windows.SceneWin.ScrollingOnSceneTreeView(true); + // Enable scrolling of view + if (window is SceneTreeWindow) + (window as SceneTreeWindow).ScrollingOnSceneTreeView(true); + else if (window is PrefabWindow) + (window as PrefabWindow).ScrollingOnTreeView(true); }; } @@ -291,9 +299,6 @@ namespace FlaxEditor.SceneGraph.GUI { using (new UndoBlock(ActorNode.Root.Undo, Actor, "Rename")) Actor.Name = renamePopup.Text; - - // Enable scrolling of scene view - Editor.Instance.Windows.SceneWin.ScrollingOnSceneTreeView(true); } /// diff --git a/Source/Editor/Windows/Assets/PrefabWindow.Actions.cs b/Source/Editor/Windows/Assets/PrefabWindow.Actions.cs index d16bc13f6..fc7a9123d 100644 --- a/Source/Editor/Windows/Assets/PrefabWindow.Actions.cs +++ b/Source/Editor/Windows/Assets/PrefabWindow.Actions.cs @@ -153,6 +153,9 @@ namespace FlaxEditor.Windows.Assets { OnPasteAction(pasteAction); } + + // Scroll to new selected node + ScrollToSelectedNode(); } /// @@ -180,6 +183,9 @@ namespace FlaxEditor.Windows.Assets { OnPasteAction(pasteAction); } + + // Scroll to new selected node + ScrollToSelectedNode(); } private void OnPasteAction(PasteActorsAction pasteAction) @@ -328,6 +334,9 @@ namespace FlaxEditor.Windows.Assets }, action2.ActionString); action.Do(); Undo.AddAction(action); + + _treePanel.PerformLayout(); + _treePanel.PerformLayout(); } } } diff --git a/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs b/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs index 26c7af2e3..c80ecf0c5 100644 --- a/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs +++ b/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs @@ -67,7 +67,7 @@ namespace FlaxEditor.Windows.Assets private DragHandlers _dragHandlers; public SceneTreePanel(PrefabWindow window) - : base(ScrollBars.Vertical) + : base(ScrollBars.None) { _window = window; Offsets = Margin.Zero; @@ -246,24 +246,53 @@ namespace FlaxEditor.Windows.Assets // Spawning actors options contextMenu.AddSeparator(); - var spawnMenu = contextMenu.AddChildMenu("New"); - var newActorCm = spawnMenu.ContextMenu; - for (int i = 0; i < SceneTreeWindow.SpawnActorsGroups.Length; i++) - { - var group = SceneTreeWindow.SpawnActorsGroups[i]; - if (group.Types.Length == 1) + // Go through each actor and add it to the context menu if it has the ActorContextMenu attribute + foreach (var actorType in Editor.CodeEditing.Actors.Get()) + { + if (actorType.IsAbstract) + continue; + ActorContextMenuAttribute attribute = null; + foreach (var e in actorType.GetAttributes(true)) { - var type = group.Types[0].Value; - newActorCm.AddButton(group.Types[0].Key, () => Spawn(type)); - } - else - { - var groupCm = newActorCm.AddChildMenu(group.Name).ContextMenu; - for (int j = 0; j < group.Types.Length; j++) + if (e is ActorContextMenuAttribute actorContextMenuAttribute) { - var type = group.Types[j].Value; - groupCm.AddButton(group.Types[j].Key, () => Spawn(type)); + attribute = actorContextMenuAttribute; + break; + } + } + if (attribute == null) + continue; + var splitPath = attribute.Path.Split('/'); + ContextMenuChildMenu childCM = null; + bool mainCM = true; + for (int i = 0; i < splitPath?.Length; i++) + { + if (i == splitPath.Length - 1) + { + if (mainCM) + { + contextMenu.AddButton(splitPath[i].Trim(), () => Spawn(actorType.Type)); + mainCM = false; + } + else + { + childCM?.ContextMenu.AddButton(splitPath[i].Trim(), () => Spawn(actorType.Type)); + childCM.ContextMenu.AutoSort = true; + } + } + else + { + if (mainCM) + { + childCM = contextMenu.GetOrAddChildMenu(splitPath[i].Trim()); + mainCM = false; + } + else + { + childCM = childCM?.ContextMenu.GetOrAddChildMenu(splitPath[i].Trim()); + } + childCM.ContextMenu.AutoSort = true; } } } @@ -310,7 +339,7 @@ namespace FlaxEditor.Windows.Assets { if (selection.Count != 0) Select(actor); - actor.TreeNode.StartRenaming(); + actor.TreeNode.StartRenaming(this); } } diff --git a/Source/Editor/Windows/Assets/PrefabWindow.cs b/Source/Editor/Windows/Assets/PrefabWindow.cs index 3a4e544c1..78d210592 100644 --- a/Source/Editor/Windows/Assets/PrefabWindow.cs +++ b/Source/Editor/Windows/Assets/PrefabWindow.cs @@ -23,6 +23,7 @@ namespace FlaxEditor.Windows.Assets private readonly SplitPanel _split1; private readonly SplitPanel _split2; private readonly TextBox _searchBox; + private readonly Panel _treePanel; private readonly PrefabTree _tree; private readonly PrefabWindowViewport _viewport; private readonly CustomEditorPresenter _propertiesEditor; @@ -132,17 +133,26 @@ namespace FlaxEditor.Windows.Assets }; _searchBox.TextChanged += OnSearchBoxTextChanged; + _treePanel = new Panel() + { + AnchorPreset = AnchorPresets.StretchAll, + Offsets = new Margin(0.0f, 0.0f, headerPanel.Bottom, 0.0f), + ScrollBars = ScrollBars.Both, + IsScrollable = true, + Parent = sceneTreePanel, + }; + // Prefab structure tree Graph = new LocalSceneGraph(new CustomRootNode(this)); _tree = new PrefabTree { - Y = headerPanel.Bottom, Margin = new Margin(0.0f, 0.0f, -16.0f, 0.0f), // Hide root node + IsScrollable = true, }; _tree.AddChild(Graph.Root.TreeNode); _tree.SelectedChanged += OnTreeSelectedChanged; _tree.RightClick += OnTreeRightClick; - _tree.Parent = sceneTreePanel; + _tree.Parent = _treePanel; headerPanel.Parent = sceneTreePanel; // Prefab viewport @@ -192,6 +202,32 @@ namespace FlaxEditor.Windows.Assets InputActions.Add(options => options.Rename, Rename); InputActions.Add(options => options.FocusSelection, _viewport.FocusSelection); } + + /// + /// Enables or disables vertical and horizontal scrolling on the tree panel. + /// + /// The state to set scrolling to + public void ScrollingOnTreeView(bool enabled) + { + if (_treePanel.VScrollBar != null) + _treePanel.VScrollBar.ThumbEnabled = enabled; + if (_treePanel.HScrollBar != null) + _treePanel.HScrollBar.ThumbEnabled = enabled; + } + + /// + /// Scrolls to the selected node in the tree. + /// + public void ScrollToSelectedNode() + { + // Scroll to node + var nodeSelection = _tree.Selection; + if (nodeSelection.Count != 0) + { + var scrollControl = nodeSelection[nodeSelection.Count - 1]; + _treePanel.ScrollViewTo(scrollControl); + } + } private void OnSearchBoxTextChanged() { @@ -211,6 +247,28 @@ namespace FlaxEditor.Windows.Assets PerformLayout(); } + /// + public override bool OnMouseUp(Float2 location, MouseButton button) + { + if (base.OnMouseUp(location, button)) + return true; + + if (button == MouseButton.Right && _treePanel.ContainsPoint(ref location)) + { + _tree.Deselect(); + var locationCM = location + _searchBox.BottomLeft; + ShowContextMenu(Parent, ref locationCM); + return true; + } + + if (button == MouseButton.Left && _treePanel.ContainsPoint(ref location)) + { + _tree.Deselect(); + return true; + } + return false; + } + private void OnScriptsReloadBegin() { _isScriptsReloading = true; diff --git a/Source/Editor/Windows/SceneTreeWindow.ContextMenu.cs b/Source/Editor/Windows/SceneTreeWindow.ContextMenu.cs index bef3f1b3c..a9c946c46 100644 --- a/Source/Editor/Windows/SceneTreeWindow.ContextMenu.cs +++ b/Source/Editor/Windows/SceneTreeWindow.ContextMenu.cs @@ -60,23 +60,57 @@ namespace FlaxEditor.Windows if (isSingleActorSelected) { var convertMenu = contextMenu.AddChildMenu("Convert"); - var convertActorCm = convertMenu.ContextMenu; - for (int i = 0; i < SpawnActorsGroups.Length; i++) + convertMenu.ContextMenu.AutoSort = true; + foreach (var actorType in Editor.CodeEditing.Actors.Get()) { - var group = SpawnActorsGroups[i]; + if (actorType.IsAbstract) + continue; - if (group.Types.Length == 1) + ActorContextMenuAttribute attribute = null; + foreach (var e in actorType.GetAttributes(true)) { - var type = group.Types[0].Value; - convertActorCm.AddButton(group.Types[0].Key, () => Editor.SceneEditing.Convert(type)); - } - else - { - var groupCm = convertActorCm.AddChildMenu(group.Name).ContextMenu; - for (int j = 0; j < group.Types.Length; j++) + if (e is ActorContextMenuAttribute actorContextMenuAttribute) { - var type = group.Types[j].Value; - groupCm.AddButton(group.Types[j].Key, () => Editor.SceneEditing.Convert(type)); + attribute = actorContextMenuAttribute; + break; + } + } + if (attribute == null) + continue; + var splitPath = attribute?.Path.Split('/'); + ContextMenuChildMenu childCM = convertMenu; + bool mainCM = true; + for (int i = 0; i < splitPath?.Length; i++) + { + if (i == splitPath.Length - 1) + { + if (mainCM) + { + convertMenu.ContextMenu.AddButton(splitPath[i].Trim(), () => Editor.SceneEditing.Convert(actorType.Type)); + mainCM = false; + } + else + { + childCM?.ContextMenu.AddButton(splitPath[i].Trim(), () => Editor.SceneEditing.Convert(actorType.Type)); + childCM.ContextMenu.AutoSort = true; + } + } + else + { + // Remove new path for converting menu + if (splitPath[i] == "New") + continue; + + if (mainCM) + { + childCM = convertMenu.ContextMenu.GetOrAddChildMenu(splitPath[i].Trim()); + mainCM = false; + } + else + { + childCM = childCM?.ContextMenu.GetOrAddChildMenu(splitPath[i].Trim()); + } + childCM.ContextMenu.AutoSort = true; } } } @@ -114,24 +148,50 @@ namespace FlaxEditor.Windows contextMenu.AddSeparator(); - var spawnMenu = contextMenu.AddChildMenu("New"); - var newActorCm = spawnMenu.ContextMenu; - for (int i = 0; i < SpawnActorsGroups.Length; i++) + // go through each actor and add it to the context menu if it has the ActorContextMenu attribute + foreach (var actorType in Editor.CodeEditing.Actors.Get()) { - var group = SpawnActorsGroups[i]; + if (actorType.IsAbstract || !actorType.HasAttribute(typeof(ActorContextMenuAttribute), true)) + continue; - if (group.Types.Length == 1) + ActorContextMenuAttribute attribute = null; + foreach (var actorAttribute in actorType.GetAttributes(true)) { - var type = group.Types[0].Value; - newActorCm.AddButton(group.Types[0].Key, () => Spawn(type)); - } - else - { - var groupCm = newActorCm.AddChildMenu(group.Name).ContextMenu; - for (int j = 0; j < group.Types.Length; j++) + if (actorAttribute is ActorContextMenuAttribute actorContextMenuAttribute) { - var type = group.Types[j].Value; - groupCm.AddButton(group.Types[j].Key, () => Spawn(type)); + attribute = actorContextMenuAttribute; + } + } + var splitPath = attribute?.Path.Split('/'); + ContextMenuChildMenu childCM = null; + bool mainCM = true; + for (int i = 0; i < splitPath?.Length; i++) + { + if (i == splitPath.Length - 1) + { + if (mainCM) + { + contextMenu.AddButton(splitPath[i].Trim(), () => Spawn(actorType.Type)); + mainCM = false; + } + else + { + childCM?.ContextMenu.AddButton(splitPath[i].Trim(), () => Spawn(actorType.Type)); + childCM.ContextMenu.AutoSort = true; + } + } + else + { + if (mainCM) + { + childCM = contextMenu.GetOrAddChildMenu(splitPath[i].Trim()); + mainCM = false; + } + else + { + childCM = childCM?.ContextMenu.GetOrAddChildMenu(splitPath[i].Trim()); + } + childCM.ContextMenu.AutoSort = true; } } } diff --git a/Source/Editor/Windows/SceneTreeWindow.cs b/Source/Editor/Windows/SceneTreeWindow.cs index 396bd3747..8fd6e33ee 100644 --- a/Source/Editor/Windows/SceneTreeWindow.cs +++ b/Source/Editor/Windows/SceneTreeWindow.cs @@ -22,113 +22,6 @@ namespace FlaxEditor.Windows /// public partial class SceneTreeWindow : SceneEditorWindow { - /// - /// The spawnable actors group. - /// - public struct ActorsGroup - { - /// - /// The group name. - /// - public string Name; - - /// - /// The types to spawn (name and type). - /// - public KeyValuePair[] Types; - } - - /// - /// The Spawnable actors (groups with single entry are inlined without a child menu) - /// - public static readonly ActorsGroup[] SpawnActorsGroups = - { - new ActorsGroup - { - Types = new[] { new KeyValuePair("Actor", typeof(EmptyActor)) } - }, - new ActorsGroup - { - Types = new[] { new KeyValuePair("Model", typeof(StaticModel)) } - }, - new ActorsGroup - { - Types = new[] { new KeyValuePair("Camera", typeof(Camera)) } - }, - new ActorsGroup - { - Name = "Lights", - Types = new[] - { - new KeyValuePair("Directional Light", typeof(DirectionalLight)), - new KeyValuePair("Point Light", typeof(PointLight)), - new KeyValuePair("Spot Light", typeof(SpotLight)), - new KeyValuePair("Sky Light", typeof(SkyLight)), - } - }, - new ActorsGroup - { - Name = "Visuals", - Types = new[] - { - new KeyValuePair("Environment Probe", typeof(EnvironmentProbe)), - new KeyValuePair("Sky", typeof(Sky)), - new KeyValuePair("Skybox", typeof(Skybox)), - new KeyValuePair("Exponential Height Fog", typeof(ExponentialHeightFog)), - new KeyValuePair("PostFx Volume", typeof(PostFxVolume)), - new KeyValuePair("Decal", typeof(Decal)), - new KeyValuePair("Particle Effect", typeof(ParticleEffect)), - } - }, - new ActorsGroup - { - Name = "Physics", - Types = new[] - { - new KeyValuePair("Rigid Body", typeof(RigidBody)), - new KeyValuePair("Character Controller", typeof(CharacterController)), - new KeyValuePair("Box Collider", typeof(BoxCollider)), - new KeyValuePair("Sphere Collider", typeof(SphereCollider)), - new KeyValuePair("Capsule Collider", typeof(CapsuleCollider)), - new KeyValuePair("Mesh Collider", typeof(MeshCollider)), - new KeyValuePair("Fixed Joint", typeof(FixedJoint)), - new KeyValuePair("Distance Joint", typeof(DistanceJoint)), - new KeyValuePair("Slider Joint", typeof(SliderJoint)), - new KeyValuePair("Spherical Joint", typeof(SphericalJoint)), - new KeyValuePair("Hinge Joint", typeof(HingeJoint)), - new KeyValuePair("D6 Joint", typeof(D6Joint)), - } - }, - new ActorsGroup - { - Name = "Other", - Types = new[] - { - new KeyValuePair("Animated Model", typeof(AnimatedModel)), - new KeyValuePair("Bone Socket", typeof(BoneSocket)), - new KeyValuePair("CSG Box Brush", typeof(BoxBrush)), - new KeyValuePair("Audio Source", typeof(AudioSource)), - new KeyValuePair("Audio Listener", typeof(AudioListener)), - new KeyValuePair("Scene Animation", typeof(SceneAnimationPlayer)), - new KeyValuePair("Nav Mesh Bounds Volume", typeof(NavMeshBoundsVolume)), - new KeyValuePair("Nav Link", typeof(NavLink)), - new KeyValuePair("Nav Modifier Volume", typeof(NavModifierVolume)), - new KeyValuePair("Spline", typeof(Spline)), - } - }, - new ActorsGroup - { - Name = "GUI", - Types = new[] - { - new KeyValuePair("UI Control", typeof(UIControl)), - new KeyValuePair("UI Canvas", typeof(UICanvas)), - new KeyValuePair("Text Render", typeof(TextRender)), - new KeyValuePair("Sprite Render", typeof(SpriteRender)), - } - }, - }; - private TextBox _searchBox; private Tree _tree; private Panel _sceneTreePanel; @@ -249,7 +142,7 @@ namespace FlaxEditor.Windows { if (selection.Count != 0) Editor.SceneEditing.Select(actor); - actor.TreeNode.StartRenaming(); + actor.TreeNode.StartRenaming(this); } } @@ -442,6 +335,15 @@ namespace FlaxEditor.Windows return true; } + if (buttons == MouseButton.Left) + { + if (Editor.StateMachine.CurrentState.CanEditScene) + { + Editor.SceneEditing.Deselect(); + } + return true; + } + return false; } diff --git a/Source/Engine/Animations/SceneAnimations/SceneAnimationPlayer.h b/Source/Engine/Animations/SceneAnimations/SceneAnimationPlayer.h index 4e0fcaa40..cdeb29fa5 100644 --- a/Source/Engine/Animations/SceneAnimations/SceneAnimationPlayer.h +++ b/Source/Engine/Animations/SceneAnimations/SceneAnimationPlayer.h @@ -11,7 +11,7 @@ /// /// The scene animation playback actor. /// -API_CLASS() class FLAXENGINE_API SceneAnimationPlayer : public Actor, public IPostFxSettingsProvider +API_CLASS(Attributes = "ActorContextMenu(\"New/Other/Scene Animation\")") class FLAXENGINE_API SceneAnimationPlayer : public Actor, public IPostFxSettingsProvider { DECLARE_SCENE_OBJECT(SceneAnimationPlayer); diff --git a/Source/Engine/Audio/AudioListener.h b/Source/Engine/Audio/AudioListener.h index 4c9f608fa..9edcb4ff7 100644 --- a/Source/Engine/Audio/AudioListener.h +++ b/Source/Engine/Audio/AudioListener.h @@ -7,7 +7,7 @@ /// /// Represents a listener that hears audio sources. For spatial audio the volume and pitch of played audio is determined by the distance, orientation and velocity differences between the source and the listener. /// -API_CLASS() class FLAXENGINE_API AudioListener : public Actor +API_CLASS(Attributes="ActorContextMenu(\"New/Audio/Audio Listener\")") class FLAXENGINE_API AudioListener : public Actor { DECLARE_SCENE_OBJECT(AudioListener); private: diff --git a/Source/Engine/Audio/AudioSource.h b/Source/Engine/Audio/AudioSource.h index ebc8dc957..4335795e9 100644 --- a/Source/Engine/Audio/AudioSource.h +++ b/Source/Engine/Audio/AudioSource.h @@ -13,7 +13,7 @@ /// /// Whether or not an audio source is spatial is controlled by the assigned AudioClip.The volume and the pitch of a spatial audio source is controlled by its position and the AudioListener's position/direction/velocity. /// -API_CLASS() class FLAXENGINE_API AudioSource : public Actor +API_CLASS(Attributes="ActorContextMenu(\"New/Audio/Audio Source\")") class FLAXENGINE_API AudioSource : public Actor { DECLARE_SCENE_OBJECT(AudioSource); friend class AudioStreamingHandler; diff --git a/Source/Engine/Content/Storage/FlaxStorage.cpp b/Source/Engine/Content/Storage/FlaxStorage.cpp index 949750349..065011659 100644 --- a/Source/Engine/Content/Storage/FlaxStorage.cpp +++ b/Source/Engine/Content/Storage/FlaxStorage.cpp @@ -622,6 +622,33 @@ bool FlaxStorage::LoadAssetChunk(FlaxChunk* chunk) // Seek stream->SetPosition(chunk->LocationInFile.Address); + if (stream->HasError()) + { + // Sometimes stream->HasError() from setposition. result in a crash or missing media in release (stream _file._handle = nullptr). + // When retrying, it looks like it works and we can continue. We need this to success. + + for (int retry = 0; retry < 5; retry++) + { + Platform::Sleep(50); + stream = OpenFile(); + failed = stream == nullptr; + if (!failed) + { + stream->SetPosition(chunk->LocationInFile.Address); + } + if (!stream->HasError()) + break; + } + } + + if (stream->HasError()) + { + failed = true; + UnlockChunks(); + LOG(Warning, "SetPosition failed on chunk {0}.", ToString()); + return failed; + } + // Load data auto size = chunk->LocationInFile.Size; if (chunk->Flags & FlaxChunkFlags::CompressedLZ4) diff --git a/Source/Engine/Core/Types/Variant.cpp b/Source/Engine/Core/Types/Variant.cpp index 227d6708f..5bf8dbf88 100644 --- a/Source/Engine/Core/Types/Variant.cpp +++ b/Source/Engine/Core/Types/Variant.cpp @@ -2268,6 +2268,11 @@ const Ray& Variant::AsRay() const #endif } +Transform& Variant::AsTransform() +{ + return *(Transform*)AsBlob.Data; +} + const Transform& Variant::AsTransform() const { return *(const Transform*)AsBlob.Data; diff --git a/Source/Engine/Core/Types/Variant.h b/Source/Engine/Core/Types/Variant.h index bfb7c14b0..33ad6df19 100644 --- a/Source/Engine/Core/Types/Variant.h +++ b/Source/Engine/Core/Types/Variant.h @@ -332,6 +332,7 @@ public: const BoundingBox& AsBoundingBox() const; Ray& AsRay(); const Ray& AsRay() const; + Transform& AsTransform(); const Transform& AsTransform() const; const Matrix& AsMatrix() const; Array& AsArray(); diff --git a/Source/Engine/Level/Actors/AnimatedModel.h b/Source/Engine/Level/Actors/AnimatedModel.h index 7230ace0f..d07c93752 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.h +++ b/Source/Engine/Level/Actors/AnimatedModel.h @@ -12,7 +12,7 @@ /// /// Performs an animation and renders a skinned model. /// -API_CLASS() class FLAXENGINE_API AnimatedModel : public ModelInstanceActor +API_CLASS(Attributes="ActorContextMenu(\"New/Other/Animated Model\")") class FLAXENGINE_API AnimatedModel : public ModelInstanceActor { DECLARE_SCENE_OBJECT(AnimatedModel); friend class AnimationsSystem; diff --git a/Source/Engine/Level/Actors/BoneSocket.h b/Source/Engine/Level/Actors/BoneSocket.h index e3ed1e5f4..4e107aac0 100644 --- a/Source/Engine/Level/Actors/BoneSocket.h +++ b/Source/Engine/Level/Actors/BoneSocket.h @@ -7,7 +7,7 @@ /// /// Actor that links to the animated model skeleton node transformation. /// -API_CLASS() class FLAXENGINE_API BoneSocket : public Actor +API_CLASS(Attributes="ActorContextMenu(\"New/Other/Bone Socket\")") class FLAXENGINE_API BoneSocket : public Actor { DECLARE_SCENE_OBJECT(BoneSocket); diff --git a/Source/Engine/Level/Actors/BoxBrush.h b/Source/Engine/Level/Actors/BoxBrush.h index fc30aedc2..5e8fe2cb9 100644 --- a/Source/Engine/Level/Actors/BoxBrush.h +++ b/Source/Engine/Level/Actors/BoxBrush.h @@ -65,7 +65,7 @@ public: /// /// Performs CSG box brush operation that adds or removes geometry. /// -API_CLASS() class FLAXENGINE_API BoxBrush : public Actor, public CSG::Brush +API_CLASS(Attributes="ActorContextMenu(\"New/Other/Box Brush\")") class FLAXENGINE_API BoxBrush : public Actor, public CSG::Brush { DECLARE_SCENE_OBJECT(BoxBrush); private: diff --git a/Source/Engine/Level/Actors/Camera.h b/Source/Engine/Level/Actors/Camera.h index 465130110..e01cf11c4 100644 --- a/Source/Engine/Level/Actors/Camera.h +++ b/Source/Engine/Level/Actors/Camera.h @@ -18,7 +18,7 @@ /// /// Describes the camera projection and view. Provides information about how to render scene (viewport location and direction, etc.). /// -API_CLASS(Sealed) class FLAXENGINE_API Camera : public Actor +API_CLASS(Sealed, Attributes="ActorContextMenu(\"New/Camera\")") class FLAXENGINE_API Camera : public Actor { DECLARE_SCENE_OBJECT(Camera); diff --git a/Source/Engine/Level/Actors/Decal.h b/Source/Engine/Level/Actors/Decal.h index 8cc6c2df7..497186cc5 100644 --- a/Source/Engine/Level/Actors/Decal.h +++ b/Source/Engine/Level/Actors/Decal.h @@ -11,7 +11,7 @@ /// /// Actor that draws the can be used to draw a custom decals on top of the other objects. /// -API_CLASS() class FLAXENGINE_API Decal : public Actor +API_CLASS(Attributes="ActorContextMenu(\"New/Visuals/Decal\")") class FLAXENGINE_API Decal : public Actor { DECLARE_SCENE_OBJECT(Decal); private: diff --git a/Source/Engine/Level/Actors/DirectionalLight.h b/Source/Engine/Level/Actors/DirectionalLight.h index 1e89e7aa3..f9347be36 100644 --- a/Source/Engine/Level/Actors/DirectionalLight.h +++ b/Source/Engine/Level/Actors/DirectionalLight.h @@ -7,7 +7,7 @@ /// /// Directional light emits light from direction in space. /// -API_CLASS() class FLAXENGINE_API DirectionalLight : public LightWithShadow +API_CLASS(Attributes="ActorContextMenu(\"New/Lights/Directional Light\")") class FLAXENGINE_API DirectionalLight : public LightWithShadow { DECLARE_SCENE_OBJECT(DirectionalLight); public: diff --git a/Source/Engine/Level/Actors/EmptyActor.h b/Source/Engine/Level/Actors/EmptyActor.h index 00d1cf0a8..17742d137 100644 --- a/Source/Engine/Level/Actors/EmptyActor.h +++ b/Source/Engine/Level/Actors/EmptyActor.h @@ -7,7 +7,7 @@ /// /// The empty actor that is useful to create hierarchy and/or hold scripts. See . /// -API_CLASS() class FLAXENGINE_API EmptyActor : public Actor +API_CLASS(Attributes="ActorContextMenu(\"New/Actor\")") class FLAXENGINE_API EmptyActor : public Actor { DECLARE_SCENE_OBJECT(EmptyActor); public: diff --git a/Source/Engine/Level/Actors/EnvironmentProbe.h b/Source/Engine/Level/Actors/EnvironmentProbe.h index 9284ba328..e5a5faa84 100644 --- a/Source/Engine/Level/Actors/EnvironmentProbe.h +++ b/Source/Engine/Level/Actors/EnvironmentProbe.h @@ -10,7 +10,7 @@ /// /// Environment Probe can capture space around the objects to provide reflections. /// -API_CLASS() class FLAXENGINE_API EnvironmentProbe : public Actor +API_CLASS(Attributes="ActorContextMenu(\"New/Visuals/Environment Probe\")") class FLAXENGINE_API EnvironmentProbe : public Actor { DECLARE_SCENE_OBJECT(EnvironmentProbe); public: diff --git a/Source/Engine/Level/Actors/ExponentialHeightFog.h b/Source/Engine/Level/Actors/ExponentialHeightFog.h index fe2bf316d..ac2d24d91 100644 --- a/Source/Engine/Level/Actors/ExponentialHeightFog.h +++ b/Source/Engine/Level/Actors/ExponentialHeightFog.h @@ -12,7 +12,7 @@ /// /// Used to create fogging effects such as clouds but with a density that is related to the height of the fog. /// -API_CLASS() class FLAXENGINE_API ExponentialHeightFog : public Actor, public IFogRenderer +API_CLASS(Attributes="ActorContextMenu(\"New/Visuals/Exponential Height Fog\")") class FLAXENGINE_API ExponentialHeightFog : public Actor, public IFogRenderer { DECLARE_SCENE_OBJECT(ExponentialHeightFog); private: diff --git a/Source/Engine/Level/Actors/PointLight.h b/Source/Engine/Level/Actors/PointLight.h index 6e28b4405..066bfb81b 100644 --- a/Source/Engine/Level/Actors/PointLight.h +++ b/Source/Engine/Level/Actors/PointLight.h @@ -9,7 +9,7 @@ /// /// Point light emits light from point in all directions. /// -API_CLASS() class FLAXENGINE_API PointLight : public LightWithShadow +API_CLASS(Attributes="ActorContextMenu(\"New/Lights/Point Light\")") class FLAXENGINE_API PointLight : public LightWithShadow { DECLARE_SCENE_OBJECT(PointLight); private: diff --git a/Source/Engine/Level/Actors/PostFxVolume.h b/Source/Engine/Level/Actors/PostFxVolume.h index bc269eb22..97d61f1f3 100644 --- a/Source/Engine/Level/Actors/PostFxVolume.h +++ b/Source/Engine/Level/Actors/PostFxVolume.h @@ -9,7 +9,7 @@ /// /// A special type of volume that blends custom set of post process settings into the rendering. /// -API_CLASS() class FLAXENGINE_API PostFxVolume : public BoxVolume, public IPostFxSettingsProvider +API_CLASS(Attributes="ActorContextMenu(\"New/Visuals/Post Fx Volume\")") class FLAXENGINE_API PostFxVolume : public BoxVolume, public IPostFxSettingsProvider { DECLARE_SCENE_OBJECT(PostFxVolume); private: diff --git a/Source/Engine/Level/Actors/Sky.h b/Source/Engine/Level/Actors/Sky.h index 1d8bbdbf9..85c09eefd 100644 --- a/Source/Engine/Level/Actors/Sky.h +++ b/Source/Engine/Level/Actors/Sky.h @@ -14,7 +14,7 @@ class GPUPipelineState; /// /// Sky actor renders atmosphere around the scene with fog and sky. /// -API_CLASS() class FLAXENGINE_API Sky : public Actor, public IAtmosphericFogRenderer, public ISkyRenderer +API_CLASS(Attributes="ActorContextMenu(\"New/Visuals/Sky\")") class FLAXENGINE_API Sky : public Actor, public IAtmosphericFogRenderer, public ISkyRenderer { DECLARE_SCENE_OBJECT(Sky); private: diff --git a/Source/Engine/Level/Actors/SkyLight.h b/Source/Engine/Level/Actors/SkyLight.h index 18fb22349..4663709b5 100644 --- a/Source/Engine/Level/Actors/SkyLight.h +++ b/Source/Engine/Level/Actors/SkyLight.h @@ -9,7 +9,7 @@ /// /// Sky light captures the distant parts of the scene and applies it as a light. Allows to add ambient light. /// -API_CLASS() class FLAXENGINE_API SkyLight : public Light +API_CLASS(Attributes="ActorContextMenu(\"New/Lights/Sky Light\")") class FLAXENGINE_API SkyLight : public Light { DECLARE_SCENE_OBJECT(SkyLight); public: diff --git a/Source/Engine/Level/Actors/Skybox.h b/Source/Engine/Level/Actors/Skybox.h index 12faaa3a3..0684976bd 100644 --- a/Source/Engine/Level/Actors/Skybox.h +++ b/Source/Engine/Level/Actors/Skybox.h @@ -11,7 +11,7 @@ /// /// Skybox actor renders sky using custom cube texture or material. /// -API_CLASS() class FLAXENGINE_API Skybox : public Actor, public ISkyRenderer +API_CLASS(Attributes="ActorContextMenu(\"New/Visuals/Sky Box\")") class FLAXENGINE_API Skybox : public Actor, public ISkyRenderer { DECLARE_SCENE_OBJECT(Skybox); private: diff --git a/Source/Engine/Level/Actors/Spline.h b/Source/Engine/Level/Actors/Spline.h index 86f580075..a2d2fa7d2 100644 --- a/Source/Engine/Level/Actors/Spline.h +++ b/Source/Engine/Level/Actors/Spline.h @@ -8,7 +8,7 @@ /// /// Spline shape actor that defines spatial curve with utility functions for general purpose usage. /// -API_CLASS() class FLAXENGINE_API Spline : public Actor +API_CLASS(Attributes="ActorContextMenu(\"New/Other/Spline\")") class FLAXENGINE_API Spline : public Actor { DECLARE_SCENE_OBJECT(Spline); typedef BezierCurveKeyframe Keyframe; diff --git a/Source/Engine/Level/Actors/SpotLight.h b/Source/Engine/Level/Actors/SpotLight.h index aa86eff9f..059e4d28d 100644 --- a/Source/Engine/Level/Actors/SpotLight.h +++ b/Source/Engine/Level/Actors/SpotLight.h @@ -9,7 +9,7 @@ /// /// Spot light emits light from the point in a given direction. /// -API_CLASS() class FLAXENGINE_API SpotLight : public LightWithShadow +API_CLASS(Attributes="ActorContextMenu(\"New/Lights/Spot Light\")") class FLAXENGINE_API SpotLight : public LightWithShadow { DECLARE_SCENE_OBJECT(SpotLight); private: diff --git a/Source/Engine/Level/Actors/StaticModel.h b/Source/Engine/Level/Actors/StaticModel.h index b05a7df9b..ba8468e92 100644 --- a/Source/Engine/Level/Actors/StaticModel.h +++ b/Source/Engine/Level/Actors/StaticModel.h @@ -10,7 +10,7 @@ /// /// Renders model on the screen. /// -API_CLASS() class FLAXENGINE_API StaticModel : public ModelInstanceActor +API_CLASS(Attributes="ActorContextMenu(\"New/Model\")") class FLAXENGINE_API StaticModel : public ModelInstanceActor { DECLARE_SCENE_OBJECT(StaticModel); private: diff --git a/Source/Engine/Navigation/NavLink.h b/Source/Engine/Navigation/NavLink.h index 50a6cc39e..7a788a2a5 100644 --- a/Source/Engine/Navigation/NavLink.h +++ b/Source/Engine/Navigation/NavLink.h @@ -8,7 +8,7 @@ /// The off-mesh link objects used to define a custom point-to-point edge within the navigation graph. /// An off-mesh connection is a user defined traversable connection made up to two vertices, at least one of which resides within a navigation mesh polygon allowing movement outside the navigation mesh. /// -API_CLASS() class FLAXENGINE_API NavLink : public Actor +API_CLASS(Attributes="ActorContextMenu(\"New/Other/Nav Link\")") class FLAXENGINE_API NavLink : public Actor { DECLARE_SCENE_OBJECT(NavLink); public: diff --git a/Source/Engine/Navigation/NavMeshBoundsVolume.h b/Source/Engine/Navigation/NavMeshBoundsVolume.h index 51f2e80eb..595105048 100644 --- a/Source/Engine/Navigation/NavMeshBoundsVolume.h +++ b/Source/Engine/Navigation/NavMeshBoundsVolume.h @@ -8,7 +8,7 @@ /// /// A special type of volume that defines the area of the scene in which navigation meshes are generated. /// -API_CLASS() class FLAXENGINE_API NavMeshBoundsVolume : public BoxVolume +API_CLASS(Attributes="ActorContextMenu(\"New/Other/Nav Mesh Bounds Volume\")") class FLAXENGINE_API NavMeshBoundsVolume : public BoxVolume { DECLARE_SCENE_OBJECT(NavMeshBoundsVolume); public: diff --git a/Source/Engine/Navigation/NavModifierVolume.h b/Source/Engine/Navigation/NavModifierVolume.h index f06149872..c2992ccdc 100644 --- a/Source/Engine/Navigation/NavModifierVolume.h +++ b/Source/Engine/Navigation/NavModifierVolume.h @@ -8,7 +8,7 @@ /// /// A special type of volume that defines the area of the scene in which navigation is restricted (eg. higher traversal cost or dynamic obstacle block). /// -API_CLASS() class FLAXENGINE_API NavModifierVolume : public BoxVolume +API_CLASS(Attributes="ActorContextMenu(\"New/Other/Nav Modifier Volume\")") class FLAXENGINE_API NavModifierVolume : public BoxVolume { DECLARE_SCENE_OBJECT(NavModifierVolume); public: diff --git a/Source/Engine/Particles/ParticleEffect.h b/Source/Engine/Particles/ParticleEffect.h index c71775ff7..5f3b898ea 100644 --- a/Source/Engine/Particles/ParticleEffect.h +++ b/Source/Engine/Particles/ParticleEffect.h @@ -133,7 +133,7 @@ public: /// /// The particle system instance that plays the particles simulation in the game. /// -API_CLASS() class FLAXENGINE_API ParticleEffect : public Actor +API_CLASS(Attributes="ActorContextMenu(\"New/Visuals/Particle Effects\")") class FLAXENGINE_API ParticleEffect : public Actor { DECLARE_SCENE_OBJECT(ParticleEffect); public: diff --git a/Source/Engine/Physics/Actors/RigidBody.h b/Source/Engine/Physics/Actors/RigidBody.h index a2ed21948..f93abe915 100644 --- a/Source/Engine/Physics/Actors/RigidBody.h +++ b/Source/Engine/Physics/Actors/RigidBody.h @@ -14,7 +14,7 @@ class Collider; /// Physics simulation driven object. /// /// -API_CLASS() class FLAXENGINE_API RigidBody : public Actor, public IPhysicsActor +API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Rigid Body\")") class FLAXENGINE_API RigidBody : public Actor, public IPhysicsActor { DECLARE_SCENE_OBJECT(RigidBody); protected: @@ -79,9 +79,7 @@ public: /// /// Gets the 'drag' force added to reduce linear movement. /// - /// - /// Linear damping can be used to slow down an object. The higher the drag the more the object slows down. - /// + /// Linear damping can be used to slow down an object. The higher the drag the more the object slows down. API_PROPERTY(Attributes="EditorOrder(60), DefaultValue(0.01f), Limit(0), EditorDisplay(\"Rigid Body\")") FORCE_INLINE float GetLinearDamping() const { @@ -91,18 +89,14 @@ public: /// /// Sets the 'drag' force added to reduce linear movement. /// - /// - /// Linear damping can be used to slow down an object. The higher the drag the more the object slows down. - /// + /// Linear damping can be used to slow down an object. The higher the drag the more the object slows down. /// The value. API_PROPERTY() void SetLinearDamping(float value); /// /// Gets the 'drag' force added to reduce angular movement. /// - /// - /// Angular damping can be used to slow down the rotation of an object. The higher the drag the more the rotation slows down. - /// + /// Angular damping can be used to slow down the rotation of an object. The higher the drag the more the rotation slows down. API_PROPERTY(Attributes="EditorOrder(70), DefaultValue(0.05f), Limit(0), EditorDisplay(\"Rigid Body\")") FORCE_INLINE float GetAngularDamping() const { @@ -112,9 +106,7 @@ public: /// /// Sets the 'drag' force added to reduce angular movement. /// - /// - /// Angular damping can be used to slow down the rotation of an object. The higher the drag the more the rotation slows down. - /// + /// Angular damping can be used to slow down the rotation of an object. The higher the drag the more the rotation slows down. /// The value. API_PROPERTY() void SetAngularDamping(float value); @@ -287,46 +279,35 @@ public: /// /// Gets the linear velocity of the rigidbody. /// - /// - /// It's used mostly to get the current velocity. Manual modifications may result in unrealistic behaviour. - /// + /// It's used mostly to get the current velocity. Manual modifications may result in unrealistic behaviour. API_PROPERTY(Attributes="HideInEditor") Vector3 GetLinearVelocity() const; /// /// Sets the linear velocity of the rigidbody. /// - /// - /// It's used mostly to get the current velocity. Manual modifications may result in unrealistic behaviour. - /// + /// It's used mostly to get the current velocity. Manual modifications may result in unrealistic behaviour. /// The value. API_PROPERTY() void SetLinearVelocity(const Vector3& value) const; /// /// Gets the angular velocity of the rigidbody measured in radians per second. /// - /// - /// It's used mostly to get the current angular velocity. Manual modifications may result in unrealistic behaviour. - /// + /// It's used mostly to get the current angular velocity. Manual modifications may result in unrealistic behaviour. API_PROPERTY(Attributes="HideInEditor") Vector3 GetAngularVelocity() const; /// /// Sets the angular velocity of the rigidbody measured in radians per second. /// - /// - /// It's used mostly to get the current angular velocity. Manual modifications may result in unrealistic behaviour. - /// + /// It's used mostly to get the current angular velocity. Manual modifications may result in unrealistic behaviour. /// The value. API_PROPERTY() void SetAngularVelocity(const Vector3& value) const; /// /// Gets the maximum depenetration velocity when rigidbody moving out of penetrating state. /// - /// - /// This value controls how much velocity the solver can introduce to correct for penetrations in contacts. - /// Using this property can smooth objects moving out of colliding state and prevent unstable motion. - /// + /// This value controls how much velocity the solver can introduce to correct for penetrations in contacts. Using this property can smooth objects moving out of colliding state and prevent unstable motion. /// The value API_PROPERTY(Attributes="HideInEditor") float GetMaxDepenetrationVelocity() const; @@ -334,19 +315,14 @@ public: /// /// Sets the maximum depenetration velocity when rigidbody moving out of penetrating state. /// - /// - /// This value controls how much velocity the solver can introduce to correct for penetrations in contacts. - /// Using this property can smooth objects moving out of colliding state and prevent unstable motion. - /// + /// This value controls how much velocity the solver can introduce to correct for penetrations in contacts. Using this property can smooth objects moving out of colliding state and prevent unstable motion. /// The value. API_PROPERTY() void SetMaxDepenetrationVelocity(const float value) const; /// /// Gets the mass-normalized kinetic energy threshold below which an actor may go to sleep. /// - /// - /// Actors whose kinetic energy divided by their mass is below this threshold will be candidates for sleeping. - /// + /// Actors whose kinetic energy divided by their mass is below this threshold will be candidates for sleeping. /// The value API_PROPERTY(Attributes="HideInEditor") float GetSleepThreshold() const; @@ -354,9 +330,7 @@ public: /// /// Sets the mass-normalized kinetic energy threshold below which an actor may go to sleep. /// - /// - /// Actors whose kinetic energy divided by their mass is below this threshold will be candidates for sleeping. - /// + /// Actors whose kinetic energy divided by their mass is below this threshold will be candidates for sleeping. /// The value. API_PROPERTY() void SetSleepThreshold(const float value) const; diff --git a/Source/Engine/Physics/Colliders/BoxCollider.h b/Source/Engine/Physics/Colliders/BoxCollider.h index d49ae33bd..a91872acd 100644 --- a/Source/Engine/Physics/Colliders/BoxCollider.h +++ b/Source/Engine/Physics/Colliders/BoxCollider.h @@ -9,7 +9,7 @@ /// A box-shaped primitive collider. /// /// -API_CLASS() class FLAXENGINE_API BoxCollider : public Collider +API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Box Collider\")") class FLAXENGINE_API BoxCollider : public Collider { DECLARE_SCENE_OBJECT(BoxCollider); private: @@ -20,9 +20,7 @@ public: /// /// Gets the size of the box, measured in the object's local space. /// - /// - /// The box size will be scaled by the actor's world scale. - /// + /// The box size will be scaled by the actor's world scale. API_PROPERTY(Attributes="EditorOrder(100), DefaultValue(typeof(Vector3), \"100,100,100\"), EditorDisplay(\"Collider\")") FORCE_INLINE Float3 GetSize() const { @@ -32,9 +30,7 @@ public: /// /// Sets the size of the box, measured in the object's local space. /// - /// - /// The box size will be scaled by the actor's world scale. - /// + /// The box size will be scaled by the actor's world scale. API_PROPERTY() void SetSize(const Float3& value); /// diff --git a/Source/Engine/Physics/Colliders/CapsuleCollider.h b/Source/Engine/Physics/Colliders/CapsuleCollider.h index f62bd4154..c4837b814 100644 --- a/Source/Engine/Physics/Colliders/CapsuleCollider.h +++ b/Source/Engine/Physics/Colliders/CapsuleCollider.h @@ -8,11 +8,9 @@ /// /// A capsule-shaped primitive collider. /// -/// -/// Capsules are cylinders with a half-sphere at each end centered at the origin and extending along the X axis, and two hemispherical ends. -/// +/// Capsules are cylinders with a half-sphere at each end centered at the origin and extending along the X axis, and two hemispherical ends. /// -API_CLASS() class FLAXENGINE_API CapsuleCollider : public Collider +API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Capsule Collider\")") class FLAXENGINE_API CapsuleCollider : public Collider { DECLARE_SCENE_OBJECT(CapsuleCollider); private: @@ -24,9 +22,7 @@ public: /// /// Gets the radius of the sphere, measured in the object's local space. /// - /// - /// The sphere radius will be scaled by the actor's world scale. - /// + /// The sphere radius will be scaled by the actor's world scale. API_PROPERTY(Attributes="EditorOrder(100), DefaultValue(20.0f), EditorDisplay(\"Collider\")") FORCE_INLINE float GetRadius() const { @@ -36,17 +32,13 @@ public: /// /// Sets the radius of the sphere, measured in the object's local space. /// - /// - /// The sphere radius will be scaled by the actor's world scale. - /// + /// The sphere radius will be scaled by the actor's world scale. API_PROPERTY() void SetRadius(float value); /// /// Gets the height of the capsule, measured in the object's local space between the centers of the hemispherical ends. /// - /// - /// The capsule height will be scaled by the actor's world scale. - /// + /// The capsule height will be scaled by the actor's world scale. API_PROPERTY(Attributes="EditorOrder(110), DefaultValue(100.0f), EditorDisplay(\"Collider\")") FORCE_INLINE float GetHeight() const { @@ -56,9 +48,7 @@ public: /// /// Sets the height of the capsule, measured in the object's local space between the centers of the hemispherical ends. /// - /// - /// The capsule height will be scaled by the actor's world scale. - /// + /// The capsule height will be scaled by the actor's world scale. API_PROPERTY() void SetHeight(float value); public: diff --git a/Source/Engine/Physics/Colliders/CharacterController.h b/Source/Engine/Physics/Colliders/CharacterController.h index 8087d61e8..79a88d601 100644 --- a/Source/Engine/Physics/Colliders/CharacterController.h +++ b/Source/Engine/Physics/Colliders/CharacterController.h @@ -9,7 +9,7 @@ /// Physical objects that allows to easily do player movement constrained by collisions without having to deal with a rigidbody. /// /// -API_CLASS() class FLAXENGINE_API CharacterController : public Collider, public IPhysicsActor +API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Character Controller\")") class FLAXENGINE_API CharacterController : public Collider, public IPhysicsActor { DECLARE_SCENE_OBJECT(CharacterController); public: diff --git a/Source/Engine/Physics/Colliders/MeshCollider.h b/Source/Engine/Physics/Colliders/MeshCollider.h index a12746623..9aea57e72 100644 --- a/Source/Engine/Physics/Colliders/MeshCollider.h +++ b/Source/Engine/Physics/Colliders/MeshCollider.h @@ -10,7 +10,7 @@ /// A collider represented by an arbitrary mesh. /// /// -API_CLASS() class FLAXENGINE_API MeshCollider : public Collider +API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Mesh Collider\")") class FLAXENGINE_API MeshCollider : public Collider { DECLARE_SCENE_OBJECT(MeshCollider); public: diff --git a/Source/Engine/Physics/Colliders/SphereCollider.h b/Source/Engine/Physics/Colliders/SphereCollider.h index 1638300ff..263ff84f2 100644 --- a/Source/Engine/Physics/Colliders/SphereCollider.h +++ b/Source/Engine/Physics/Colliders/SphereCollider.h @@ -8,7 +8,7 @@ /// A sphere-shaped primitive collider. /// /// -API_CLASS() class FLAXENGINE_API SphereCollider : public Collider +API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Sphere Collider\")") class FLAXENGINE_API SphereCollider : public Collider { DECLARE_SCENE_OBJECT(SphereCollider); private: @@ -18,9 +18,7 @@ public: /// /// Gets the radius of the sphere, measured in the object's local space. /// - /// - /// The sphere radius will be scaled by the actor's world scale. - /// + /// The sphere radius will be scaled by the actor's world scale. API_PROPERTY(Attributes="EditorOrder(100), DefaultValue(50.0f), EditorDisplay(\"Collider\")") FORCE_INLINE float GetRadius() const { @@ -30,9 +28,7 @@ public: /// /// Sets the radius of the sphere, measured in the object's local space. /// - /// - /// The sphere radius will be scaled by the actor's world scale. - /// + /// The sphere radius will be scaled by the actor's world scale. API_PROPERTY() void SetRadius(float value); public: diff --git a/Source/Engine/Physics/Joints/D6Joint.h b/Source/Engine/Physics/Joints/D6Joint.h index 66819bb0b..2182f810f 100644 --- a/Source/Engine/Physics/Joints/D6Joint.h +++ b/Source/Engine/Physics/Joints/D6Joint.h @@ -160,7 +160,7 @@ public: /// It also allows you to constrain limits to only specific axes or completely lock specific axes. /// /// -API_CLASS() class FLAXENGINE_API D6Joint : public Joint +API_CLASS(Attributes="ActorContextMenu(\"New/Physics/D6 Joint\")") class FLAXENGINE_API D6Joint : public Joint { DECLARE_SCENE_OBJECT(D6Joint); private: @@ -174,9 +174,7 @@ public: /// /// Gets the motion type around the specified axis. /// - /// - /// Each axis may independently specify that the degree of freedom is locked (blocking relative movement along or around this axis), limited by the corresponding limit, or free. - /// + /// Each axis may independently specify that the degree of freedom is locked (blocking relative movement along or around this axis), limited by the corresponding limit, or free. /// The axis the degree of freedom around which the motion type is specified. /// The value. API_FUNCTION() FORCE_INLINE D6JointMotion GetMotion(const D6JointAxis axis) const @@ -187,9 +185,7 @@ public: /// /// Sets the motion type around the specified axis. /// - /// - /// Each axis may independently specify that the degree of freedom is locked (blocking relative movement along or around this axis), limited by the corresponding limit, or free. - /// + /// Each axis may independently specify that the degree of freedom is locked (blocking relative movement along or around this axis), limited by the corresponding limit, or free. /// The axis the degree of freedom around which the motion type is specified. /// The value. API_FUNCTION() void SetMotion(const D6JointAxis axis, const D6JointMotion value); diff --git a/Source/Engine/Physics/Joints/DistanceJoint.h b/Source/Engine/Physics/Joints/DistanceJoint.h index cb31b8215..1d60f8473 100644 --- a/Source/Engine/Physics/Joints/DistanceJoint.h +++ b/Source/Engine/Physics/Joints/DistanceJoint.h @@ -37,7 +37,7 @@ DECLARE_ENUM_OPERATORS(DistanceJointFlag); /// Physics joint that maintains an upper or lower (or both) bound on the distance between two bodies. /// /// -API_CLASS() class FLAXENGINE_API DistanceJoint : public Joint +API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Distance Joint\")") class FLAXENGINE_API DistanceJoint : public Joint { DECLARE_SCENE_OBJECT(DistanceJoint); private: @@ -65,9 +65,7 @@ public: /// /// Gets the allowed minimum distance for the joint. /// - /// - /// Used only when DistanceJointFlag.MinDistance flag is set. The minimum distance must be no more than the maximum distance. Default: 0, Range: [0, float.MaxValue]. - /// + /// Used only when DistanceJointFlag.MinDistance flag is set. The minimum distance must be no more than the maximum distance. Default: 0, Range: [0, float.MaxValue]. API_PROPERTY(Attributes="EditorOrder(110), DefaultValue(0.0f), Limit(0.0f), EditorDisplay(\"Joint\")") FORCE_INLINE float GetMinDistance() const { @@ -77,17 +75,13 @@ public: /// /// Sets the allowed minimum distance for the joint. /// - /// - /// Used only when DistanceJointFlag.MinDistance flag is set. The minimum distance must be no more than the maximum distance. Default: 0, Range: [0, float.MaxValue]. - /// + /// Used only when DistanceJointFlag.MinDistance flag is set. The minimum distance must be no more than the maximum distance. Default: 0, Range: [0, float.MaxValue]. API_PROPERTY() void SetMinDistance(float value); /// /// Gets the allowed maximum distance for the joint. /// - /// - /// Used only when DistanceJointFlag.MaxDistance flag is set. The maximum distance must be no less than the minimum distance. Default: 0, Range: [0, float.MaxValue]. - /// + /// Used only when DistanceJointFlag.MaxDistance flag is set. The maximum distance must be no less than the minimum distance. Default: 0, Range: [0, float.MaxValue]. API_PROPERTY(Attributes="EditorOrder(120), DefaultValue(10.0f), Limit(0.0f), EditorDisplay(\"Joint\")") FORCE_INLINE float GetMaxDistance() const { @@ -97,17 +91,13 @@ public: /// /// Sets the allowed maximum distance for the joint. /// - /// - /// Used only when DistanceJointFlag.MaxDistance flag is set. The maximum distance must be no less than the minimum distance. Default: 0, Range: [0, float.MaxValue]. - /// + /// Used only when DistanceJointFlag.MaxDistance flag is set. The maximum distance must be no less than the minimum distance. Default: 0, Range: [0, float.MaxValue]. API_PROPERTY() void SetMaxDistance(float value); /// /// Gets the error tolerance of the joint. /// - /// - /// The distance beyond the joint's [min, max] range before the joint becomes active. Default: 25, Range: [0.1, float.MaxValue]. - /// + /// The distance beyond the joint's [min, max] range before the joint becomes active. Default: 25, Range: [0.1, float.MaxValue]. API_PROPERTY(Attributes="EditorOrder(130), DefaultValue(25.0f), Limit(0.0f), EditorDisplay(\"Joint\")") FORCE_INLINE float GetTolerance() const { @@ -117,9 +107,7 @@ public: /// /// Sets the error tolerance of the joint. /// - /// - /// The distance beyond the joint's [min, max] range before the joint becomes active. Default: 25, Range: [0.1, float.MaxValue]. - /// + /// The distance beyond the joint's [min, max] range before the joint becomes active. Default: 25, Range: [0.1, float.MaxValue]. API_PROPERTY() void SetTolerance(float value); /// diff --git a/Source/Engine/Physics/Joints/FixedJoint.h b/Source/Engine/Physics/Joints/FixedJoint.h index 9e6280023..cb6c9e133 100644 --- a/Source/Engine/Physics/Joints/FixedJoint.h +++ b/Source/Engine/Physics/Joints/FixedJoint.h @@ -8,7 +8,7 @@ /// Physics joint that maintains a fixed distance and orientation between its two attached bodies. /// /// -API_CLASS() class FLAXENGINE_API FixedJoint : public Joint +API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Fixed Joint\")") class FLAXENGINE_API FixedJoint : public Joint { DECLARE_SCENE_OBJECT(FixedJoint); public: diff --git a/Source/Engine/Physics/Joints/HingeJoint.h b/Source/Engine/Physics/Joints/HingeJoint.h index 14e3198e5..27f012c85 100644 --- a/Source/Engine/Physics/Joints/HingeJoint.h +++ b/Source/Engine/Physics/Joints/HingeJoint.h @@ -57,17 +57,9 @@ API_STRUCT() struct HingeJointDrive API_FIELD() bool FreeSpin = false; public: - /// - /// Compares two objects. - /// - /// The other. - /// True if both objects are equal. bool operator==(const HingeJointDrive& other) const { - return Velocity == other.Velocity - && ForceLimit == other.ForceLimit - && GearRatio == other.GearRatio - && FreeSpin && other.FreeSpin; + return Math::NearEqual(Velocity, other.Velocity) && Math::NearEqual(ForceLimit, other.ForceLimit) && Math::NearEqual(GearRatio, other.GearRatio) && FreeSpin == other.FreeSpin; } }; @@ -75,7 +67,7 @@ public: /// Physics joint that removes all but a single rotation degree of freedom from its two attached bodies (for example a door hinge). /// /// -API_CLASS() class FLAXENGINE_API HingeJoint : public Joint +API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Hinge Joint\")") class FLAXENGINE_API HingeJoint : public Joint { DECLARE_SCENE_OBJECT(HingeJoint); private: @@ -101,9 +93,7 @@ public: /// /// Gets the joint limit properties. /// - /// - /// Determines the limit of the joint. Limit constrains the motion to the specified angle range. You must enable the limit flag on the joint in order for this to be recognized. - /// + /// Determines the limit of the joint. Limit constrains the motion to the specified angle range. You must enable the limit flag on the joint in order for this to be recognized. API_PROPERTY(Attributes="EditorOrder(110), EditorDisplay(\"Joint\")") FORCE_INLINE LimitAngularRange GetLimit() const { @@ -113,17 +103,13 @@ public: /// /// Sets the joint limit properties. /// - /// - /// Determines the limit of the joint. Limit constrains the motion to the specified angle range. You must enable the limit flag on the joint in order for this to be recognized. - /// + /// Determines the limit of the joint. Limit constrains the motion to the specified angle range. You must enable the limit flag on the joint in order for this to be recognized. API_PROPERTY() void SetLimit(const LimitAngularRange& value); /// /// Gets the joint drive properties. /// - /// - /// Determines the drive properties of the joint. It drives the joint's angular velocity towards a particular value. You must enable the drive flag on the joint in order for the drive to be active. - /// + /// Determines the drive properties of the joint. It drives the joint's angular velocity towards a particular value. You must enable the drive flag on the joint in order for the drive to be active. API_PROPERTY(Attributes="EditorOrder(120), EditorDisplay(\"Joint\")") FORCE_INLINE HingeJointDrive GetDrive() const { @@ -133,9 +119,7 @@ public: /// /// Sets the joint drive properties. /// - /// - /// Determines the drive properties of the joint. It drives the joint's angular velocity towards a particular value. You must enable the drive flag on the joint in order for the drive to be active. - /// + /// Determines the drive properties of the joint. It drives the joint's angular velocity towards a particular value. You must enable the drive flag on the joint in order for the drive to be active. API_PROPERTY() void SetDrive(const HingeJointDrive& value); public: diff --git a/Source/Engine/Physics/Joints/SliderJoint.h b/Source/Engine/Physics/Joints/SliderJoint.h index b909ee925..3bee7d242 100644 --- a/Source/Engine/Physics/Joints/SliderJoint.h +++ b/Source/Engine/Physics/Joints/SliderJoint.h @@ -27,7 +27,7 @@ DECLARE_ENUM_OPERATORS(SliderJointFlag); /// Physics joint that removes all but a single translational degree of freedom. Bodies are allowed to move along a single axis. /// /// -API_CLASS() class FLAXENGINE_API SliderJoint : public Joint +API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Slider Joint\")") class FLAXENGINE_API SliderJoint : public Joint { DECLARE_SCENE_OBJECT(SliderJoint); private: @@ -52,9 +52,7 @@ public: /// /// Gets the joint limit properties. /// - /// - /// Determines the limit of the joint. Limit constrains the motion to the specified angle range. You must enable the limit flag on the joint in order for this to be recognized. - /// + /// Determines the limit of the joint. Limit constrains the motion to the specified angle range. You must enable the limit flag on the joint in order for this to be recognized. API_PROPERTY(Attributes="EditorOrder(110), EditorDisplay(\"Joint\")") FORCE_INLINE LimitLinearRange GetLimit() const { @@ -64,9 +62,7 @@ public: /// /// Sets the joint limit properties. /// - /// - /// Determines a limit that constrains the movement of the joint to a specific minimum and maximum distance. You must enable the limit flag on the joint in order for this to be recognized. - /// + /// Determines a limit that constrains the movement of the joint to a specific minimum and maximum distance. You must enable the limit flag on the joint in order for this to be recognized. API_PROPERTY() void SetLimit(const LimitLinearRange& value); public: diff --git a/Source/Engine/Physics/Joints/SphericalJoint.h b/Source/Engine/Physics/Joints/SphericalJoint.h index 328575fa2..dbee8d7cc 100644 --- a/Source/Engine/Physics/Joints/SphericalJoint.h +++ b/Source/Engine/Physics/Joints/SphericalJoint.h @@ -29,7 +29,7 @@ DECLARE_ENUM_OPERATORS(SphericalJointFlag); /// rotate around the anchor points, and their rotation can be limited by an elliptical cone. /// /// -API_CLASS() class FLAXENGINE_API SphericalJoint : public Joint +API_CLASS(Attributes = "ActorContextMenu(\"New/Physics/Spherical Joint\")") class FLAXENGINE_API SphericalJoint : public Joint { DECLARE_SCENE_OBJECT(SphericalJoint); private: @@ -54,9 +54,7 @@ public: /// /// Gets the joint limit properties. /// - /// - /// Determines the limit of the joint. Limit constrains the motion to the specified angle range. You must enable the limit flag on the joint in order for this to be recognized. - /// + /// Determines the limit of the joint. Limit constrains the motion to the specified angle range. You must enable the limit flag on the joint in order for this to be recognized. API_PROPERTY(Attributes="EditorOrder(110), EditorDisplay(\"Joint\")") FORCE_INLINE LimitConeRange GetLimit() const { @@ -66,9 +64,7 @@ public: /// /// Sets the joint limit properties. /// - /// - /// Determines a limit that constrains the movement of the joint to a specific minimum and maximum distance. You must enable the limit flag on the joint in order for this to be recognized. - /// + /// Determines a limit that constrains the movement of the joint to a specific minimum and maximum distance. You must enable the limit flag on the joint in order for this to be recognized. API_PROPERTY() void SetLimit(const LimitConeRange& value); public: diff --git a/Source/Engine/Scripting/Attributes/Editor/ActorContextMenu.cs b/Source/Engine/Scripting/Attributes/Editor/ActorContextMenu.cs new file mode 100644 index 000000000..aab4ed92d --- /dev/null +++ b/Source/Engine/Scripting/Attributes/Editor/ActorContextMenu.cs @@ -0,0 +1,26 @@ +using System; + +namespace FlaxEngine +{ + /// + /// This attribute is used to show actors that can be created in the scene and prefab context menus. Separate the subcontext menus with a /. + /// + [Serializable] + [AttributeUsage(AttributeTargets.Class)] + public class ActorContextMenuAttribute : Attribute + { + /// + /// The path to be used in the context menu + /// + public string Path; + + /// + /// Initializes a new instance of the class. + /// + /// The path to use to create the context menu + public ActorContextMenuAttribute(string path) + { + Path = path; + } + } +} diff --git a/Source/Engine/Serialization/Serialization.cpp b/Source/Engine/Serialization/Serialization.cpp index 163a65d2b..2d6a8b4b8 100644 --- a/Source/Engine/Serialization/Serialization.cpp +++ b/Source/Engine/Serialization/Serialization.cpp @@ -344,7 +344,7 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Varian Deserialize(value, v.AsBoundingBox(), modifier); break; case VariantType::Transform: - Deserialize(value, *(Transform*)v.AsBlob.Data, modifier); + Deserialize(value, v.AsTransform(), modifier); break; case VariantType::Ray: Deserialize(value, v.AsRay(), modifier); diff --git a/Source/Engine/Serialization/Stream.cpp b/Source/Engine/Serialization/Stream.cpp index 9758aaef4..842d4cc42 100644 --- a/Source/Engine/Serialization/Stream.cpp +++ b/Source/Engine/Serialization/Stream.cpp @@ -15,7 +15,6 @@ #include "Engine/Scripting/ManagedSerialization.h" #include "Engine/Scripting/Scripting.h" #include "Engine/Scripting/ScriptingObject.h" -#include "Engine/Scripting/ScriptingObjectReference.h" #include "Engine/Scripting/ManagedCLR/MCore.h" #include "Engine/Scripting/ManagedCLR/MUtils.h" @@ -438,7 +437,7 @@ void ReadStream::Read(Variant& data) ReadBytes(&data.AsData, sizeof(Quaternion)); break; case VariantType::Transform: - ReadTransform((Transform*)&data.AsData); + ReadTransform(&data.AsTransform()); break; case VariantType::Rectangle: ReadBytes(&data.AsData, sizeof(Rectangle)); diff --git a/Source/Engine/UI/SpriteRender.h b/Source/Engine/UI/SpriteRender.h index bb976da5e..839b274f2 100644 --- a/Source/Engine/UI/SpriteRender.h +++ b/Source/Engine/UI/SpriteRender.h @@ -10,7 +10,7 @@ /// /// Sprite rendering object. /// -API_CLASS() class FLAXENGINE_API SpriteRender : public Actor +API_CLASS(Attributes="ActorContextMenu(\"New/UI/Sprite Render\")") class FLAXENGINE_API SpriteRender : public Actor { DECLARE_SCENE_OBJECT(SpriteRender); private: diff --git a/Source/Engine/UI/TextRender.h b/Source/Engine/UI/TextRender.h index 82858b580..3c8be565a 100644 --- a/Source/Engine/UI/TextRender.h +++ b/Source/Engine/UI/TextRender.h @@ -19,7 +19,7 @@ /// /// Text rendering object. /// -API_CLASS() class FLAXENGINE_API TextRender : public Actor +API_CLASS(Attributes="ActorContextMenu(\"New/UI/Text Render\")") class FLAXENGINE_API TextRender : public Actor { DECLARE_SCENE_OBJECT(TextRender); private: diff --git a/Source/Engine/UI/UICanvas.h b/Source/Engine/UI/UICanvas.h index 4eff6cebc..d207739eb 100644 --- a/Source/Engine/UI/UICanvas.h +++ b/Source/Engine/UI/UICanvas.h @@ -7,7 +7,7 @@ /// /// Root of the UI structure. Renders GUI and handles input events forwarding. /// -API_CLASS(Sealed, NoConstructor) class FLAXENGINE_API UICanvas : public Actor +API_CLASS(Sealed, NoConstructor, Attributes="ActorContextMenu(\"New/UI/UI Canvas\")") class FLAXENGINE_API UICanvas : public Actor { DECLARE_SCENE_OBJECT(UICanvas); public: diff --git a/Source/Engine/UI/UIControl.h b/Source/Engine/UI/UIControl.h index 27de5d855..381cbf98a 100644 --- a/Source/Engine/UI/UIControl.h +++ b/Source/Engine/UI/UIControl.h @@ -8,7 +8,7 @@ /// /// Contains a single GUI control (on C# side). /// -API_CLASS(Sealed) class FLAXENGINE_API UIControl : public Actor +API_CLASS(Sealed, Attributes="ActorContextMenu(\"New/UI/UI Control\")") class FLAXENGINE_API UIControl : public Actor { DECLARE_SCENE_OBJECT(UIControl); private: diff --git a/Source/ThirdParty/OpenFBX/ofbx.cpp b/Source/ThirdParty/OpenFBX/ofbx.cpp index 02a37e94a..001a39271 100644 --- a/Source/ThirdParty/OpenFBX/ofbx.cpp +++ b/Source/ThirdParty/OpenFBX/ofbx.cpp @@ -2131,6 +2131,7 @@ template <> const char* fromString(const char* str, const char* end, Mat template static void parseTextArray(const Property& property, std::vector* out) { + out->clear(); const u8* iter = property.value.begin; for (int i = 0; i < property.count; ++i) { diff --git a/Source/Tools/Flax.Build/Build/Builder.Projects.cs b/Source/Tools/Flax.Build/Build/Builder.Projects.cs index 1772cb444..bb645a940 100644 --- a/Source/Tools/Flax.Build/Build/Builder.Projects.cs +++ b/Source/Tools/Flax.Build/Build/Builder.Projects.cs @@ -435,7 +435,7 @@ namespace Flax.Build else if (dependencyModule.BinaryModuleName == "FlaxEngine") { // TODO: instead of this hack find a way to reference the prebuilt target bindings binary (example: game C# project references FlaxEngine C# prebuilt dll) - project.CSharp.FileReferences.Add(Path.Combine(Globals.EngineRoot, Platform.GetEditorBinaryDirectory(), "Development/FlaxEngine.CSharp.dll")); + project.CSharp.FileReferences.Add(Path.Combine(Globals.EngineRoot, "Binaries/Editor/Win64/Development/FlaxEngine.CSharp.dll")); } } } diff --git a/Source/Tools/Flax.Build/Projects/VisualStudioCode/VisualStudioCodeProjectGenerator.cs b/Source/Tools/Flax.Build/Projects/VisualStudioCode/VisualStudioCodeProjectGenerator.cs index 872354f22..930915a79 100644 --- a/Source/Tools/Flax.Build/Projects/VisualStudioCode/VisualStudioCodeProjectGenerator.cs +++ b/Source/Tools/Flax.Build/Projects/VisualStudioCode/VisualStudioCodeProjectGenerator.cs @@ -569,6 +569,7 @@ namespace Flax.Build.Projects.VisualStudioCode json.AddField("jake.autoDetect", "off"); json.AddField("grunt.autoDetect", "off"); json.AddField("omnisharp.defaultLaunchSolution", solution.Name + ".sln"); + json.AddField("omnisharp.useModernNet", false); json.EndObject(); // Folders