diff --git a/Source/Editor/SceneGraph/Actors/BoxColliderNode.cs b/Source/Editor/SceneGraph/Actors/BoxColliderNode.cs index 1f92eceea..566cefb5e 100644 --- a/Source/Editor/SceneGraph/Actors/BoxColliderNode.cs +++ b/Source/Editor/SceneGraph/Actors/BoxColliderNode.cs @@ -7,9 +7,37 @@ using Real = System.Single; #endif using FlaxEngine; +using FlaxEditor.CustomEditors.Dedicated; +using FlaxEditor.CustomEditors; +using FlaxEditor.Scripting; namespace FlaxEditor.SceneGraph.Actors { + /// + /// 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); + layout.Button("Resize to Fit", Editor.Instance.CodeDocs.GetTooltip(new ScriptMemberInfo(typeof(BoxCollider).GetMethod("AutoResize")))).Button.Clicked += OnResizeClicked; + } + + private void OnResizeClicked() + { + foreach (var value in Values) + { + if (value is BoxCollider collider) + collider.AutoResize(); + } + } + } + /// /// Scene tree node for actor type. /// @@ -37,5 +65,13 @@ namespace FlaxEditor.SceneGraph.Actors return base.RayCastSelf(ref ray, out distance, out normal); } + + /// + public override void PostSpawn() + { + base.PostSpawn(); + + ((BoxCollider)Actor).AutoResize(); + } } } diff --git a/Source/Engine/Physics/Colliders/BoxCollider.cpp b/Source/Engine/Physics/Colliders/BoxCollider.cpp index b80b68de0..d74b3efba 100644 --- a/Source/Engine/Physics/Colliders/BoxCollider.cpp +++ b/Source/Engine/Physics/Colliders/BoxCollider.cpp @@ -2,6 +2,7 @@ #include "BoxCollider.h" #include "Engine/Physics/PhysicsBackend.h" +#include "Engine/Level/Scene/Scene.h" BoxCollider::BoxCollider(const SpawnParams& params) : Collider(params) @@ -19,6 +20,32 @@ void BoxCollider::SetSize(const Float3& value) UpdateBounds(); } +void BoxCollider::AutoResize() +{ + Actor* parent = GetParent(); + if (Cast(parent)) + return; + + // Get bounds of all siblings (excluding itself) + const Vector3 parentScale = parent->GetScale(); + if (parentScale.IsAnyZero()) + return; // Avoid division by zero + BoundingBox parentBox = parent->GetBox(); + for (const Actor* sibling : parent->Children) + { + if (sibling != this) + BoundingBox::Merge(parentBox, sibling->GetBoxWithChildren(), parentBox); + } + const Vector3 parentSize = parentBox.GetSize(); + const Vector3 parentCenter = parentBox.GetCenter() - parent->GetPosition(); + + // Update bounds + SetLocalPosition(Vector3::Zero); + SetSize(parentSize / parentScale); + SetCenter(parentCenter / parentScale); + SetOrientation(GetOrientation() * Quaternion::Invert(GetOrientation())); +} + #if USE_EDITOR #include "Engine/Debug/DebugDraw.h" diff --git a/Source/Engine/Physics/Colliders/BoxCollider.h b/Source/Engine/Physics/Colliders/BoxCollider.h index 5bcc21b45..3c15ce640 100644 --- a/Source/Engine/Physics/Colliders/BoxCollider.h +++ b/Source/Engine/Physics/Colliders/BoxCollider.h @@ -43,6 +43,11 @@ public: return _bounds; } + /// + /// Resizes the collider based on the bounds of it's parent to contain it whole (including any siblings). + /// + API_FUNCTION() void AutoResize(); + public: // [Collider] #if USE_EDITOR