4
\$\begingroup\$

The following is used to create a masonry effect with varying height rectangles. How can I simplify and make this more elegant in Unity?

private float startX = 0.0f;
private float startY = 0.0f;
private float posX = 0.0f;
private float posY = 0.0f;
private float prevWidth = 0;
private float prevHeight = 0;
private int index = 0;
private int currentCol = 0;


private void AddCard(int index, int col, float width, float height)
{
    GameObject goCard = (GameObject)GameObject.Instantiate(pfCard00);
    PackedSprite psCard = goCard.GetComponentInChildren<PackedSprite>();

    goCard.name = "QuestItemCard" + index.ToString();
    goCard.transform.parent = goCardContainer.transform;
    psCard.height = height;

    if (currentCol != col) 
    {
        posX += width;

        posY = 0;
        prevHeight = 0;
    }

    // placement
    posY += (prevHeight / 2) + (height / 2);
    goCard.transform.localPosition = new Vector3(startX + posX, startY - posY, goCard.transform.position.z);

    if (currentCol != col)
    {
        prevWidth = width;

        currentCol = col;
    }

    prevHeight = height;
}

Usage:

AddCard(0, 0, 100, 100);
AddCard(1, 0, 100, 100);
AddCard(2, 0, 100, 100);
AddCard(3, 0, 100, 200);

AddCard(4, 1, 100, 100);
AddCard(5, 1, 100, 100);
AddCard(6, 1, 100, 100);
AddCard(7, 1, 100, 200);
\$\endgroup\$
  • \$\begingroup\$ A couple of questions before answering: Do you want gaps? It looks like the taller cards at the end (#3 and #7) will lift the next row by 100 units leaving a gap. Is it possible to have varying height cards in one row? And what do you want to do with the indices? you're not using them now. \$\endgroup\$ – theodox Dec 20 '13 at 5:52
  • \$\begingroup\$ A good start would be making index a static field and incrementing it each time you call AddCard. Then you don't have to pass that value in at all (or remember it somewhere) \$\endgroup\$ – Nick Udell Apr 24 '14 at 11:38
5
\$\begingroup\$

Consider splitting the code that increments the column into a separate method that can be called manually. Now you do not have to pass in column or row, and index can be incremented by the AddCard method. This greatly simplifies usage and allows you to make use of a for loop.

private float startX = 0.0f;
private float startY = 0.0f;
private float posX = 0.0f;
private float posY = 0.0f;
private float prevWidth = 0;
private float prevHeight = 0;
private int index = 0;
private int currentCol = 0;


private void IncreaseColumn()
{
    currentCol++;
    posX += width;
    posY = 0;
    prevHeight = 0;
}

private void AddCard(float width, float height)
{
    GameObject goCard = (GameObject)GameObject.Instantiate(pfCard00);
    PackedSprite psCard = goCard.GetComponentInChildren<PackedSprite>();

    goCard.name = "QuestItemCard" + index.ToString();
    goCard.transform.parent = goCardContainer.transform;
    psCard.height = height;

    // placement
    posY += (prevHeight / 2) + (height / 2);
    goCard.transform.localPosition = new Vector3(startX + posX, startY - posY, goCard.transform.position.z);

    prevWidth = width;
    prevHeight = height;

    index++;
}

Usage:

var columns = 2;
var rows = 4;

for(int x= 0; x< columns; x++)
{
    for(int y = 0; y<rows-1; y++)
    {
        AddCard(100, 100);
    }
    AddCard(100, 200);
    IncreaseColumn();
}
\$\endgroup\$

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.