Nik Myers
Nik Myers

Reputation: 1873

Unity3D async game object instantiation

I'm making my first project in Unity3D right now. This is a 2D game. This is some kind of a runner, but with possibility for player to go back on some distance. To achieve this functionality for the moment, i'm doing something like this:

When i was testing it on my PC, everything was fine, but for some reason, when next screen is creating it's causing my phone to lag for somewhat like a second, now how the code goes:

In Start() method of the script i'm initializing two scenes:

    Scene scene = new Scene ();
    scene.setSceneBounds (screenBounds);
    scene.createBackground (cameraOffsetOnStart, sceneSize);
    scene.createContent ();

    sceneNumber++;
    currentScenePosition = sceneSize * sceneNumber;
    Vector2 nextScenePosition = new Vector2 (cameraOffsetOnStart.x + currentScenePosition.x, cameraOffsetOnStart.y);

    Scene scene2 = new Scene ();
    screenBounds.min = new Vector2(min.x + currentScenePosition.x, min.y);
    screenBounds.max = new Vector2(max.x + currentScenePosition.x, max.y);
    scene2.setSceneBounds (screenBounds);
    scene2.createBackground (nextScenePosition, sceneSize);
    scene2.createContent ();

And then in Update() i'm checking if player exceedes current scene and creating new one:

void Update () {
    if (player.transform.position.x - playerOffset > sceneNumber * (max.x - min.x)) {
        Debug.Log("current scene is : " + (++sceneNumber));
        currentScenePosition = sceneSize * sceneNumber;
        Vector2 nextScenePosition = new Vector2 (cameraOffsetOnStart.x + currentScenePosition.x, cameraOffsetOnStart.y);
        Scene scene = new Scene();
        screenBounds.min = new Vector2(min.x + currentScenePosition.x, min.y);
        screenBounds.max = new Vector2(max.x + currentScenePosition.x, max.y);
        scene.setSceneBounds (screenBounds);
        scene.createBackground(nextScenePosition, sceneSize);
        scene.createWebs();
        sceneManager.Scenes.Add(scene);
    }
}

And the code for creating content:

public void createBackground(Vector2 position, Vector2 size) {
    background = new Background (position, size);
}

public void createContent() {
    Vector2[] positions = Utilities.generateRandomPositions(5, sceneBounds, 4f);

    for (int i = 0; i < positions.Length; i++) {
        Web web = ScriptableObject.CreateInstance<Web>();
        web.init(positions[i]);
    }
}

The problem of lagging comes from createContent method. Code for init :

    public void init(Vector2 position) {
        if (position != Vector2.zero) {
            obj = Instantiate (Resources.Load ("Textures/web", typeof(GameObject)), position, Quaternion.identity) as GameObject;
        }
    }

It's obvious that Instantiate method, calling 5 times in a row for 5 object is causing this behviour.

More details on "Textures/web" if needed: This is a prefab with circle collider and rigidbody, which set to be kinematic

Questions: Why it's lagging on only 5 items? Am i using Instantiate in a wrong way? How can i make it faster? Is there a way to call it async?

Upvotes: 0

Views: 8272

Answers (1)

Paweł Marecki
Paweł Marecki

Reputation: 630

As discussed in comments.

In line:

obj = Instantiate (Resources.Load ("Textures/web", typeof(GameObject)), position, Quaternion.identity) as GameObject;

You loading resources from devices memory each time you call this code. Just store GameObject in some variable e.g in Start() method.

Upvotes: 3

Related Questions