How to make a good pickup management ?

Hi all

I'm trying to design a good pickup management system and i want to share with you because i need help with it.

I have some approaches, all of them use 2 clases, PickUpControl and PickupManager.

1.-

First approach is when you trigger a Pickup (which have PickUpControl attached), then it sends a message to the onlyone PickUpManager in the scene. This PickUpManager recive the message, informs to some other systems about PickUp values, and then, send another message to PickUp to become inactive/invisible for a period of time.

I think this approach fails in optimitzation because message system, which uses PostMessages and Observers, will attempt to send one message for every PickUp when PickUpManager needs to send a message to one PickUp.

2.-

Second approach is when you Awake() your PickUpManager, make a Find() and put every PickUp finded in a vector-like structure, then, for every pickup, set an unique identifier. At same time, every PickUp in it's Awake() will Find() a reference of PickUpManager(). Then when you trigger a PickUp, this PickUp calls a function on PickUpManager informing it about the event, passing PickUp-ID as a parameter in this function. With this, PickUpManager can know which PickUp is triggered and instantly acces it via index or hashtable.

The problem of this approach is, whats happen if you have different type of PickUps in the scene ? Now you see all PickUps as the same type of PickUps with same call function control.

Conclusion:

Im trying to find a 'best practice' method for managing PickUps and if it can be, to use the same approach for managing other type of objects like Enemie <--> EnemyManager, etc...

Thanks for your time :)

A cheaper way to access a central manager is through singleton model: in Awake the class stores the this pointer into a public static variable so now you can call the object methods directly using this variable. Example in C#:

public class Example : MonoBehaviour {

    public static Example self;

    void Awake() {
        self = this;
    }

    void ExampleFunc() {
        // ...
    }
}

now you can call the `ExampleFunc` using `Example.self.ExampleFunc()`.

But why do you want to have pickups centralized? Why not just let the pickup know what it needs to give, give it when player walks over it's collider and destroy itself or if it need to respawn, disable the collider and the drawing and wait for a certain interval before enabling it again.

You can also sub-class from PickUp, so you can have PickUps with very different logic that all derive from PickUp, and therefore can all register themselves with your pickup manager.

The static Manager option is definitely preferable, however, I prefer this, for Awake safety

public class Example : MonoBehaviour {

    private static Example self;

    public static Example Self{
        get{
            if(self == null){
             //find this object and assign to self
            }
            return self;
        }
    }

    void Awake() {
        self = this;
    }

    void ExampleFunc() {
        // ...
    }
}