diff --git a/Source/Editor/GUI/Docking/DockPanelProxy.cs b/Source/Editor/GUI/Docking/DockPanelProxy.cs
index 15ff2cad0..e6e57de8e 100644
--- a/Source/Editor/GUI/Docking/DockPanelProxy.cs
+++ b/Source/Editor/GUI/Docking/DockPanelProxy.cs
@@ -13,6 +13,7 @@ namespace FlaxEditor.GUI.Docking
public class DockPanelProxy : ContainerControl
{
private DockPanel _panel;
+ private double _dragEnterTime = -1;
///
/// 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);
}
///
@@ -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;
+ ///
+ public override void OnDragLeave()
+ {
+ _dragEnterTime = -1;
- return DragDropEffect.None;
+ base.OnDragLeave();
}
///
@@ -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)
diff --git a/Source/Editor/Gizmo/IGizmoOwner.cs b/Source/Editor/Gizmo/IGizmoOwner.cs
index ff653196e..3ab0a917b 100644
--- a/Source/Editor/Gizmo/IGizmoOwner.cs
+++ b/Source/Editor/Gizmo/IGizmoOwner.cs
@@ -106,5 +106,11 @@ namespace FlaxEditor.Gizmo
///
/// The nodes to select
void Select(List nodes);
+
+ ///
+ /// Spawns the actor in the viewport hierarchy.
+ ///
+ /// The new actor to spawn.
+ void Spawn(Actor actor);
}
}
diff --git a/Source/Editor/Surface/Archetypes/Parameters.cs b/Source/Editor/Surface/Archetypes/Parameters.cs
index 6ed5a61e6..4cf1af4f6 100644
--- a/Source/Editor/Surface/Archetypes/Parameters.cs
+++ b/Source/Editor/Surface/Archetypes/Parameters.cs
@@ -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)
diff --git a/Source/Editor/Viewport/EditorGizmoViewport.cs b/Source/Editor/Viewport/EditorGizmoViewport.cs
index a24dd2f38..fe579e7e5 100644
--- a/Source/Editor/Viewport/EditorGizmoViewport.cs
+++ b/Source/Editor/Viewport/EditorGizmoViewport.cs
@@ -86,6 +86,9 @@ namespace FlaxEditor.Viewport
///
public abstract void Select(List nodes);
+ ///
+ public abstract void Spawn(Actor actor);
+
///
protected override bool IsControllingMouse => Gizmos.Active?.IsControllingMouse ?? false;
diff --git a/Source/Editor/Viewport/MainEditorGizmoViewport.cs b/Source/Editor/Viewport/MainEditorGizmoViewport.cs
index e85b6c2b3..24c8f1c4c 100644
--- a/Source/Editor/Viewport/MainEditorGizmoViewport.cs
+++ b/Source/Editor/Viewport/MainEditorGizmoViewport.cs
@@ -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 _dragAssets;
- private readonly DragActorType _dragActorType = new DragActorType(ValidateDragActorType);
-
private SelectionOutline _customSelectionOutline;
- ///
- /// The custom drag drop event arguments.
- ///
- ///
- public class DragDropEventArgs : DragEventArgs
- {
- ///
- /// The hit.
- ///
- public SceneGraphNode Hit;
-
- ///
- /// The hit location.
- ///
- public Vector3 HitLocation;
- }
-
///
/// The editor sprites rendering effect.
///
@@ -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;
///
/// Drag and drop handlers
///
- public readonly DragHandlers DragHandlers = new DragHandlers();
+ public readonly ViewportDragHandlers DragHandlers;
///
/// The transform gizmo.
@@ -219,7 +194,7 @@ namespace FlaxEditor.Viewport
: base(Object.New(), editor.Undo, editor.Scene.Root)
{
_editor = editor;
- _dragAssets = new DragAssets(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())
- {
- GetHitLocation(ref location, out var hit, out _, out _);
- ClearDragEffects();
- var material = FlaxEngine.Content.LoadAsync(_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();
- }
-
///
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
///
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);
}
///
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())
- {
- var material = FlaxEngine.Content.LoadAsync(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())
- {
- 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);
- }
-
///
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);
}
///
@@ -1211,6 +974,14 @@ namespace FlaxEditor.Viewport
_editor.SceneEditing.Select(nodes);
}
+ ///
+ 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);
+ }
+
///
public override void OnDestroy()
{
diff --git a/Source/Editor/Viewport/PrefabWindowViewport.cs b/Source/Editor/Viewport/PrefabWindowViewport.cs
index eb462deb1..6e111f588 100644
--- a/Source/Editor/Viewport/PrefabWindowViewport.cs
+++ b/Source/Editor/Viewport/PrefabWindowViewport.cs
@@ -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();
+
+ ///
+ /// Drag and drop handlers
+ ///
+ public readonly ViewportDragHandlers DragHandlers;
///
/// 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);
}
+
///
public EditorViewport Viewport => this;
@@ -354,6 +357,12 @@ namespace FlaxEditor.Viewport
_window.Select(nodes);
}
+ ///
+ public void Spawn(Actor actor)
+ {
+ _window.Spawn(actor);
+ }
+
///
protected override bool IsControllingMouse => Gizmos.Active?.IsControllingMouse ?? false;
@@ -669,11 +678,11 @@ namespace FlaxEditor.Viewport
///
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())
return true;
}
-
return false;
}
@@ -697,86 +705,21 @@ namespace FlaxEditor.Viewport
///
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);
}
///
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(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);
- }
-
///
/// Focuses the viewport on the current selection of the gizmo.
///
@@ -814,57 +757,11 @@ namespace FlaxEditor.Viewport
///
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);
}
///
diff --git a/Source/Editor/Viewport/ViewportDraggingHelper.cs b/Source/Editor/Viewport/ViewportDraggingHelper.cs
new file mode 100644
index 000000000..8a1b4f183
--- /dev/null
+++ b/Source/Editor/Viewport/ViewportDraggingHelper.cs
@@ -0,0 +1,257 @@
+// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
+
+using System;
+using System.Linq;
+using FlaxEditor.Content;
+using FlaxEditor.Gizmo;
+using FlaxEditor.GUI.Drag;
+using FlaxEditor.SceneGraph;
+using FlaxEditor.SceneGraph.Actors;
+using FlaxEditor.Scripting;
+using FlaxEngine;
+using FlaxEngine.GUI;
+
+namespace FlaxEditor.Viewport
+{
+ ///
+ /// Utility to help managing dragging assets, actors and other objects into the editor viewport.
+ ///
+ public class ViewportDragHandlers : DragHandlers
+ {
+ ///
+ /// The custom drag drop event arguments.
+ ///
+ ///
+ public class DragDropEventArgs : DragEventArgs
+ {
+ ///
+ /// The hit.
+ ///
+ public SceneGraphNode Hit;
+
+ ///
+ /// The hit location.
+ ///
+ public Vector3 HitLocation;
+ }
+
+ private readonly IGizmoOwner _owner;
+ private readonly EditorViewport _viewport;
+ private readonly DragAssets _dragAssets;
+ private readonly DragActorType _dragActorType;
+
+ private StaticModel _previewStaticModel;
+ private int _previewModelEntryIndex;
+ private BrushSurface _previewBrushSurface;
+
+ internal ViewportDragHandlers(IGizmoOwner owner, EditorViewport viewport, Func validateAsset, Func validateDragActorType)
+ {
+ _owner = owner;
+ _viewport = viewport;
+ Add(_dragAssets = new DragAssets(validateAsset));
+ Add(_dragActorType = new DragActorType(validateDragActorType));
+ }
+
+ internal void ClearDragEffects()
+ {
+ _previewStaticModel = null;
+ _previewModelEntryIndex = -1;
+ _previewBrushSurface = new BrushSurface();
+ }
+
+ internal void CollectDrawCalls(ViewportDebugDrawData debugDrawData, ref RenderContext renderContext)
+ {
+ if (_previewStaticModel)
+ debugDrawData.HighlightModel(_previewStaticModel, _previewModelEntryIndex);
+ if (_previewBrushSurface.Brush != null)
+ debugDrawData.HighlightBrushSurface(_previewBrushSurface);
+ }
+
+ internal DragDropEffect DragEnter(ref Float2 location, DragData data)
+ {
+ var result = OnDragEnter(data);
+ SetDragEffects(ref location);
+ return result;
+ }
+
+ internal DragDropEffect DragMove(ref Float2 location, DragData data)
+ {
+ SetDragEffects(ref location);
+ return Effect;
+ }
+
+ internal DragDropEffect DragDrop(ref Float2 location, DragData data)
+ {
+ Vector3 hitLocation = _viewport.ViewPosition, hitNormal = -_viewport.ViewDirection;
+ SceneGraphNode hit = null;
+ if (HasValidDrag)
+ {
+ GetHitLocation(ref location, out hit, out hitLocation, out hitNormal);
+ }
+
+ var result = DragDropEffect.None;
+ if (_dragAssets.HasValidDrag)
+ {
+ result = _dragAssets.Effect;
+ foreach (var asset in _dragAssets.Objects)
+ Spawn(asset, hit, ref location, ref hitLocation, ref hitNormal);
+ }
+ else if (_dragActorType.HasValidDrag)
+ {
+ result = _dragActorType.Effect;
+ foreach (var actorType in _dragActorType.Objects)
+ Spawn(actorType, hit, ref location, ref hitLocation, ref hitNormal);
+ }
+
+ OnDragDrop(new DragDropEventArgs { Hit = hit, HitLocation = hitLocation });
+
+ return result;
+ }
+
+ private void SetDragEffects(ref Float2 location)
+ {
+ if (_dragAssets.HasValidDrag && _dragAssets.Objects[0].IsOfType())
+ {
+ GetHitLocation(ref location, out var hit, out _, out _);
+ ClearDragEffects();
+ var material = FlaxEngine.Content.LoadAsync(_dragAssets.Objects[0].ID);
+ if (material.IsDecal)
+ return;
+
+ if (hit is StaticModelNode staticModelNode)
+ {
+ _previewStaticModel = (StaticModel)staticModelNode.Actor;
+ var ray = _viewport.ConvertMouseToRay(ref location);
+ _previewStaticModel.IntersectsEntry(ref ray, out _, out _, out _previewModelEntryIndex);
+ }
+ else if (hit is BoxBrushNode.SideLinkNode brushSurfaceNode)
+ {
+ _previewBrushSurface = brushSurfaceNode.Surface;
+ }
+ }
+ }
+
+ 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 = _viewport.ConvertMouseToRay(ref location);
+ var view = new Ray(_viewport.ViewPosition, _viewport.ViewDirection);
+ var gridPlane = new Plane(Vector3.Zero, Vector3.Up);
+ var flags = SceneGraphNode.RayCastData.FlagTypes.SkipColliders | SceneGraphNode.RayCastData.FlagTypes.SkipEditorPrimitives;
+ hit = _owner.SceneGraphRoot.RayCast(ref ray, ref view, out var closest, out var normal, flags);
+ var girdGizmo = (GridGizmo)_owner.Gizmos.FirstOrDefault(x => x is GridGizmo);
+ if (hit != null)
+ {
+ // Use hit location
+ hitLocation = ray.Position + ray.Direction * closest;
+ hitNormal = normal;
+ }
+ else if (girdGizmo != null && girdGizmo.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 = view.GetPoint(100);
+ hitNormal = Vector3.Up;
+ }
+ }
+
+ 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
+ var transformGizmo = (TransformGizmo)_owner.Gizmos.FirstOrDefault(x => x is TransformGizmo);
+ if (transformGizmo != null && (_owner.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);
+ _owner.Spawn(actor);
+ _viewport.Focus();
+ }
+
+ 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);
+ }
+
+ private void Spawn(AssetItem item, SceneGraphNode hit, ref Float2 location, ref Vector3 hitLocation, ref Vector3 hitNormal)
+ {
+ if (item.IsOfType())
+ {
+ var material = FlaxEngine.Content.LoadAsync(item.ID);
+ if (material && !material.WaitForLoaded(500) && 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 = _viewport.ConvertMouseToRay(ref location);
+ if (staticModel.IntersectsEntry(ref ray, out _, out _, out var entryIndex))
+ {
+ using (new UndoBlock(_owner.Undo, staticModel, "Change material"))
+ staticModel.SetMaterial(entryIndex, material);
+ }
+ }
+ else if (hit is BoxBrushNode.SideLinkNode brushSurfaceNode)
+ {
+ using (new UndoBlock(_owner.Undo, brushSurfaceNode.Brush, "Change material"))
+ {
+ var surface = brushSurfaceNode.Surface;
+ surface.Material = material;
+ brushSurfaceNode.Surface = surface;
+ }
+ }
+ return;
+ }
+ if (item.IsOfType())
+ {
+ Editor.Instance.Scene.OpenScene(item.ID, true);
+ return;
+ }
+ {
+ var actor = item.OnEditorDrop(this);
+ actor.Name = item.ShortName;
+ Spawn(actor, ref hitLocation, ref hitNormal);
+ }
+ }
+ }
+}
diff --git a/Source/Editor/Windows/PluginsWindow.cs b/Source/Editor/Windows/PluginsWindow.cs
index c5ec02b31..268c22581 100644
--- a/Source/Editor/Windows/PluginsWindow.cs
+++ b/Source/Editor/Windows/PluginsWindow.cs
@@ -190,7 +190,7 @@ namespace FlaxEditor.Windows
};
_addPluginProjectButton = new Button
{
- Text = "Create Plugin Project",
+ Text = "Create Project",
TooltipText = "Add new plugin project.",
AnchorPreset = AnchorPresets.TopLeft,
LocalLocation = new Float2(70, 18),
@@ -201,7 +201,7 @@ namespace FlaxEditor.Windows
_cloneProjectButton = new Button
{
- Text = "Clone Plugin Project",
+ Text = "Clone Project",
TooltipText = "Git Clone a plugin project.",
AnchorPreset = AnchorPresets.TopLeft,
LocalLocation = new Float2(70 + _addPluginProjectButton.Size.X + 8, 18),
diff --git a/Source/Editor/Windows/SceneTreeWindow.cs b/Source/Editor/Windows/SceneTreeWindow.cs
index 250bd2301..63ba7b960 100644
--- a/Source/Editor/Windows/SceneTreeWindow.cs
+++ b/Source/Editor/Windows/SceneTreeWindow.cs
@@ -423,6 +423,7 @@ namespace FlaxEditor.Windows
var actor = item.OnEditorDrop(this);
actor.Name = item.ShortName;
Level.SpawnActor(actor);
+ Editor.Scene.MarkSceneEdited(actor.Scene);
}
result = DragDropEffect.Move;
}
@@ -440,6 +441,7 @@ namespace FlaxEditor.Windows
}
actor.Name = item.Name;
Level.SpawnActor(actor);
+ Editor.Scene.MarkSceneEdited(actor.Scene);
}
result = DragDropEffect.Move;
}
diff --git a/Source/Engine/Core/Types/StringBuilder.h b/Source/Engine/Core/Types/StringBuilder.h
index 051554a23..068f245d0 100644
--- a/Source/Engine/Core/Types/StringBuilder.h
+++ b/Source/Engine/Core/Types/StringBuilder.h
@@ -3,6 +3,7 @@
#pragma once
#include "String.h"
+#include "StringView.h"
#include "Engine/Core/Collections/Array.h"
///
@@ -138,6 +139,11 @@ public:
_data.Add(*str, str.Length());
return *this;
}
+ StringBuilder& Append(const StringView& str)
+ {
+ _data.Add(*str, str.Length());
+ return *this;
+ }
// Append int to the string
// @param val Value to append
diff --git a/Source/Engine/Graphics/Graphics.cpp b/Source/Engine/Graphics/Graphics.cpp
index fa03fb7cd..f91c58cea 100644
--- a/Source/Engine/Graphics/Graphics.cpp
+++ b/Source/Engine/Graphics/Graphics.cpp
@@ -67,7 +67,8 @@ void GraphicsSettings::Apply()
Graphics::AllowCSMBlending = AllowCSMBlending;
Graphics::GlobalSDFQuality = GlobalSDFQuality;
Graphics::GIQuality = GIQuality;
- Graphics::PostProcessSettings = PostProcessSettings;
+ Graphics::PostProcessSettings = ::PostProcessSettings();
+ Graphics::PostProcessSettings.BlendWith(PostProcessSettings, 1.0f);
}
void Graphics::DisposeDevice()
diff --git a/Source/Engine/Level/Actors/Sky.h b/Source/Engine/Level/Actors/Sky.h
index 81aca3653..6d0935f78 100644
--- a/Source/Engine/Level/Actors/Sky.h
+++ b/Source/Engine/Level/Actors/Sky.h
@@ -31,19 +31,19 @@ public:
///
/// Directional light that is used to simulate the sun.
///
- API_FIELD(Attributes="EditorOrder(10), DefaultValue(null), EditorDisplay(\"Sun\")")
+ API_FIELD(Attributes="EditorOrder(10), DefaultValue(null), EditorDisplay(\"Sky\")")
ScriptingObjectReference SunLight;
///
/// The sun disc scale.
///
- API_FIELD(Attributes="EditorOrder(20), DefaultValue(2.0f), EditorDisplay(\"Sun\"), Limit(0, 100, 0.01f)")
+ API_FIELD(Attributes="EditorOrder(20), DefaultValue(2.0f), EditorDisplay(\"Sky\"), Limit(0, 100, 0.01f)")
float SunDiscScale = 2.0f;
///
/// The sun power.
///
- API_FIELD(Attributes="EditorOrder(30), DefaultValue(8.0f), EditorDisplay(\"Sun\"), Limit(0, 1000, 0.01f)")
+ API_FIELD(Attributes="EditorOrder(30), DefaultValue(8.0f), EditorDisplay(\"Sky\"), Limit(0, 1000, 0.01f)")
float SunPower = 8.0f;
private:
diff --git a/Source/Engine/Level/Level.cpp b/Source/Engine/Level/Level.cpp
index a95b8070f..5f1432d31 100644
--- a/Source/Engine/Level/Level.cpp
+++ b/Source/Engine/Level/Level.cpp
@@ -1064,6 +1064,7 @@ bool Level::loadScene(rapidjson_flax::Value& data, int32 engineBuild, Scene** ou
}
}
}
+ prefabSyncData.InitNewObjects();
}
// /\ all above this has to be done on an any thread
diff --git a/Source/Engine/Level/SceneObjectsFactory.cpp b/Source/Engine/Level/SceneObjectsFactory.cpp
index a46edf070..985da6c29 100644
--- a/Source/Engine/Level/SceneObjectsFactory.cpp
+++ b/Source/Engine/Level/SceneObjectsFactory.cpp
@@ -403,6 +403,15 @@ SceneObjectsFactory::PrefabSyncData::PrefabSyncData(Array& sceneOb
{
}
+void SceneObjectsFactory::PrefabSyncData::InitNewObjects()
+{
+ for (int32 i = 0; i < NewObjects.Count(); i++)
+ {
+ SceneObject* obj = SceneObjects[InitialCount + i];
+ obj->Initialize();
+ }
+}
+
void SceneObjectsFactory::SetupPrefabInstances(Context& context, const PrefabSyncData& data)
{
PROFILE_CPU_NAMED("SetupPrefabInstances");
diff --git a/Source/Engine/Level/SceneObjectsFactory.h b/Source/Engine/Level/SceneObjectsFactory.h
index b1a9b8a9d..86fd5364a 100644
--- a/Source/Engine/Level/SceneObjectsFactory.h
+++ b/Source/Engine/Level/SceneObjectsFactory.h
@@ -78,6 +78,7 @@ public:
ISerializeModifier* Modifier;
PrefabSyncData(Array& sceneObjects, const ISerializable::DeserializeStream& data, ISerializeModifier* modifier);
+ void InitNewObjects();
private:
struct NewObj
diff --git a/Source/Engine/Platform/Apple/ApplePlatform.cpp b/Source/Engine/Platform/Apple/ApplePlatform.cpp
index c939c1af2..8a2e1d7ef 100644
--- a/Source/Engine/Platform/Apple/ApplePlatform.cpp
+++ b/Source/Engine/Platform/Apple/ApplePlatform.cpp
@@ -43,6 +43,7 @@
#include
#if CRASH_LOG_ENABLE
#include
+#include
#endif
CPUInfo Cpu;
@@ -502,20 +503,42 @@ Array ApplePlatform::GetStackFrames(int32 skipCount,
{
char** names = backtrace_symbols(callstack + skipCount, useCount);
result.Resize(useCount);
+ Array parts;
+ int32 len;
+#define COPY_STR(str, dst) \
+ len = Math::Min(str.Length(), ARRAY_COUNT(frame.dst) - 1); \
+ Platform::MemoryCopy(frame.dst, str.Get(), len); \
+ frame.dst[len] = 0
for (int32 i = 0; i < useCount; i++)
{
- char* name = names[i];
+ const StringAnsi name(names[i]);
StackFrame& frame = result[i];
frame.ProgramCounter = callstack[skipCount + i];
frame.ModuleName[0] = 0;
frame.FileName[0] = 0;
frame.LineNumber = 0;
- int32 nameLen = Math::Min(StringUtils::Length(name), ARRAY_COUNT(frame.FunctionName) - 1);
- Platform::MemoryCopy(frame.FunctionName, name, nameLen);
- frame.FunctionName[nameLen] = 0;
-
+
+ // Decode name
+ parts.Clear();
+ name.Split(' ', parts);
+ if (parts.Count() == 6)
+ {
+ COPY_STR(parts[1], ModuleName);
+ const StringAnsiView toDemangle(parts[3]);
+ int status = 0;
+ char* demangled = __cxxabiv1::__cxa_demangle(*toDemangle, 0, 0, &status);
+ const StringAnsiView toCopy = demangled && status == 0 ? StringAnsiView(demangled) : StringAnsiView(toDemangle);
+ COPY_STR(toCopy, FunctionName);
+ if (demangled)
+ free(demangled);
+ }
+ else
+ {
+ COPY_STR(name, FunctionName);
+ }
}
free(names);
+#undef COPY_STR
}
#endif
return result;
diff --git a/Source/Engine/Platform/Base/PlatformBase.cpp b/Source/Engine/Platform/Base/PlatformBase.cpp
index d15bec61c..9a6b1b9dc 100644
--- a/Source/Engine/Platform/Base/PlatformBase.cpp
+++ b/Source/Engine/Platform/Base/PlatformBase.cpp
@@ -633,14 +633,21 @@ String PlatformBase::GetStackTrace(int32 skipCount, int32 maxDepth, void* contex
for (const auto& frame : stackFrames)
{
StringAsUTF16 functionName(frame.FunctionName);
+ const StringView functionNameStr(functionName.Get());
if (StringUtils::Length(frame.FileName) != 0)
{
StringAsUTF16 fileName(frame.FileName);
- result.AppendFormat(TEXT(" at {0}() in {1}:line {2}\n"), functionName.Get(), fileName.Get(), frame.LineNumber);
+ result.Append(TEXT(" at ")).Append(functionNameStr);
+ if (!functionNameStr.EndsWith(')'))
+ result.Append(TEXT("()"));
+ result.AppendFormat(TEXT("in {0}:line {1}\n"),fileName.Get(), frame.LineNumber);
}
else if (StringUtils::Length(frame.FunctionName) != 0)
{
- result.AppendFormat(TEXT(" at {0}()\n"), functionName.Get());
+ result.Append(TEXT(" at ")).Append(functionNameStr);
+ if (!functionNameStr.EndsWith(')'))
+ result.Append(TEXT("()"));
+ result.Append('\n');
}
else
{
diff --git a/Source/Tools/Flax.Build/Build/DotNet/DotNetSdk.cs b/Source/Tools/Flax.Build/Build/DotNet/DotNetSdk.cs
index c2999999d..8eea4d6dd 100644
--- a/Source/Tools/Flax.Build/Build/DotNet/DotNetSdk.cs
+++ b/Source/Tools/Flax.Build/Build/DotNet/DotNetSdk.cs
@@ -249,11 +249,17 @@ namespace Flax.Build
if (dotnetSdkVersions == null)
dotnetSdkVersions = GetVersions(Path.Combine(dotnetPath, "sdk"));
if (dotnetRuntimeVersions == null)
- dotnetRuntimeVersions = GetVersions(Path.Combine(dotnetPath, "shared/Microsoft.NETCore.App"));
+ dotnetRuntimeVersions = GetVersions(Path.Combine(dotnetPath, "shared", "Microsoft.NETCore.App"));
+
+ dotnetSdkVersions = dotnetSdkVersions.Where(x => IsValidVersion(Path.Combine(dotnetPath, "sdk", x)));
+ dotnetRuntimeVersions = dotnetRuntimeVersions.Where(x => IsValidVersion(Path.Combine(dotnetPath, "shared", "Microsoft.NETCore.App", x)));
dotnetSdkVersions = dotnetSdkVersions.OrderByDescending(ParseVersion);
dotnetRuntimeVersions = dotnetRuntimeVersions.OrderByDescending(ParseVersion);
+ Log.Verbose($"Found the following .NET SDK versions: {string.Join(", ", dotnetSdkVersions)}");
+ Log.Verbose($"Found the following .NET runtime versions: {string.Join(", ", dotnetRuntimeVersions)}");
+
string dotnetSdkVersion = dotnetSdkVersions.FirstOrDefault(x => ParseVersion(x).Major >= MinimumVersion.Major && ParseVersion(x).Major <= MaximumVersion.Major);
string dotnetRuntimeVersion = dotnetRuntimeVersions.FirstOrDefault(x => ParseVersion(x).Major >= MinimumVersion.Major && ParseVersion(x).Major <= MaximumVersion.Major);
if (string.IsNullOrEmpty(dotnetSdkVersion))
@@ -276,7 +282,7 @@ namespace Flax.Build
// Pick SDK runtime
if (!TryAddHostRuntime(platform, architecture, rid) && !TryAddHostRuntime(platform, architecture, ridFallback))
{
- var path = Path.Combine(RootPath, $"packs/Microsoft.NETCore.App.Host.{rid}/{RuntimeVersionName}/runtimes/{rid}/native");
+ var path = Path.Combine(RootPath, "packs", $"Microsoft.NETCore.App.Host.{rid}", RuntimeVersionName, "runtimes", rid, "native");
Log.Warning($"Missing .NET SDK host runtime for {platform} {architecture} ({path}).");
return;
}
@@ -465,6 +471,11 @@ namespace Flax.Build
.FirstOrDefault();
}
+ private static bool IsValidVersion(string versionPath)
+ {
+ return File.Exists(Path.Combine(versionPath, ".version"));
+ }
+
private static string SearchForDotnetLocationLinux()
{
if (File.Exists("/etc/dotnet/install_location")) // Officially recommended dotnet location file
diff --git a/Source/Tools/Flax.Build/global.json b/Source/Tools/Flax.Build/global.json
index a6e7dc6c3..3fe9e80f6 100644
--- a/Source/Tools/Flax.Build/global.json
+++ b/Source/Tools/Flax.Build/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "7.0.0",
- "rollForward": "latestMinor"
+ "rollForward": "latestMajor"
}
}
\ No newline at end of file
diff --git a/global.json b/global.json
index a6e7dc6c3..3fe9e80f6 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "7.0.0",
- "rollForward": "latestMinor"
+ "rollForward": "latestMajor"
}
}
\ No newline at end of file