diff --git a/Source/Engine/UI/GUI/CanvasContainer.cs b/Source/Engine/UI/GUI/CanvasContainer.cs
index 82c68a2cb..15e77985e 100644
--- a/Source/Engine/UI/GUI/CanvasContainer.cs
+++ b/Source/Engine/UI/GUI/CanvasContainer.cs
@@ -29,6 +29,33 @@ namespace FlaxEngine.GUI
return ((CanvasRootControl)a).Canvas.Order - ((CanvasRootControl)b).Canvas.Order;
}
+ private bool RayCast3D(ref Float2 location, out Control hit, out Float2 hitLocation)
+ {
+ hit = null;
+ hitLocation = Float2.Zero;
+
+ // Calculate 3D mouse ray
+ UICanvas.CalculateRay(ref location, out Ray ray);
+
+ // Test 3D canvases
+ var layerMask = MainRenderTask.Instance?.ViewLayersMask ?? LayersMask.Default;
+ for (int i = _children.Count - 1; i >= 0 && _children.Count > 0; i--)
+ {
+ var child = (CanvasRootControl)_children[i];
+ if (child.Visible && child.Enabled && child.Is3D && layerMask.HasLayer(child.Canvas.Layer))
+ {
+ if (child.Intersects3D(ref ray, out var childLocation))
+ {
+ hit = child;
+ hitLocation = childLocation;
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
///
public override void OnChildrenChanged()
{
@@ -63,8 +90,20 @@ namespace FlaxEngine.GUI
///
public override bool RayCast(ref Float2 location, out Control hit)
{
- // Ignore self
- return RayCastChildren(ref location, out hit);
+ // Ignore self and only test children
+ if (RayCastChildren(ref location, out hit))
+ return true;
+
+ // Test 3D
+ if (RayCast3D(ref location, out hit, out var hitLocation))
+ {
+ // Test deeper to hit actual control not the root
+ hit.RayCast(ref hitLocation, out hit);
+ if (hit != null)
+ return true;
+ }
+
+ return false;
}
///
@@ -81,22 +120,10 @@ namespace FlaxEngine.GUI
// 2D GUI first
base.OnMouseEnter(location);
- // Calculate 3D mouse ray
- UICanvas.CalculateRay(ref location, out Ray ray);
-
// Test 3D
- var layerMask = MainRenderTask.Instance?.ViewLayersMask ?? LayersMask.Default;
- for (int i = _children.Count - 1; i >= 0 && _children.Count > 0; i--)
+ if (RayCast3D(ref location, out var hit, out var hitLocation))
{
- var child = (CanvasRootControl)_children[i];
- if (child.Visible && child.Enabled && child.Is3D && layerMask.HasLayer(child.Canvas.Layer))
- {
- if (child.Intersects3D(ref ray, out var childLocation))
- {
- child.OnMouseEnter(childLocation);
- return;
- }
- }
+ hit.OnMouseEnter(hitLocation);
}
}
@@ -170,22 +197,11 @@ namespace FlaxEngine.GUI
if (base.OnMouseWheel(location, delta))
return true;
- // Calculate 3D mouse ray
- UICanvas.CalculateRay(ref location, out Ray ray);
-
// Test 3D
- var layerMask = MainRenderTask.Instance?.ViewLayersMask ?? LayersMask.Default;
- for (int i = _children.Count - 1; i >= 0 && _children.Count > 0; i--)
+ if (RayCast3D(ref location, out var hit, out var hitLocation))
{
- var child = (CanvasRootControl)_children[i];
- if (child.Visible && child.Enabled && child.Is3D && layerMask.HasLayer(child.Canvas.Layer))
- {
- if (child.Intersects3D(ref ray, out var childLocation))
- {
- child.OnMouseWheel(childLocation, delta);
- return true;
- }
- }
+ hit.OnMouseWheel(hitLocation, delta);
+ return true;
}
return false;
@@ -198,22 +214,11 @@ namespace FlaxEngine.GUI
if (base.OnMouseDown(location, button))
return true;
- // Calculate 3D mouse ray
- UICanvas.CalculateRay(ref location, out Ray ray);
-
// Test 3D
- var layerMask = MainRenderTask.Instance?.ViewLayersMask ?? LayersMask.Default;
- for (int i = _children.Count - 1; i >= 0 && _children.Count > 0; i--)
+ if (RayCast3D(ref location, out var hit, out var hitLocation))
{
- var child = (CanvasRootControl)_children[i];
- if (child.Visible && child.Enabled && child.Is3D && layerMask.HasLayer(child.Canvas.Layer))
- {
- if (child.Intersects3D(ref ray, out var childLocation))
- {
- child.OnMouseDown(childLocation, button);
- return true;
- }
- }
+ hit.OnMouseDown(hitLocation, button);
+ return true;
}
return false;
@@ -226,22 +231,11 @@ namespace FlaxEngine.GUI
if (base.OnMouseUp(location, button))
return true;
- // Calculate 3D mouse ray
- UICanvas.CalculateRay(ref location, out Ray ray);
-
// Test 3D
- var layerMask = MainRenderTask.Instance?.ViewLayersMask ?? LayersMask.Default;
- for (int i = _children.Count - 1; i >= 0 && _children.Count > 0; i--)
+ if (RayCast3D(ref location, out var hit, out var hitLocation))
{
- var child = (CanvasRootControl)_children[i];
- if (child.Visible && child.Enabled && child.Is3D && layerMask.HasLayer(child.Canvas.Layer))
- {
- if (child.Intersects3D(ref ray, out var childLocation))
- {
- child.OnMouseUp(childLocation, button);
- return true;
- }
- }
+ hit.OnMouseUp(hitLocation, button);
+ return true;
}
return false;
@@ -254,22 +248,11 @@ namespace FlaxEngine.GUI
if (base.OnMouseDoubleClick(location, button))
return true;
- // Calculate 3D mouse ray
- UICanvas.CalculateRay(ref location, out Ray ray);
-
// Test 3D
- var layerMask = MainRenderTask.Instance?.ViewLayersMask ?? LayersMask.Default;
- for (int i = _children.Count - 1; i >= 0 && _children.Count > 0; i--)
+ if (RayCast3D(ref location, out var hit, out var hitLocation))
{
- var child = (CanvasRootControl)_children[i];
- if (child.Visible && child.Enabled && child.Is3D && layerMask.HasLayer(child.Canvas.Layer))
- {
- if (child.Intersects3D(ref ray, out var childLocation))
- {
- child.OnMouseDoubleClick(childLocation, button);
- return true;
- }
- }
+ hit.OnMouseDoubleClick(hitLocation, button);
+ return true;
}
return false;
diff --git a/Source/Engine/UI/GUI/RootControl.cs b/Source/Engine/UI/GUI/RootControl.cs
index 43fce3d25..a325018a8 100644
--- a/Source/Engine/UI/GUI/RootControl.cs
+++ b/Source/Engine/UI/GUI/RootControl.cs
@@ -6,7 +6,7 @@ using System.Collections.Generic;
namespace FlaxEngine.GUI
{
///
- /// GUI root control that is represented by a window or an canvas and can contain children but has no parent at all. It's a source of the input events.
+ /// GUI root control that is represented by a window or a canvas and can contain children but has no parent at all. It's a source of the input events.
///
public abstract class RootControl : ContainerControl
{