Cherr Skees
Cherr Skees

Reputation: 1518

Creating a List of Unity Objects

I'm trying to create a strip of sprites. I created a list of game objects and it seems to work ok. Except I have a duplicate object in the game view, so it seemed like I need to destroy my "template object". When I do that it looks fine, but then when I try to move them it says I'm trying to access an object that has been destroyed. Can someone help explain my issue? It seems that I'm confused on Instantiate and how it works exactly. I was under the impression that the object isn't created in the game view until the instantiate. But then why do I get a duplicate object? Thanks for your input.

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

public class ReelStrip : MonoBehaviour {
    public List <Sprite> image = new List<Sprite>();
    public List <int> index = new List<int>();
    public List <GameObject> symbol = new List<GameObject> ();
    public int reelNumber;
    public float symbolHeight = 1.74f;
    public float symbolWidth = 2.00f;
    public float speed = 0.01f;


    // Use this for initialization
    void Start () {
        reelNumber = 0;
        loadStrip (new List<int>{0,0,1,2,4,1,4,5});
    }

    void addSymbol(int indexToAdd)
    { 
        string name = "reelNum: " + reelNumber + " index " + indexToAdd;
        SpriteRenderer renderer = new SpriteRenderer ();
        GameObject symbolObject = new GameObject (name);
        symbolObject.AddComponent<SpriteRenderer> ();
        renderer = symbolObject.GetComponent<SpriteRenderer> ();
        symbolObject.AddComponent<symbol> ();
        Sprite loadedSprite = Resources.Load <Sprite>(symbolNameAtIndex(indexToAdd)) as Sprite;
        renderer.sprite = loadedSprite;
        symbol.Add (symbolObject);

        Vector3 newPos;
        if(symbol.Count<2)
        {
            newPos = new Vector3(0.0f,0.0f,0.0f);
                }
                else{
            newPos = new Vector3(symbol[symbol.Count-1].transform.position.x,symbol[symbol.Count-1].transform.position.y + symbolHeight, 0.0f);
            }
        Instantiate (symbol[symbol.Count-1], newPos, Quaternion.identity);
        // destroy template object


///// confused on the destroy //////
        //Destroy (symbolObject);



    }

    public void moveStripDown(float delta)
    {
        for (int i=0;i<symbol.Count;i++)
        {
            symbol[i].transform.position = new Vector3(symbol[i].transform.position.x,symbol[i].transform.position.y - delta, symbol[i].transform.position.z);

        }

    }

    public void loadStrip(List <int> Indexes)
    {
        for (int i=0;i<Indexes.Count;i++)
        {
            addSymbol (Indexes[i]);
        }

    }

    public string symbolNameAtIndex(int index)
    {
        string returnString;
    switch (index) {
        case 0:
            returnString = "img1";
            break;
        case 1:
            returnString = "img2";
            break;
        case 2:
            returnString = "img3";
            break;
        case 3:
            returnString = "img4";
            break;
        case 4:
            returnString = "img5";
            break;
        default:
            returnString = "symbolnotfound";
            break;



        }

        return returnString;
    }

    // Update is called once per frame
    void Update () {

        moveStripDown (speed*Time.deltaTime);
    }
}

Upvotes: 0

Views: 55345

Answers (1)

矢瑠飛
矢瑠飛

Reputation: 36

Since you have added the symbolObject to a list and later destroy the same symbolObject, the added object no longer exists when you try to move (although the reference stays in the list).

GameObject():GameObject creates a new GameObject in the hierarchy and Instantiate(original:Object):Object clones an object. When a GameObject is created or cloned, it will also appear in the hierarchy.

To get your code working, add the instantiated object to the list and then destroy the game object.

symbol.Add (Instantiate (symbol[symbol.Count-1], newPos, Quaternion.identity));
Destroy (symbolObject);

an alternative would be to skip the Instantiate step completely since you create a new game object every time.

However, I would recommend that you keep your game object as a prefab and load it from the resource folder and use Instantiate on said object. Read the folloiwng link for how to use the resources load folder (2nd example also shows how to use Instantiate for this) http://docs.unity3d.com/ScriptReference/Resources.Load.html

Upvotes: 2

Related Questions