0
\$\begingroup\$

I'm a hobbyist at programming so I'm sure I'm missing something very simple:

Basically I have a script that has a method for repositioning a 3x3 grid of tiles every time the player goes out of the center tile. They are ordered in a List 0-8 left to right, top to bottom. The strange thing is it works perfectly for tile indexes 0,1,2,3 and 5, but the bottom row doesn't re-orient the tiles correctly even though it's using the same method that works for all the other tiles.

No errors thrown in the log.

Here is the method I created and the switch statement that calls the method. TilesArr is instantiated in the Start() function and is declared in the script class itself.

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

public class ParallaxBG : MonoBehaviour {
public GameObject tile;
public GameObject containter;
public GameObject player;
public int SlowDownFactor = 300;
public float tileWidth = 5f;

private List<GameObject> TilesArr = new List<GameObject>{ };

//this is a method for shifting the tiles in any direction.
public List<GameObject> arrangeTiles(List<GameObject> arrayToModify, int startingTile, bool columnMod, int iterationQty, int xMod, int yMod, int newArrayStartingIndex){
    List<GameObject> arrayClone = new List<GameObject>(arrayToModify);
    if (columnMod) {
        for (int i = startingTile; i < startingTile+(iterationQty*3); i+=3) {
            arrayClone[i].transform.position = arrayClone[i].transform.position + new Vector3 (xMod*tileWidth,yMod*tileWidth,0);
            GameObject thisTile = arrayClone [i];
            //int rotation = Random.Range (0, 3);
            //thisTile.transform.Rotate(0,0,90*rotation);
            arrayClone.RemoveAt (i);
            arrayClone.Insert ((i - startingTile) + newArrayStartingIndex,thisTile);
        }
        return arrayClone;
    } else {
        for (int i = startingTile; i < (startingTile + iterationQty); i++) {
            arrayClone [i].transform.position = arrayClone [i].transform.position + new Vector3 (xMod * tileWidth, yMod * tileWidth, 0);
            GameObject thisTile = arrayClone [i];
            //int rotation = Random.Range (0, 3);
            //thisTile.transform.Rotate(0,0,90*rotation);
            arrayClone.RemoveAt (i);
            arrayClone.Insert ((i - startingTile) + newArrayStartingIndex, thisTile);

        }
        return arrayClone;
    }
}


// Use this for initialization
void Start () {
    float pX = player.transform.position.x;
    float pY = player.transform.position.y;
    for (int i = 0; i < 9; i++) {
        GameObject Tile = Instantiate (tile);
        Tile.name = "t" + i;
        Tile.transform.SetParent (containter.transform,false);
        Tile.transform.localScale = new Vector2(tileWidth,tileWidth);
        int rotation = Random.Range (0, 3);
        Tile.transform.Rotate (0, 0, rotation * 90);

        if (i <= 2) {
            Tile.transform.position = new Vector2 ((pX - 1 + i)*tileWidth, pY + tileWidth);

        } else if (i >= 3 && i <= 5) {
            Tile.transform.position = new Vector2 ((pX - 4 + i)*tileWidth, pY);

        } else {
            Tile.transform.position = new Vector2 ((pX - 7 + i)*tileWidth, pY - tileWidth);

        }
        TilesArr.Add (Tile);


    }
}

// Update is called once per frame
private int counter = 0;
void Update () {
    if (counter == 0) {
        Vector2 playerVelocity = player.GetComponent<Rigidbody2D> ().velocity/SlowDownFactor;
        Vector2 pTrans = (Vector2)player.transform.position;


        //we just grab player velocity and slowed it down. 
        //tile index starts at 0 on each Update() call
        int tileIndex = 0;
        foreach (var Tile in TilesArr) {

            //loop starts with complete=false 
            bool complete = false;


            Tile.transform.position = new Vector2 (Tile.transform.position.x - playerVelocity.x, Tile.transform.position.y - playerVelocity.y);
            Vector2 tTrans = Tile.transform.position;

            if (tileIndex != 4 && (Mathf.Abs (pTrans.x - tTrans.x) < (tileWidth / 2)) && (Mathf.Abs(pTrans.y - tTrans.y) < (tileWidth / 2))) {
                List<GameObject> moveOne;

                switch (tileIndex) {
                case 0:
                    moveOne = arrangeTiles (TilesArr, 6, false, 3, -1, 3, 0);
                    TilesArr = new List<GameObject>(arrangeTiles (moveOne, 5, true, 2, -3, 0, 3));
                    for (int i = 0; i < 9; i++) {
                        TilesArr[i].transform.position = new Vector2 (TilesArr[i].transform.position.x,TilesArr[i].transform.position.y);

                    }
                    complete = true;
                    break;
                case 1:
                    TilesArr = new List<GameObject>(arrangeTiles (TilesArr, 6, false, 3, 0, 3, 0));
                    for (int i = 0; i < 9; i++) {
                        TilesArr[i].transform.position = new Vector2 (TilesArr[i].transform.position.x,TilesArr[i].transform.position.y);
                    }
                    complete = true;
                    break;
                case 2:
                    moveOne = arrangeTiles (TilesArr, 6, false, 3, 1, 3, 0);
                    TilesArr = new List<GameObject>(arrangeTiles (moveOne, 3, true, 2, 3, 0, 5));
                    for (int i = 0; i < 9; i++) {
                        TilesArr[i].transform.position = new Vector2 (TilesArr[i].transform.position.x,TilesArr[i].transform.position.y);

                    }
                    complete = true;
                    break;
                case 3:
                    TilesArr = new List<GameObject>(arrangeTiles (TilesArr, 2, true, 3, -3, 0, 0));
                    for (int i = 0; i < 9; i++) {
                        TilesArr[i].transform.position = new Vector2 (TilesArr[i].transform.position.x,TilesArr[i].transform.position.y);
                    }
                    complete = true;
                    break;
                //there is no case 4 because that is center tile.
                case 5:
                    TilesArr = new List<GameObject>(arrangeTiles (TilesArr, 0, true, 3, 3, 0, 2));
                    for (int i = 0; i < 9; i++) {
                        TilesArr[i].transform.position = new Vector2 (TilesArr[i].transform.position.x,TilesArr[i].transform.position.y);
                    }
                    complete = true;
                    break;
                    //WHY IS THE BOTTOM ROW NOT WORKING??
                case 6:
                    moveOne = arrangeTiles (TilesArr, 0, false, 3, -1, -3, 6);
                    TilesArr = new List<GameObject>(arrangeTiles (moveOne, 2, true, 2, -3, 0, 0));
                    for (int i = 0; i < 9; i++) {
                        TilesArr[i].transform.position = new Vector2 (TilesArr[i].transform.position.x,TilesArr[i].transform.position.y);

                    }
                    complete = true;
                    break;
                case 7:
                    TilesArr = new List<GameObject>(arrangeTiles (TilesArr, 3, false, 3, 0, -3, 6));

                    for (int i = 0; i < 9; i++) {
                        Debug.Log (TilesArr [i].name);
                        TilesArr[i].transform.position = new Vector2 (TilesArr[i].transform.position.x,TilesArr[i].transform.position.y);
                    }
                    complete = true;
                    break;
                case 8:
                    moveOne = arrangeTiles (TilesArr, 0, false, 3, 1, -3, 6);
                    TilesArr = new List<GameObject>(arrangeTiles (moveOne, 0, true, 2, 3, 0, 2));
                    for (int i = 0; i < 9; i++) {
                        TilesArr[i].transform.position = new Vector2 (TilesArr[i].transform.position.x,TilesArr[i].transform.position.y);

                    }
                    complete = true;
                    break;
                default:
                    Debug.Log ("were in the middle");
                    break;


                }   


            }
            tileIndex += 1;
            if(complete){
                break;

            }
        }
        //counter = 0;
    }
    //counter = 1;

}

}

\$\endgroup\$
5
  • \$\begingroup\$ Wow no offense but I am getting a headache trying to read the code. What about you try to explain more precisely what your code is doing, you don't know, you might even be able to understand where your mistake is by doing so :) \$\endgroup\$ – realUser404 Jan 11 '17 at 17:05
  • \$\begingroup\$ Hey! None taken, I know it's kind of ugly... Sorry about that. What the code does is on startup, it takes a List<GameObject> TileArr of 9 identical instantiated tiles arranged in a 3x3 grid with the player starting on tile 4 (the middle tile of the 9 tiles, indexed from 0). Then, on each Update(), the foreach(Tile in TileArr) moves each tile opposite to the direction the player is moving in. The if() statement checks whether the player is no longer in the middle tile and if he's hit the edge of one of the outer tiles. \$\endgroup\$ – Dbilyk Jan 12 '17 at 3:51
  • \$\begingroup\$ If the player has entered the area of one of the outer tiles, the tileIndex counter indicates which index the condition was true for, which then evaluates the corresponding switch statement. The switch case creates a new list out of the existing TilesArr List which moves the tile transforms and their positions in the returned TilesArr copy such that the tile which triggered the switch statement is now the new center tile, index 4. the for() loop following this method call by redrawing the new TilesArr, and the process repeats. \$\endgroup\$ – Dbilyk Jan 12 '17 at 3:56
  • \$\begingroup\$ The method is designed to take an existing list to modify, the starting index from which the tiles need to be shuffled, whether we are moving a row or a column, how many elements in the row or column need to be moved from out starting position, the x and y modifications to the transform that reflect the shuffling visually and, of course, the index to which this set of elements in the array is to be moved. \$\endgroup\$ – Dbilyk Jan 12 '17 at 4:00
  • \$\begingroup\$ I updated post to reflect the complete script, maybe that will help :D \$\endgroup\$ – Dbilyk Jan 12 '17 at 4:07
1
\$\begingroup\$

I've found the solution, it had to do with way my List.RemoveAt() command was affecting the order of the array when the starting index was less than the index i wanted to move the items to.

The revised method below works:

public List<GameObject> arrangeTiles(List<GameObject> arrayToModify, int startingTile, bool columnMod, int iterationQty, int xMod, int yMod, int newArrayStartingIndex){
        List<GameObject> arrayClone = new List<GameObject>(arrayToModify);
        //COLUMN
        if (columnMod) {
            for (int i = startingTile; i < startingTile+(iterationQty*3); i+=3) {
                //modifying columns does not need an IF statement with respect to the starting index and the insert index because I can only move the column 2 spaces away max, 
                //but the script iterates by 3 units so the each next iteration retains the correct element in the 2nd and 3rd position upon completion of the loop.  VERY CONFUSING BUT IT WORKS!

                arrayClone [i].transform.position = arrayClone [i].transform.position + new Vector3 (xMod * tileWidth, yMod * tileWidth, 0);
                GameObject thisTile = arrayClone [i];
                arrayClone.RemoveAt (i);
                arrayClone.Insert ((i - startingTile) + newArrayStartingIndex, thisTile);
            }
            return arrayClone;
        //ROW
        } else {
            for (int i = startingTile; i < (startingTile + iterationQty); i++) {
                if (startingTile > newArrayStartingIndex) {
                    arrayClone [i].transform.position = arrayClone [i].transform.position + new Vector3 (xMod * tileWidth, yMod * tileWidth, 0);
                    GameObject thisTile = arrayClone [i];
                    arrayClone.RemoveAt (i);
                    arrayClone.Insert ((i - startingTile) + newArrayStartingIndex, thisTile);
                } else {
                    arrayClone [startingTile].transform.position = arrayClone [startingTile].transform.position + new Vector3 (xMod * tileWidth, yMod * tileWidth, 0);
                    GameObject thisTile = arrayClone [startingTile];
                    arrayClone.RemoveAt (startingTile);
                    arrayClone.Add (thisTile);
                }

            }
            return arrayClone;
        }
    }
\$\endgroup\$
1
  • \$\begingroup\$ I told you you would find the answer yourself :) \$\endgroup\$ – realUser404 Jan 12 '17 at 9:12

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.