Pickup

Pickup is the abstract base for items collected on collision. HealthPickup is the built-in one.

Pickup

MemberDescription
OnCollectedUnityEvent<GameObject> invoked when collected, with the collector (the collision’s Rigidbody GameObject when it has one).
bool TryCollect(Collision collision)Collects the pickup if Apply accepts the collision. Returns true if collected. Called automatically from OnCollisionEnter.
protected abstract bool Apply(Collision collision)Applies the pickup’s effect. Return false to ignore the collision.
protected virtual void OnCollisionEnter(Collision collision)Calls TryCollect. Override to collect from somewhere else.
protected virtual bool destroyOnCollectWhether the pickup is destroyed once collected. true by default.

When destroyOnCollect is true, the pickup is collected only once: OnCollected fires, then the GameObject is destroyed. When it’s false, the pickup stays and can be collected again on every new collision.

Note

Collision events need a non-kinematic Rigidbody on one of the two objects. Two kinematic bodies, or a kinematic body and a static collider, don’t collide by default.

HealthPickup

HealthPickup : Pickup changes the collector’s Health by _amount.

FieldTypeDescription
_amountfloatHealth change on collect. Positive calls Health.Heal, negative calls Health.Hurt.
_collectorsLayerMaskLayers that can collect the pickup.
_destroyOnCollectboolOverrides destroyOnCollect. When on, the pickup is also destroyed when it hits a collider without a Rigidbody.

Apply accepts a collision when the other collider is on a collector layer and has a living Health on itself or a parent. The DamageData uses the first contact’s point and normal, with the pickup as instigator.

Example: Health Pack

using UnityEngine;
using GlowingRifts.ModularHealthSystem;

public class HealthPack : Pickup
{
    [SerializeField] private float _amount = 25f;

    protected override bool Apply(Collision collision)
    {
        Health health = collision.collider.GetComponentInParent<Health>();
        if (!health || health.isDead || health.isFull) return false;

        health.Heal(new DamageData { damagePoints = _amount, instigator = gameObject });
        return true;
    }
}

Tip

Returning false when health is full leaves the pack in the world for later.