Projectile destruction with Observer pattern

I’ve build a little prototype game. Each player can shoot projectile and can’t shoot again until it explodes (out of screen bounds, collision, etc). I’m using Observer pattern so player subscribes to projectile instance destruction delegate and changes its state when projectile destroyed. My question is: how do i unsubscribe from projectile that being destroyed?

public class Projectile : MonoBehaviour
{
    [SerializeField] private float _speed = 5f;
    private Rigidbody2D _rigidbody2D;
    public event Action OnDestroy;

    private void Awake()
    {
        _rigidbody2D = GetComponent<Rigidbody2D>();
    }

    private void FixedUpdate()
    {
        _rigidbody2D.MovePosition(_rigidbody2D.position + (Vector2)_rigidbody2D.transform.up * _speed * Time.fixedDeltaTime);
    }

    private void OnBecameInvisible()
    {
        OnDestroy?.Invoke();
        
        Destroy(gameObject);
    }
}

public class Player : MonoBehaviour
{
    [SerializeField] private Projectile _projectilePrefab;

    private bool _canShoot = true;

    private void Update()
    {
        ShootHandler();
    }

    private void ShootHandler()
    {
        if (_canShoot == false)
            return;

        if (Input.GetButtonDown(KeyCode.Space)) {
            _canShoot = false;

            Projectile projectile = Instantiate(_projectilePrefab, transform.position, Quaternion.identity);
            projectile.OnDestroy += ProjectileDestoyed;
        }
    }

    private void ProjectileDestoyed()
    {
        _canShoot = true;
    }
}

You don’t really need to unsubscribe to the event, because the projectile object has been destroyed. You would need to unsubscribe to the event if the lifetime of the player was shorter than the lifetime of the projectile, but it does not seem to be the case.

Anyway, if you really want to, here is how you could do it:

public class Projectile : MonoBehaviour
 {
     [SerializeField] private float _speed = 5f;
     private Rigidbody2D _rigidbody2D;

     // OnDestroy is a function of Unity, you may have problems
     // And I personally name my events with a past-tense verb
     // meaning something has occured.
     public event Action<Projectile> Destroyed;
 
     // ...
     private void OnBecameInvisible()
     {
         Destroyed?.Invoke(this);
         
         Destroy(gameObject);
     }
 }
 
 public class Player : MonoBehaviour
 {
     [SerializeField] private Projectile _projectilePrefab;
 
     private bool _canShoot = true;
 
     private void Update()
     {
         ShootHandler();
     }
 
     private void ShootHandler()
     {
         if (_canShoot == false)
             return;
 
         if (Input.GetButtonDown(KeyCode.Space)) {
             _canShoot = false;
 
             Projectile projectile = Instantiate(_projectilePrefab, transform.position, Quaternion.identity);
             projectile.Destroyed += ProjectileDestoyed;
         }
     }
 
     private void ProjectileDestoyed(Projectile destroyedProjectile)
     {
         destroyedProjectile.Destroyed  -= ProjectileDestoyed;
         _canShoot = true;
     }
 }