4
\$\begingroup\$

I want to create a block-based puzzle game that generates blocks as they are required, however I cannot seem to find any good information on how to do something like this using Unity's new sprite system.

Ideally the following would occur:

  • Generate a random number to determine the type of block
  • Create a sprite object of correct block type
  • Display block on screen

I currently have the following:

using UnityEngine;
using System.Collections;

public class Block : MonoBehaviour {

    public SpriteRenderer blockSprite;
    int row;
    int column;

    // Use this for initialization
    void Start () 
    {
        row = 0;
        column = 0;
    }

    // Update is called once per frame
    void Update () 
    {
        // gravity check
    }

    public void GenerateNewBlock()
    {
        int randNumber = Random.Range(0, System.Enum.GetNames(typeof(BlockType)).Length);
        Sprite sprite = new Sprite();

        blockSprite = gameObject.GetComponent<SpriteRenderer>();

        switch (randNumber)
        {
        case 0:
            sprite = Sprite.Create(AssetsLoader.Instance.BlockSprites[BlockType.Water], new Rect (0, 0, 100, 100), new Vector2(0, 0), 100.0f);
            break;
        case 1:
            sprite = Sprite.Create(AssetsLoader.Instance.BlockSprites[BlockType.Fire], new Rect (0, 0, 100, 100), new Vector2(0, 0), 100.0f);
            break;
        }
    }
}

public enum BlockType
{
    Water,
    Fire
}

And an assets loader Singleton class to load in the textures once into memory

using UnityEngine;
using System.Collections.Generic;

public class AssetsLoader : MonoBehaviour
{
    // instance variable to prevent multiple instances of this class
    private static AssetsLoader instance;

    // variables we want to retain state
    public Dictionary<BlockType, Texture2D> BlockSprites;

    // empty private constructor
    private AssetsLoader() {}

    // Property that holds the instance
    public static AssetsLoader Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new AssetsLoader();
            }

            return instance;
        }
    }

    // Use this for initialization
    void Start () 
    {
        BlockSprites = new Dictionary<BlockType, Sprite>();

        Sprite newSprite;

        newSprite = Resources.Load("Sprites/water block") as Texture2D;
        BlockSprites.Add(BlockType.Water, newSprite);

        newSprite = Resources.Load("Sprites/fire block") as Texture2D;
        BlockSprites.Add(BlockType.Fire, newSprite);
    }
}

Can someone please help me understand what needs to be done to create block objects in my scene. Ideally I would only use Sprite objects but I think I might need to load the assets in as Textures in order to get them to display.

\$\endgroup\$
5
\$\begingroup\$

I would use prefabs for a situation like this, you could use then to fill your dictionary like so:

public class AssetsLoader : MonoBehaviour
{
    public GameObject[] blockPrefabs;
    public Dictionary<String, Texture2D> blockTypes;

// ...

   void Start () 
   {
       blockTypes = new Dictionary<String, Sprite>();

       foreach(GameObject prefab in blockPrefabs) {
           blockTypes[prefab.name] = prefab;
       }
   }
}

This will expose the blockPrefabs array so you can drop any number of prefabs into it using the Inspector. Use meaningful names and they can function as keys for the dictionary.

You can then spawn them in your scene using Instantiate.

Edit: Another approach that would allow for enum based reference would be:

public enum BlockType
{
    Water = 0,
    Fire = 1
}

public class AssetsLoader : MonoBehaviour
{
    [SerializeField]
    private GameObject[] blockPrefabs;

    // ...

    public GameObject BlockSprites(BlockType blockType) {
        return blockPrefabs[(int)blockType];
    }
}

Here there would be a requirement to keep the contents of the array blockPrefabs and the values of the enum BlockType in sync.

\$\endgroup\$
1
  • \$\begingroup\$ A really good solution and very simple. I will try this out tonight \$\endgroup\$ Jan 14 '14 at 0:01

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.