Skip to main content

Collectable

Written by: Akram Taghavi-Burris | © Copyright 2024
Status

To transform our collectable data into interactive gameplay elements, we introduce the Collectable component. This component can be attached to any in-game object that should behave as a collectable. Designed for simplicity and flexibility, the Collectable component can be used as-is for basic collectables or extended to support more complex collectable behavior by serving as a parent class.

Implementing

The Collectable component leverages the CollectableData ScriptableObject we created earlier, allowing each instance to pull specific data directly from the assigned asset. Let's explore how this component works and then break down its code.

Collectable.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Collectable : MonoBehaviour
{
public CollectableData CollectableData; // Reference to the collectable data
private AudioSource _audioSource;
private AudioClip _audioClip;
[SerializeField]
private bool _destroyOnCollected = true;

// Called when game object initializes
public void Awake()
{
// Check if we have collectable data
if (CollectableData == null)
{
Debug.LogWarning("Collectable Data is not assigned in the inspector");
return; // Exit if data is not set
}

// If we have an audio source, set it up
if (TryGetComponent<AudioSource>(out AudioSource audioSource))
{
_audioSource = audioSource;
}

// Check if there's a collected sound clip in the data
if (CollectableData.CollectedSound != null)
{
_audioClip = CollectableData.CollectedSound;
}
}

// Called when the collectable is collected
public virtual void OnCollected()
{
PlayCollectedSound();

// If the collectable should be destroyed upon collection
if (_destroyOnCollected)
{
Destroy(gameObject);
}//end if(_destroyOnCollected)

}//end OnCollected()

// Plays the collectable's sound clip
private void PlayCollectedSound()
{
// Check if both _audioSource and _audioClip are set
if (_audioClip != null && _audioSource != null)
{
_audioSource.PlayOneShot(_audioClip);
}
else
{
Debug.LogWarning("Audio source or audio clip is not set. Sound will not play");
}//end If(_audioclip)

}//end PlayCollectedSound()
}

Key Features

  • Collectable Data Reference: The CollectableData field allows each instance of Collectable to access specific data for that collectable, making each instance unique while sharing common functionality.
  • Audio Playback: By using an AudioSource component and AudioClip from CollectableData, the Collectable component plays a sound when collected, giving instant audio feedback to the player.
  • Automatic Destruction: The _destroyOnCollected field allows control over whether the collectable should be removed from the game world after it's collected, which is particularly useful for single, use items like coins or power-ups.

Collecting Colletables

The OnCollected() method serves as the central action for the collectable. When called, it:

  1. Plays the associated sound, if one is set.
  2. Checks _destroyOnCollected to determine if the collectable should be removed from the game world.

This method is marked virtual, so if more complex behavior is needed, other collectables can inherit from Collectable and override OnCollected() with specific actions or effects, providing further flexibility.

Adding Collectable Component

By attaching the Collectable component to any in-game object, we can easily transform it into a collectable item. In the Unity Editor, this process is straightforward: we can add the Collectable component to any GameObject, such as our Apple prefab, and then assign the corresponding CollectableData asset, like "Red Apple" or "Golden Apple", in the Inspector. With the data stored in CollectableData, level designers have control over each item's properties in the Inspector, making it possible to add, customize, or remove collectables with minimal setup. This approach provides flexibility, allowing level designers to quickly modify collectables and fine-tune gameplay without changing code.

Now that we have a functional Collectable component, our items are ready to interact with the player. The next step is to create a Collector component, which will handle the logic for game objects that collect items, such as the player character, and manage interactions with the collectables themselves. This component will ensure that collectables trigger their effects upon collection, update game scores or inventory, and allow us to customize how collectables are gathered within the game.