Search Unity

Question Rotating and positioning gameobjects in a zig-zag pattern

Discussion in 'Scripting' started by seona13, May 20, 2023.

  1. seona13

    seona13

    Joined:
    Nov 28, 2019
    Posts:
    24
    I have a long straight street of houses with a road in front of them, created by lining up my house prefabs and then tilting their container slightly so that the road goes at an angle across the screen. Looks lovely. However, I ultimately need the road to have corners, creating a zigzag pattern like this:



    The houses are already broken up into groups in preparation for this. I tried simply alternating the direction that I rotated the different groups, which got me the correct directions but not the correct positioning - the segments going right ascend across the screen while the segments going left descend.



    I suspect this is happening because the origin of all those road segments is still (0,0,0), but I'm not sure how to fix it. Offset mathematics is clearly not my strong suit!

    Anyway, this is the code I'm working with at the moment:

    Code (CSharp):
    1. this.housePrefab = housePrefab;
    2.  
    3. int stretchCount = 0; // A stretch is the span between two turns
    4. int houseCount = 0;
    5. float offsetX = 0;
    6. bool goingRight = true;
    7. Transform parent = new GameObject().transform;
    8.  
    9. while (houseCount < 30)
    10. {
    11.    // Add house to the current stretch
    12.    GameObject house = GameObject.Instantiate(housePrefab, Vector3.right * offsetX, Quaternion.identity, parent);
    13.  
    14.    // Calculate offset for next house
    15.    HouseUnit unit = house.GetComponent<HouseUnit>();
    16.    MeshRenderer renderer = unit.GetHouseBase().GetComponent<MeshRenderer>();
    17.    Vector3 size = renderer.bounds.size;
    18.    offsetX += size.x;
    19.  
    20.    // Decide if we're finished with the current stretch
    21.    stretchCount++;
    22.    if (stretchCount >= 2)
    23.    {
    24.        int dieRoll = Random.Range(0, 100);
    25.        if (dieRoll >= 50)
    26.        {
    27.            // Rotate current stretch
    28.            if (goingRight)
    29.            {
    30.                parent.rotation = Quaternion.Euler(0, -45f, 0);
    31.            }
    32.            else
    33.            {
    34.                parent.rotation = Quaternion.Euler(0, 45f, 0);
    35.            }
    36.            goingRight = !goingRight;
    37.  
    38.            // Start a new stretch
    39.            stretchCount = 0;
    40.        }
    41.    }
    42.  
    43.    // If we're starting a new stretch, create a new parent to hold it
    44.    if (stretchCount == 0)
    45.    {
    46.        parent = new GameObject().transform;
    47.        parent.position = Vector3.zero;
    48.        parent.rotation = Quaternion.identity;
    49.    }
    50.  
    51.    houseCount++;
    52. }
    How do I go about lifting those left turns into their proper place? Ideally they should overlap at the turns so that the road looks properly connected, but if I need to backfill the corners for the sake of keeping the maths simple I'm willing to do that too.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,697
    I suspect you are correct.

    Here's one way that works pretty good: make a MonoBehaviour and put it on each prefab piece.

    That MonoBehaviour would just have fields telling what its "zero" point in space is relative to its local coordinates (or you could make that fixed at (0,0,0) if you like), but more importantly, how far the "placement cursor" should move in the world.

    So a 2x1 piece would move the cursor up more, etc.

    Then your placement code just uses that offset to adjust its ongoing placement cursor.