Abstract pickup component for items and ammo. It listens for trigger and collision events, checks player and inventory, applies CanPickup and OnPickup logic, plays pickup sound via an RPC broadcast, and destroys the game object on success.
/// <summary>
/// A weapon, or weapons, or ammo, that can be picked up
/// </summary>
public abstract class BasePickup : Component, Component.ITriggerListener, Component.ICollisionListener
{
/// <summary>
/// The pickup's collider, it is required
/// </summary>
[RequireComponent] public Collider Collider { get; set; }
/// <summary>
/// The sound to play when picking up this item
/// </summary>
[Property] public SoundEvent PickupSound { get; set; }
/// <summary>
/// Check if the player can pick up this object
/// </summary>
public virtual bool CanPickup( Player player, PlayerInventory inventory )
{
return true;
}
/// <summary>
/// Give the player the effect of this pickup
/// </summary>
/// <returns>Should this object be consumed, eg on successful pickup</returns>
protected virtual bool OnPickup( Player player, PlayerInventory inventory )
{
return true;
}
/// <summary>
/// Called when a gameobject enters the trigger.
/// </summary>
void ITriggerListener.OnTriggerEnter( GameObject other )
{
if ( !Networking.IsHost ) return;
if ( GameObject.IsDestroyed ) return;
if ( !other.Components.TryGet( out Player player ) )
return;
if ( !player.Components.TryGet( out PlayerInventory inventory ) )
return;
if ( !CanPickup( player, inventory ) )
return;
if ( !OnPickup( player, inventory ) )
return;
PlayPickupEffects( player );
DestroyGameObject();
}
/// <summary>
/// Called when a gameobject enters the trigger.
/// </summary>
void ICollisionListener.OnCollisionStart( Collision collision )
{
if ( !Networking.IsHost ) return;
if ( GameObject.IsDestroyed ) return;
if ( !collision.Other.GameObject.Root.Components.TryGet( out Player player ) )
return;
if ( !player.Components.TryGet( out PlayerInventory inventory ) )
return;
if ( !CanPickup( player, inventory ) )
return;
if ( !OnPickup( player, inventory ) )
return;
PlayPickupEffects( player );
DestroyGameObject();
}
[Rpc.Broadcast]
protected void PlayPickupEffects( Player player )
{
if ( Application.IsDedicatedServer ) return;
var snd = GameObject.PlaySound( PickupSound );
if ( !snd.IsValid() )
return;
if ( player.IsValid() && player.IsLocalPlayer )
{
snd.SpacialBlend = 0;
}
}
}