using Syntriax.Engine.Core; namespace Syntriax.Engine.Physics2D; public abstract class Collider2DBehaviourBase : Behaviour2D, ICollider2D { public Event OnCollisionDetected { get; private set; } = new(); public Event OnCollisionResolved { get; private set; } = new(); public Event OnTriggered { get; private set; } = new(); protected bool NeedsRecalculation { get; set; } = true; protected IRigidBody2D? _rigidBody2D = null; public IRigidBody2D? RigidBody2D => _rigidBody2D; public bool IsTrigger { get; set; } = false; public void Recalculate() { if (!NeedsRecalculation) return; CalculateCollider(); NeedsRecalculation = false; } public abstract void CalculateCollider(); protected override void OnInitialize() { BehaviourController.TryGetBehaviourInParent(out _rigidBody2D); BehaviourController.OnBehaviourAdded.AddListener(OnBehaviourAddedToController); BehaviourController.OnBehaviourRemoved.AddListener(OnBehaviourRemovedFromController); Transform.OnPositionChanged.AddListener(SetNeedsRecalculationFromPosition); Transform.OnRotationChanged.AddListener(SetNeedsRecalculationFromRotation); Transform.OnScaleChanged.AddListener(SetNeedsRecalculationFromScale); UniverseObject.OnParentChanged.AddListener(UpdateRigidBody2D); } private void UpdateRigidBody2D(IUniverseObject sender, IUniverseObject? previousParent, IUniverseObject? newParent) { BehaviourController.TryGetBehaviourInParent(out _rigidBody2D); } private void OnBehaviourAddedToController(IBehaviourController _, IBehaviour behaviour) { if (behaviour is IRigidBody2D rigidBody) _rigidBody2D = rigidBody; } private void OnBehaviourRemovedFromController(IBehaviourController _, IBehaviour behaviour) { if (behaviour is IRigidBody2D _) _rigidBody2D = null; } private void SetNeedsRecalculationFromScale(ITransform2D sender, Vector2D previousScale) => NeedsRecalculation = true; private void SetNeedsRecalculationFromPosition(ITransform2D sender, Vector2D previousPosition) => NeedsRecalculation = true; private void SetNeedsRecalculationFromRotation(ITransform2D sender, float previousRotation) => NeedsRecalculation = true; protected override void OnFinalize() { BehaviourController.OnBehaviourAdded.RemoveListener(OnBehaviourAddedToController); BehaviourController.OnBehaviourRemoved.RemoveListener(OnBehaviourRemovedFromController); Transform.OnScaleChanged.RemoveListener(SetNeedsRecalculationFromScale); Transform.OnPositionChanged.RemoveListener(SetNeedsRecalculationFromPosition); Transform.OnRotationChanged.RemoveListener(SetNeedsRecalculationFromRotation); } public void Detect(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionDetected?.Invoke(this, collisionDetectionInformation); public void Resolve(CollisionDetectionInformation collisionDetectionInformation) => OnCollisionResolved?.Invoke(this, collisionDetectionInformation); public void Trigger(ICollider2D initiator) => OnTriggered?.Invoke(this, initiator); }