diff --git a/Source/Editor/SceneGraph/Actors/BoxColliderNode.cs b/Source/Editor/SceneGraph/Actors/BoxColliderNode.cs index 1f92eceea..8c00318db 100644 --- a/Source/Editor/SceneGraph/Actors/BoxColliderNode.cs +++ b/Source/Editor/SceneGraph/Actors/BoxColliderNode.cs @@ -8,8 +8,33 @@ using Real = System.Single; using FlaxEngine; +#if FLAX_EDITOR +using FlaxEditor.CustomEditors.Dedicated; +using FlaxEditor.CustomEditors; +#endif + namespace FlaxEditor.SceneGraph.Actors { +#if FLAX_EDITOR + /// + /// Dedicated custom editor for BoxCollider objects. + /// + [CustomEditor(typeof(BoxCollider)), DefaultEditor] + public class BoxColliderEditor : ActorEditor + { + /// + public override void Initialize(LayoutElementsContainer layout) + { + base.Initialize(layout); + layout.Space(20f); + var autoResizeButton = layout.Button("Resize to Fit", "Resize the box collider to fit it's parent's bounds."); + + BoxCollider collider = Values[0] as BoxCollider; + autoResizeButton.Button.Clicked += collider.AutoResize; + } + } +#endif + /// /// Scene tree node for actor type. /// @@ -37,5 +62,13 @@ namespace FlaxEditor.SceneGraph.Actors return base.RayCastSelf(ref ray, out distance, out normal); } + + /// + public override void PostSpawn() + { + base.PostSpawn(); + BoxCollider boxCollider = Actor as BoxCollider; + boxCollider.AutoResize(); + } } } diff --git a/Source/Engine/Level/Actors/BoxCollider.cs b/Source/Engine/Level/Actors/BoxCollider.cs new file mode 100644 index 000000000..cfb6e9dde --- /dev/null +++ b/Source/Engine/Level/Actors/BoxCollider.cs @@ -0,0 +1,56 @@ +#if FLAX_EDITOR +using FlaxEditor.CustomEditors; +using FlaxEditor.CustomEditors.Dedicated; +#endif + +namespace FlaxEngine +{ + partial class BoxCollider + { + private void BoxExcluding(Actor target, ref BoundingBox output, Actor excluded) + { + foreach (Actor child in target.Children) + { + if (child == excluded) + { + continue; + } + + output = BoundingBox.Merge(output, child.Box); + BoxExcluding(child, ref output, excluded); + } + } + + /// + /// Resizes the box collider based on the bounds of it's parent. + /// + public void AutoResize() + { + if (Parent is Scene) + { + return; + } + + LocalPosition = Vector3.Zero; + + Vector3 parentScale = Parent.Scale; + BoundingBox parentBox = Parent.Box; + BoxExcluding(Parent, ref parentBox, this); + + Vector3 parentSize = parentBox.Size; + Vector3 parentCenter = parentBox.Center - Parent.Position; + + // Avoid division by zero + if (parentScale.X == 0 || parentScale.Y == 0 || parentScale.Z == 0) + { + return; + } + + Size = parentSize / parentScale; + Center = parentCenter / parentScale; + + // Undo Rotation + Orientation *= Quaternion.Invert(Orientation); + } + } +}