Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

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

Discussion in 'Scripting' started by Takodan, Apr 11, 2019.

  1. Takodan

    Takodan

    Joined:
    Nov 19, 2017
    Posts:
    6
    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?

    Code (CSharp):
    1.  
    2. public class PowerUp : MonoBehaviour
    3. {
    4.  
    5.     private Rigidbody2D rb;
    6.     private GameObject powerUp;
    7.     private static bool canSpawn = true;
    8.  
    9.     private static int PowerUpCount = 6;
    10.     private static int increaseChance = 0;
    11.  
    12.     void Awake()
    13.     {
    14.         rb = GetComponent<Rigidbody2D>();
    15.     }
    16.  
    17.     // Update is called once per frame
    18.     void FixedUpdate()
    19.     {
    20.         // As long as a power up is on screen it should move downwards
    21.         if (!canSpawn)
    22.         {
    23.             powerUp = GameObject.FindWithTag("PowerUp");
    24.             rb.isKinematic = false;
    25.             powerUp.transform.position -= powerUp.transform.up * Time.deltaTime * 0.5f;
    26.         }
    27.     }
    28.  
    29.     // Destroy the powerup when the camera can't see it
    30.     void OnBecameInvisible()
    31.     {
    32.         Destroy(powerUp);
    33.         canSpawn = true;
    34.     }
    35.  
    36.     // Check if the power up can spawn and flip the bool
    37.     public static bool CanSpawn
    38.     {
    39.         get
    40.         {
    41.             return canSpawn;
    42.         }
    43.         set
    44.         {
    45.             canSpawn = value;
    46.         }
    47.     }
    48.  
    49.     // Spawn a new powerup
    50.     public static void Spawn(Vector3 pos)
    51.     {
    52.         Instantiate(Resources.Load("Prefabs/Laser"), pos, Quaternion.identity);
    53.         CanSpawn = !CanSpawn;
    54.         PowerUpCount--;
    55.         IncreaseChance = 0;
    56.     }
    57.  
    58.     public static int CheckCount()
    59.     {
    60.         return PowerUpCount;
    61.     }
    62.  
    63.     // Get/set
    64.     public static int IncreaseChance
    65.     {
    66.         get
    67.         {
    68.             return increaseChance;
    69.         }
    70.         set
    71.         {
    72.             increaseChance = value;
    73.         }
    74.     }
    75.  
    76.     // Check for collisions
    77.     void OnCollisionEnter2D(Collision2D col)
    78.     {
    79.         if (col.collider.name == "Laser")
    80.             print("PEW, PEW!");
    81.         Destroy(powerUp);
    82.     }
    83. }
    84.  
    85.  
     
  2. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    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?
     
  3. Takodan

    Takodan

    Joined:
    Nov 19, 2017
    Posts:
    6
    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?
     
  4. adreamvoyager_unity

    adreamvoyager_unity

    Joined:
    Oct 16, 2018
    Posts:
    14
    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.......