97 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using Engine.Core;
 | 
						|
 | 
						|
namespace Engine.Physics2D;
 | 
						|
 | 
						|
public abstract class Collider2DBase : Behaviour2D, ICollider2D
 | 
						|
{
 | 
						|
    public Event<ICollider2D, CollisionDetectionInformation> OnCollisionDetected { get; } = new();
 | 
						|
    public Event<ICollider2D, CollisionDetectionInformation> OnCollisionResolved { get; } = new();
 | 
						|
    public Event<ICollider2D, ICollider2D> OnTriggered { get; } = new();
 | 
						|
 | 
						|
    private readonly Event<IBehaviourController, IBehaviourController.BehaviourAddedArguments>.EventHandler delegateOnBehaviourAddedToController = null!;
 | 
						|
    private readonly Event<IBehaviourController, IBehaviourController.BehaviourRemovedArguments>.EventHandler delegateOnBehaviourRemovedFromController = null!;
 | 
						|
    private readonly Event<ITransform2D, ITransform2D.PositionChangedArguments>.EventHandler delegateSetNeedsRecalculationFromPosition = null!;
 | 
						|
    private readonly Event<ITransform2D, ITransform2D.RotationChangedArguments>.EventHandler delegateSetNeedsRecalculationFromRotation = null!;
 | 
						|
    private readonly Event<ITransform2D, ITransform2D.ScaleChangedArguments>.EventHandler delegateSetNeedsRecalculationFromScale = null!;
 | 
						|
    private readonly Event<IUniverseObject, IUniverseObject.ParentChangedArguments>.EventHandler delegateUpdateRigidBody2D = null!;
 | 
						|
 | 
						|
    protected bool NeedsRecalculation { get; set; } = true;
 | 
						|
    protected IRigidBody2D? _rigidBody2D = null;
 | 
						|
 | 
						|
    protected Collider2DBase()
 | 
						|
    {
 | 
						|
        delegateOnBehaviourAddedToController = OnBehaviourAddedToController;
 | 
						|
        delegateOnBehaviourRemovedFromController = OnBehaviourRemovedFromController;
 | 
						|
        delegateSetNeedsRecalculationFromPosition = SetNeedsRecalculationFromPosition;
 | 
						|
        delegateSetNeedsRecalculationFromRotation = SetNeedsRecalculationFromRotation;
 | 
						|
        delegateSetNeedsRecalculationFromScale = SetNeedsRecalculationFromScale;
 | 
						|
        delegateUpdateRigidBody2D = UpdateRigidBody2D;
 | 
						|
    }
 | 
						|
 | 
						|
    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()
 | 
						|
    {
 | 
						|
        base.OnInitialize();
 | 
						|
 | 
						|
        BehaviourController.TryGetBehaviourInParent(out _rigidBody2D);
 | 
						|
 | 
						|
        BehaviourController.OnBehaviourAdded.AddListener(delegateOnBehaviourAddedToController);
 | 
						|
        BehaviourController.OnBehaviourRemoved.AddListener(delegateOnBehaviourRemovedFromController);
 | 
						|
 | 
						|
        Transform.OnPositionChanged.AddListener(delegateSetNeedsRecalculationFromPosition);
 | 
						|
        Transform.OnRotationChanged.AddListener(delegateSetNeedsRecalculationFromRotation);
 | 
						|
        Transform.OnScaleChanged.AddListener(delegateSetNeedsRecalculationFromScale);
 | 
						|
        UniverseObject.OnParentChanged.AddListener(delegateUpdateRigidBody2D);
 | 
						|
    }
 | 
						|
 | 
						|
    private void UpdateRigidBody2D(IUniverseObject sender, IUniverseObject.ParentChangedArguments args)
 | 
						|
    {
 | 
						|
        BehaviourController.TryGetBehaviourInParent(out _rigidBody2D);
 | 
						|
    }
 | 
						|
 | 
						|
    private void OnBehaviourAddedToController(IBehaviourController sender, IBehaviourController.BehaviourAddedArguments args)
 | 
						|
    {
 | 
						|
        if (args.BehaviourAdded is IRigidBody2D rigidBody)
 | 
						|
            _rigidBody2D = rigidBody;
 | 
						|
    }
 | 
						|
 | 
						|
    private void OnBehaviourRemovedFromController(IBehaviourController sender, IBehaviourController.BehaviourRemovedArguments args)
 | 
						|
    {
 | 
						|
        if (args.BehaviourRemoved is IRigidBody2D)
 | 
						|
            _rigidBody2D = null;
 | 
						|
    }
 | 
						|
 | 
						|
    private void SetNeedsRecalculationFromPosition(ITransform2D sender, ITransform2D.PositionChangedArguments args) => NeedsRecalculation = true;
 | 
						|
    private void SetNeedsRecalculationFromScale(ITransform2D sender, ITransform2D.ScaleChangedArguments args) => NeedsRecalculation = true;
 | 
						|
    private void SetNeedsRecalculationFromRotation(ITransform2D sender, ITransform2D.RotationChangedArguments args) => NeedsRecalculation = true;
 | 
						|
 | 
						|
    protected override void OnFinalize()
 | 
						|
    {
 | 
						|
        base.OnFinalize();
 | 
						|
 | 
						|
        BehaviourController.OnBehaviourAdded.RemoveListener(delegateOnBehaviourAddedToController);
 | 
						|
        BehaviourController.OnBehaviourRemoved.RemoveListener(delegateOnBehaviourRemovedFromController);
 | 
						|
        Transform.OnScaleChanged.RemoveListener(delegateSetNeedsRecalculationFromScale);
 | 
						|
 | 
						|
        Transform.OnPositionChanged.RemoveListener(delegateSetNeedsRecalculationFromPosition);
 | 
						|
        Transform.OnRotationChanged.RemoveListener(delegateSetNeedsRecalculationFromRotation);
 | 
						|
    }
 | 
						|
 | 
						|
    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);
 | 
						|
}
 |