Getting arrays to work correctly and efficiently in Unity

So the pieces are finally coming together for me with regards into how to get a city builder going and I’m currently poking through the set of tutorials I posted up on another thread. However I have questions about various things like how to do stuff more efficiently and I think I’ve managed to screw up just following this basic tutorial, it must be that I’ve put a misplaced comma somewhere because it’s all brand new code and I was just getting it into my head.

using UnityEngine;
using System.Collections;

public class TileMap : MonoBehaviour {

    public TileType[] tileTypes;

    int[,] tiles;

    int mapSizeX = 10;
    int mapSizeY = 10;

    void Start(){

        tiles = new int [mapSizeX, mapSizeY];

        // This code places the walkable tiles

        for (int x = 0; x < mapSizeX; x++) {
            for (int y = 0; y < mapSizeX; y++) {
                tiles [x, y] = 0;
            }
        }

        // This places the slowed tiles

        tiles [4, 4] = 1;
        tiles [5, 4] = 1;
        tiles [6, 4] = 1;
        tiles [7, 4] = 1;
        tiles [8, 4] = 1;

        tiles [8, 5] = 1;
        tiles [8, 6] = 1;
        tiles [8, 5] = 1;
        tiles [8, 6] = 1;

        GenerateMapVisual ();



    }

    void GenerateMapVisual ();{

        for (int x = 0; x < mapSizeX; x++) {
            for (int y = 0; y < mapSizeX; y++) {
                TileType tt = tileTypes [tiles [x, y]];
                Instantiate ( tt.tileVisualPrefab, new Vector3 (x, y, 0), Quaternion.identity);

            }
        }

    }

}

Arrays by themselves seem simple enough, they’re just places where you store lots and lots of content, in the example of a tiled grid like in the tutorial I’m following you’re placing all of the tiles at one location across a set of coordinates. What I’m curious about is the guy on the tutorial mentioned that with grids quite often games developers delete everything ones it goes off screen and then reloads it when the camera comes back. To me though that seems incredibly innefficient and not something that you’d perhaps do with modern computers? Since they’d usually be able to load things up unless the maps is ridiculously detailed like the total war games made the mistakes made.

What other techniques would you use to keep things efficient? To me the simplest thing even now I’m learning programming would be to keep the map as basic as possible so as to use less resources. Especially if you’re going turn based because what I always find is the developers load up so much detail without even thinking about it that they end up making turns last ridiculously long ( Oh god Rome 2 ;_; ) and I want to make sure to avoid that especially if you have a hybrid mix of real time and turn based gaming anyway you can focus on making the real time stuff nice and detailed.

If you could have a look at my code as well I’d be grateful, like I said, I think it’s just I’m new to arrays and don’t know where everything is supposed to go. I’ve also been experimenting with raycasting and will move on to instantiate, I get what each one of them is about, but it’s just a matter of making sure I get the right code and know how to combine everything.

For those who don’t know, here’s the tutorial I found.

 void GenerateMapVisual ();{

Remove the ; from after the () :slight_smile:

GOD DAMNIT! ;-; LOL thanks :smile:

^ apologies for the swearing if mods discover this, it’s so infuriating, I had just corrected another guy on this a couple of days ago!

wow, that’s a weird result, need to readjust my coordinates.

By the way guys, a new problem I came across, I’m trying to rotate the whole grid to face up so I everything looks better and it’s facing the right way up. In doing this, I ended up accidentally creating a grid with holes in it, so at least I’ve solved one thing I was wondering about with how to make hexagonal prefabs work however I still haven’t managed to flip the whole grid around because the piece of code I’m editing clearly only changes the rotation of the individual GameObjects being intatiated.

Instantiate (tt.tileVisualPrefab, new Vector3 (x, y), Quaternion.EulerAngles(0, 0, 180 ) );

Here’s what I’ve tried so far, it works, but as I said, I can’t flip the whole grid with this, when I try messing around with other numbers to change the position significantly the compiler complains with “Array index out of range”.

Why are you looping through your array in your Original code to set everything to 0? The moment you instantiate it: tiles = new int [mapSizeX, mapSizeY]; all values are already 0. This is because ‘int’ is a non nullable type, so it Always has to have a value, which defaults to 0; (just some optimizing).

If you want to flip the whole grid, just place the grid in a parent gameObject and flip that. That way the flipping is also more efficient as the grid object won’t need to be flipped relative to eachother, which means it’s a way cheaper operation.

I’m just following the tutorial above as I’m completely new to arrays and creating grids in general, as for your question about 0 ask the guy who made the tutorial lol :stuck_out_tongue: this is why I was asking these questions about efficiency and such though as well as just getting everything right.

Well the script is attached to an empty GameObject so I take it I need to write some new code in, I’ll experiment with what you said and see if that works.

Okay, I need to start studying and practicing arrays properly -_- there seem to be a number of ways to parent and also change positions etc. to the objects you instantiate through an array so I’m lost now, just don’t know where to put everything.

On the bright side, I managed to add a Z axis to my arrays without screwing everything up.

TileType tt = tileTypes [tiles [x, y]];
var instance = Instantiate ( tt.tileVisualPrefab, new Vector3 (x, y, 0), Quaternion.identity) as GameObject;
instance.transform.parent = this.gameObject.transform;

Assuming the script you show is on the actual parent object (it should be)

Thanks, interestingly I was searching around and did see that code but had absolutely no idea how to put it in.

Very frustrating, the parenting works and all the clones are clearly located within the empty’s hierarchy but this only happens when you press play rather than just having all the objects linked to constantly.

Sorry should I have been more specific? I was asking about how to just get the cubes all rotated to the correct axis before they were generated or rather during so this code can work on 3D coordinates.

Or should I for instance be creating all these tiles individually before hand and then calling them up? This is why I’ve been searching around for tutorials on this sort of thing because I don’t understand it at all.

yes runtime code only executes during runtime… unless you are writing custom editor scripts all the code you write will only do something when the game engine is running.

that isn’t exactly being more specific…

“correct axis”… Quaternion.identity is the “up aligned to x/y/z” what would you want the instantiated object to be aligned to?

“work on 3D coordinates”… “newVector3(x, y, 0)” x, y, z axis position. Change those and the instantiated object is put somewhere else when it is created. How do you want that to work?

Going to provide screenshots to make explaining things easier.

This is what it looks like on default.

!(http://i1134.photobucket.com/albums/m602/Lethn/Unity Screenshots/Unity 1_zps6qjyhjj4.png)

This is what I want it to be on default.

!(http://i1134.photobucket.com/albums/m602/Lethn/Unity Screenshots/Unity 2_zpsiyrtx3az.png)

Switch around the Y and Z axis. In Unity Y is up and Z is for depth, so that might be your problem now :slight_smile:

I did try that but it ended up putting everything vertically with 1 column of cubes, not sure why.

Oh I hate that so much, I just fixed it by myself.

var instance = Instantiate ( tt.tileVisualPrefab, new Vector3 (x, y, 0), Quaternion.identity) as GameObject;

I swapped the 0 round and of course, everything began to magically work because now it’s setting the coordinates of the Y axis to 0 and the coordinates of the Z axis to what’s in the main portion of the code.

var instance = Instantiate ( tt.tileVisualPrefab, new Vector3 (x, 0, z), Quaternion.identity) as GameObject;

lol thanks for your help so far guys, should be able to proceed from here unless I run into more annoyances, this way I can have the camera operate as a normal 3D camera as well without having to mess around with that bit of code too.

I just forgot guys, I wanted to get some answers on efficiency, for instance, even though this method works for tiny grids it definitely doesn’t work for the large stuff and modern games use 100x100 or even larger. What would be the best option for placing prefabs? Sprites perhaps? Let me know.

I’ve been doing some searching again by the way and found out about Mesh Filters, will be looking into that because that seems to be more like what I’m looking for in general.

Well, it really depends on the type of game you want to make. If you want to make a game like Minecraft, then check this out: [Tutorial] c# voxel terrain with infinite terrain, saving and loading - Learn Content & Certification - Unity Discussions

If you want to make a 2d top down or isometric game though, you just want to do it with sprites like you currently do it with cubes.

Isn’t that still pretty inefficient though? Because in the end you’re still creating lots and lots of objects, while they’re sprites it’s still taking up lots of resources just to be able to point and click something accurately. Thanks for that link on voxels, it’s interesting, but I’m purely thinking in terms of 3D simulation games/city builders like Cities:Skylines and Theme Park and so on.

I’ll tell you what though, I’ve had much more success experimenting with getting objects to intatiate to a raycast point. My only thing is for city builders and such this isn’t really the best option because you want to be able to click and drag from one point to another when you’re creating stuff.

Also if I want to try making a proper Civilisation style game that’s going to be much more difficult because turn based games seem to explicitly use grids.

Ah well, if you want to do something with a lot of objects like roads in Cities: Skyline or a Rollercoaster in Theme Park, you might want to look into merging maeshes into single draw calls: http://wiki.unity3d.com/index.php?title=MeshMerger

Yikes, thanks, that looks pretty complicated, this is why I wish there was a good step by step tutorial, might be able to work things out from the comments though. No wonder there are so few simulation game tutorials out there that use grid systems, it’s pretty complicated stuff. Kind of annoying that people have over-saturated youtube etc. with FPS tutorials though and not had a proper go at something tricky.

But yeah, I’ve always really liked games like Dungeon Keeper and Startopia, so I want to try my hand at getting these grids setup correctly so I can properly make these sorts of games anybody can make an FPS, but it looks like it takes quite a lot of skill to build a simulation game.