Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Call function only once in Coroutine

Discussion in 'Getting Started' started by dawidlipecki43, Nov 4, 2021.

  1. dawidlipecki43

    dawidlipecki43

    Joined:
    Oct 8, 2021
    Posts:
    1
    Hey, I am pretty new to Unity and all, I've been playing around with it in school for last 2-3 weeks.
    I am creating a game that spawns enemies and counts your score for every enemy killed. I am using a coroutine to spawn the enemies, but now I wanted to change the amount of enemies spawned per second, after you killed a few of them. Problem is if I try to use the line "
    ScoreManager testScore = GameObject.Find("Scores").GetComponent<ScoreManager>(); "
    it calls it infinite amount of times and it eats up my ram until I go into Task Manager and turn it off.
    So the question I have is how can I call the ScoreManager line only once?



    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class SpawnManager : MonoBehaviour
    6. {
    7.     [SerializeField]
    8.     private GameObject _enemyPrefab;
    9.     void Start()
    10.    
    11.     {
    12.         StartCoroutine(SpawnRoutine());
    13.     }
    14.  
    15.    
    16.     private IEnumerator SpawnRoutine()
    17.     {
    18.         while (true)
    19.         {
    20.             float randomX = Random.Range(-21f, 21f);
    21.             Instantiate(_enemyPrefab, new Vector3(randomX, 15f, 0),
    22.                 Quaternion.identity);
    23.             ScoreManager testScore = GameObject.Find("Scores").GetComponent<ScoreManager>();
    24.             if ((testScore.score > 0) && (testScore.score < 10))
    25.             {
    26.             yield return new WaitForSeconds(1.5f);
    27.             }
    28.             if ((testScore.score > 10) && (testScore.score < 20))
    29.             {
    30.             yield return new WaitForSeconds(1f);
    31.             }
     
  2. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    Find your object/component once and cache it from the
    Start
    method:
    Code (CSharp):
    1. private ScoreManager _testScore;
    2.  
    3. void Start()
    4. {
    5.   _testScore = GameObject.Find("Scores").GetComponent<ScoreManager>();
    6. }
    Or even better, ditch
    GameObject.Find
    and just expose
    _testScore
    in the inspector, then drag/drop the reference to it.
     
  3. FrankSchmutz

    FrankSchmutz

    Joined:
    Apr 18, 2020
    Posts:
    4
    You probably have a case of an infinite loop.
    It seems you do not have a
    yield return
    instruction if your test score is 0, 10, or 20 and above. You need to make sure that a
    yield return
    instruction is executed in every single iteration of the loop.