0
\$\begingroup\$

I wrote a script which pawns an object (instantiated prefab) each time the player touches the screen.

The maximum number of these spawned objects active in the scene at once is 3, and when they are not visible they will be destroyed. I need these prefabs to be able spawn again after they had been destroyed.

I tried this but it does not work...

This script is added to a game object called "canCreator" in my scene hierarchy:

public class CreatingCan: MonoBehaviour 
{
    public GameObject Can;
    public int numberOfCans;
    public bool canSpawn = true;

    private void Start()
    {      
        numberOfCans = 0;
    }
    void Update()
    {
        if (Input.touchCount > 0)
        {          
            Touch touch = Input.GetTouch(0);
            Vector2 TouchPosition = Camera.main.ScreenToWorldPoint(touch.position);
            if (touch.phase == TouchPhase.Began && canSpawn == true)
            {      
                if (Instantiate(Can, TouchPosition, Quaternion.identity))   
                {
                    numberOfCans++;                
                }
            }
        }
   
        if (numberOfCans >= 3)
        {
            canSpawn = false;
        }

    }

}

This script is on my can prefab:

public class fallingCan : MonoBehaviour 
{
    CreatingCan CC;
    private void Update()
    {
       
        if (transform.position.x < Camera.main.transform.position.x - 10)
        {
            Destroy(gameObject);
               CC.numberOfCans--;     
        }    
    }
}
\$\endgroup\$
3
  • \$\begingroup\$ "This does not work" should always be the start of a sentence where you explain why it does not work: what error message you get, how the behaviour of the code differs from what you need, etc. \$\endgroup\$
    – DMGregory
    Commented Aug 21, 2020 at 12:09
  • \$\begingroup\$ i can spawn 3 objects but then when they are destroyed i cannot spawn this objects again and also i get error message "Destroying assets is not permitted to avoid data loss" \$\endgroup\$
    – Cpt Teemo
    Commented Aug 21, 2020 at 13:13
  • \$\begingroup\$ That belongs in your question, not in a comment. \$\endgroup\$
    – DMGregory
    Commented Aug 21, 2020 at 13:16

2 Answers 2

0
\$\begingroup\$

A simple trick I like to use is introduce a self-counting object script:

public class CountedObject : MonoBehaviour {

    static int _count;

    void OnEnable() { _count++; }

    void OnDisable() { _count--; }

    public int GetActiveCount() { return _count; }
}

Then your spawner can look like...

public class CreatingCan: MonoBehaviour 
{
    public CountedObject canPrefab;
    public int spawnLimit = 3;
    public bool canSpawn = true;

    void Update()
    {
        // Don't spawn more if we've disabled spawning, or are at/above our limit.
        if (!canSpawn || canPrefab.GetActiveCount() >= spawnLimit)
            return;

        // Check all touches, not just the first one, so it works even if you
        // hold one finger on the screen, and tap with another.
        for (int i = 0; i < Input.touchCount; i++) {
            var touch = Input.GetTouch(i);
            if (touch.phase != TouchPhase.Began)
                continue; // Skip any old touches.

            Vector2 touchPosition = Camera.main.ScreenToWorldPoint(touch.position);
            Instantiate(canPrefab, touchPosition, Quaternion.identity)

            // Abort if we hit our limit, even if there are still more touches.
            if (canPrefab.GetActiveCount() >= spawnLimit)
                break;
        }
    }    
}
\$\endgroup\$
4
  • \$\begingroup\$ it works ! ty so much <3 \$\endgroup\$
    – Cpt Teemo
    Commented Aug 22, 2020 at 0:35
  • \$\begingroup\$ If it solved your problem, please click the checkmark icon to accept the answer. \$\endgroup\$
    – DMGregory
    Commented Aug 22, 2020 at 0:41
  • \$\begingroup\$ @CptTeemo Be careful with this script. The _count variable is static, which means every gameobject with this script will be counted with the same variable. This should work fine for the situation you described (counting cans) but will break down if you add a new type of object, such as bottles, which can also spawn in a different limited amount (say limit of 3 cans and 5 bottles). To get around this you would need to create a new CountedObject script with a different name, or change the _count to a collection (array, dictionary, or list) that can be referenced based on the items type/name. \$\endgroup\$ Commented Aug 22, 2020 at 4:01
  • \$\begingroup\$ If your end up in that situation, the curiously recurring template pattern will make it easy to spin up new varieties of counted objects. \$\endgroup\$
    – DMGregory
    Commented Aug 22, 2020 at 11:44
0
\$\begingroup\$

Here's your problem:

if (numberOfCans >= 3)
{
    canSpawn = false;
}

You never set canSpawn to true after this.

Maybe what you wanted is canSpawn = (numberOfCans >= 3). This will update canSpawn each frame.

\$\endgroup\$
2
  • \$\begingroup\$ I tried this and it sending me error message: Missing Reference Exception: The Object of type 'GameObject' has been destroyed but you are still trying to acces it.Your script should either check if it is null or you should not destroy the object. if (screenPos.x < -10f) { //< -40f numberOfPads--; canSpawn = true; Destroy(Cloud); //-------------------------- } \$\endgroup\$
    – Cpt Teemo
    Commented Aug 21, 2020 at 21:46
  • \$\begingroup\$ That means you deleted/destroyed the GameObject that you are using as the Can prefab. \$\endgroup\$
    – Kevin
    Commented Aug 21, 2020 at 22:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .