How To Find A Spawned Object Only Once While It's On Screen?

Hello again,

I’ve been hacking away at my Arkanoid project for about a week and i’m learning new things every day. I have a level with paddle, ball and bricks. Each time the ball hits a brick, a power up spawns and falls downward as you can see in the FixedUpdate method below. To prevent there from being more than one power up on screen at any time i use the canSpawn boolean.

My question is how FindWithTag(“PowerUp”) can be implemented in the best way. I realize that it’s not optimal trying to find the object each frame. Since the object doesn’t exists from start, but is rather instantiated when a brick is hit, what is the best approach to find the game object only one time as it spawns and then move it downwards to eventually destroy it?

But i’m still learning Unity and C#, so maybe you need to locate it each frame in order to kinematically move it?

public class PowerUp : MonoBehaviour
{

    private Rigidbody2D rb;
    private GameObject powerUp;
    private static bool canSpawn = true;

    private static int PowerUpCount = 6;
    private static int increaseChance = 0;

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

    // Update is called once per frame
    void FixedUpdate()
    {
        // As long as a power up is on screen it should move downwards
        if (!canSpawn)
        {
            powerUp = GameObject.FindWithTag("PowerUp");
            rb.isKinematic = false;
            powerUp.transform.position -= powerUp.transform.up * Time.deltaTime * 0.5f;
        }
    }

    // Destroy the powerup when the camera can't see it
    void OnBecameInvisible()
    {
        Destroy(powerUp);
        canSpawn = true;
    }

    // Check if the power up can spawn and flip the bool
    public static bool CanSpawn
    {
        get
        {
            return canSpawn;
        }
        set
        {
            canSpawn = value;
        }
    }

    // Spawn a new powerup
    public static void Spawn(Vector3 pos)
    {
        Instantiate(Resources.Load("Prefabs/Laser"), pos, Quaternion.identity);
        CanSpawn = !CanSpawn;
        PowerUpCount--;
        IncreaseChance = 0;
    }

    public static int CheckCount()
    {
        return PowerUpCount;
    }

    // Get/set
    public static int IncreaseChance
    {
        get
        {
            return increaseChance;
        }
        set
        {
            increaseChance = value;
        }
    }

    // Check for collisions
    void OnCollisionEnter2D(Collision2D col)
    {
        if (col.collider.name == "Laser")
            print("PEW, PEW!");
        Destroy(powerUp);
    }
}

You would store a reference when you instantiate it. I’m not sure what you are thinking in your logic here though. Is the class you posted meant to be a powerup manager or is it on the powerup?

Like a mentioned, i’m new to both Unity and C#.

It’s the script attached to the power up game object and as such, has all the logic regarding the object. Is the proper way to have two scripts for one object or why are you asking?

At the top I would write:

GameObject powerupReference

When you instantiate it you can do:

powerupReference = Instantiate(Resources.Load(“Prefabs/Laser”), pos, Quaternion.identity);

and then you anywhere in the script you can call

if (powerupReference != null)

powerupReference.transform…