Day 21 - Cellular Extraction

Dealing with the different spacial representations…differently.


Current status: Ugh.

Assets/Managers/MapManager.cslink
27
28
29
30
31
32
33
34
35
36
37
38
39
private Vector3 nextPosition, nextScale;
private Queue<Transform> objectQueue;
private Dictionary<Vector3, Transform> cell_transforms;
private bool directionRight;

public float nextDBUpdate;
public float dbUpdateDelta = 5f;

private List<string> cellKeyList;
private Dictionary<Vector3, CellLite> cells;
private List<Vector3> cellsKeys;

private Dictionary<Vector3,Transform> portalTransforms;
Assets/Managers/MapManager.cslink
89
Vector3 position = new Vector3((-1f) * cells[v].x, (-1f) * cells[v].y, 0.1f * cells[v].z);
Assets/Managers/MapManager.cslink
144
145
tempts.position += new Vector3(-0.5f * (bestXSize - 1), -0.5f * (bestYSize - 1), 0f);
tempts.localScale += new Vector3((float) (bestXSize - 1), (float) (bestYSize - 1), 0f);
Assets/Managers/MapManager.cslink
151
Vector3 position = new Vector3((-1f) * cells[v].x, (-1f) * cells[v].y, (0.1f * cells[v].z) + 0.5f);
Assets/Managers/NpcManager.cslink
25
26
private Dictionary<int, Vector3> npcLocations;
private Dictionary<Vector3,List<int>> cellsContainingNpcs = new Dictionary<Vector3,List<int>>();
Assets/Managers/NpcManager.cslink
107
Vector3 position = new Vector3((-1f) * npc.X, (-1f) * npc.Y, (0.1f * npc.Z) + 0.2f);
Assets/Managers/NpcManager.cslink
166
167
168
169
170
171
172
173
foreach (int npcId in cellsContainingNpcs[cell]) {
    Vector3 scale = new Vector3(1.0f/dimension, 1.0f/dimension, npcScripts[npcId].transform.localScale.z);
    Vector3 position = new Vector3((-1f) * cell.x, (-1f) * cell.y, (0.1f * cell.z) + 0.2f); // start at the center of the cell
    position += new Vector3(0.5f, 0.5f, 0f); // move to corner
    position -= new Vector3(column * (1.0f/dimension), row * (1.0f/dimension), 0f);
    position -= new Vector3((1.0f/dimension)/2f, (1.0f/dimension)/2f, 0f);
    npcScripts[npcId].newPosition = position;
    npcScripts[npcId].newScale = scale;

The natural coordinates of a cell are discrete values, but we’re using a Vector3 (three floating point values) everywhere. Expensive. Plus, we’re making the conversion from the server coordinate system to Unity’s left-hand Cartesian coordinate system in multiple places.


Structure

Assets/lib/CellLoc.cslink
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public struct CellLoc {
    public short x;
    public short y;
    public int z;
    public short idx; // index of this space in the cell
    public short dim; // number of subcells on a row, and also number of rows

    public CellLoc(short x, short y, int z) {
        this.x = x; this.y = y; this.z = z;
        this.idx = this.dim = 1;
    }

    public CellLoc(int x, int y, int z) {
        this.x = (short) x; this.y = (short) y; this.z = z;
        this.idx = this.dim = 1;
    }
}

public class CLUtils {
    public static Vector3 CellLocToVector3(CellLoc c) {
        if (c.dim == 1) { // the simple case
            return new Vector3((1f) * c.x,
                               (-1f) * c.y,
                               (-0.1f) * c.z);
        } else {
            return Vector3.zero;
        }
    }
}

Not handling the multiple-entities-in-a-cell case yet, but this structure is sufficient for the map:

Assets/Managers/MapManager.cslink
27
28
29
30
31
32
33
34
35
36
private Dictionary<CellLoc, Transform> cell_transforms;

public float nextDBUpdate;
public float dbUpdateDelta = 5f;

private List<string> cellKeyList;
private Dictionary<CellLoc, CellLite> cells;
private List<CellLoc> cellsKeys;

private Dictionary<CellLoc,Transform> portalTransforms;
Assets/Managers/MapManager.cslink
85
86
87
88
89
90
91
if (cellNeedsTransform[c]) {
    // Instantiate this one
    Vector3 position = CLUtils.CellLocToVector3(new CellLoc(cells[c].x, cells[c].y, cells[c].z));
        
    Transform tempts = Instantiate(prefab, 
                                   position,
                                   Quaternion.identity) as Transform;

We store and index on CellLocs, and only convert to Vector3 when we need to. We still need to push CellLoc into the CellLite class, as you can see above.

We’ve also switched conversions, from negating x and y to negating y and z. It seems more natural this way, but it does make our textures upside down and backwards, ergo:

Assets/Managers/MapManager.cslink
152
rend.material.mainTextureScale = new Vector2((-1f) * tempts.localScale.x, (-1f) * tempts.localScale.y);

Let’s take a look:


Bonus: Life on a Sine Wave

Temporarily did this:

Assets/lib/CellLoc.cslink
27
28
29
30
31
public static Vector3 CellLocToVector3(CellLoc c) {
    Vector3 v;
    v.x = (-1f) * c.x;
    v.y = (-1f) * c.y;
    v.z = 0.1f * c.z + (float) (Math.Sin(c.x / 10f) * 5f);

And bypassed the map cell chunking logic, to get this:


BTW, tried some stuff with Octopress 3 and decided not to make that move yet. I’ve also seen a lot of lockups in Unity while using Visual Studio for debugging. Oh well.


Day 21 code - visualizer