0
\$\begingroup\$

I am new to game development and for exercise I made endless runner where everything is generated randomly from prefabs and both player and obstacles are being destroyed once they are off the screen. There are two scenes - Start and Game. At the Start scene you can click on Play button which will take you to the Game scene and you can mute the sound.

When I start the game and I click on the Play button it loads the Game scene perfectly and game runs and works just fine. When player dies the game over window is shown. From there two options are available - either go to the Start scene or play the game one more time.

If I choose to play one more time everything works perfectly. But if I choose to go to the Start scene and then click on Play button to play the game then once the Game scene is loaded the player and the obstacle game objects are not being generated and floor and background Quads are not being resized properly to fit the screen. And I get the following error -

MissingReferenceException: The object of type 'RecycleGameObject' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
ObjectPool.NextObject (Vector3 pos) (at Assets/Scripts/ObjectPool.cs:28)

My question is - what can I do so that every time I come back to the scene everything is being loaded just like the first time?

I am currently loading scenes with this code:

SceneManager.LoadScene("Start");

And this is the ObjectPool class:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class ObjectPool : MonoBehaviour {

    public RecycleGameObject prefab;
    private List<RecycleGameObject> poolInstances = new List<RecycleGameObject>();

    private RecycleGameObject CreateInstance(Vector3 pos)
    {

        var clone = GameObject.Instantiate(prefab);
        clone.transform.position = pos;
        clone.transform.parent = transform;

        poolInstances.Add(clone);

        return clone;
    }

    public RecycleGameObject NextObject(Vector3 pos)
    {
        RecycleGameObject instance = null;

        foreach(var go in poolInstances)
        {
            if(go.gameObject.activeSelf != true)//here I get the error
            {
                instance = go;
                instance.transform.position = pos;
            }
        }

        if(instance == null)
        {
            instance = CreateInstance(pos);
        }


        instance.Restart();

        return instance;
    }



}
\$\endgroup\$
  • 1
    \$\begingroup\$ How are you currently loading your scenes? Can you paste the code in your question? \$\endgroup\$ – jgallant Aug 3 '16 at 11:50
  • \$\begingroup\$ The exception indicates that you are trying to access a game object which has been destroyed. The output gives you hints where to look. Check / Debug the ObjectPool class and see if you are accessing an object which is no longer there. \$\endgroup\$ – floAr Aug 3 '16 at 11:51
0
\$\begingroup\$

It seems like you are using object pooling. In other words you have a class with a list of object instances.

A scene change usually destroys all objects in it. You somehow managed that your object pool is not destroyed on scene change (There are several ways to do that, but it is not clear from the question which one you used. I would suspect it might have something to do with the way you ensured that it is globally available to all classes which need it). So your object pool retains its list of references to instantiated objects, but the objects themselves get destroyed on the scene change. So after the scene-change the pool is full of references to destroyed objects.

To solve the problem either re-initialize your object pool on scene changes or have it clear itself automatically by checking if a pooled object is == null and if it is re-Instantiate it.

Alternatively you can also attach your object pool to an invisible game-object in your scene. That way it gets re-initialized each time the scene is loaded.

By the way: Many games do not really need object pooling. When you are not sure you have performance problems which are caused by object destruction and re-instantiation, then it's just premature optimization. That means you spend time on implementing a system which adds more complexity and more potential bugs to your software architecture without giving you any tangible benefit.

\$\endgroup\$
  • \$\begingroup\$ Thank you very much! It works almost perfect now. Now only background and floor are not being resized properly when leaving and coming back to the scene. \$\endgroup\$ – niko85 Aug 3 '16 at 12:45
  • \$\begingroup\$ @niko85 To help you with that we would need to know more about how and where you implemented that resizing. But you already accepted the answer to this question, so you should post this as a new question. \$\endgroup\$ – Philipp Aug 3 '16 at 12:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.