Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

C# Unity Math help, object instantiate positions

Discussion in 'Scripting' started by snoboxstudio, May 4, 2022.

  1. snoboxstudio

    snoboxstudio

    Joined:
    Oct 1, 2016
    Posts:
    3
    Hi all, I was hoping I could get some help on figuring out the maths of my card instantiation function.
    I am able to get the appropriate number of cards to spawn in rows and columns like in the picture above, but I'm having trouble figuring out my math for positioning/spacing.
    In the image below, my partner has drawn what the client wishes the 'card board' to look like; think 'Guess Who' board game; with the perspective being dead on.

    (Since my image didn't work, click here for the image)

    So I've tried to create an instantiation function that starts at the center and subtracts a predesignated float amount for the xGap, then switching over for the second half of the row. Also adding to the scale as they get 'closer to the camera'.
    However, when I add in my math for positioning, I get one less card per row and the positioning seems slightly off... Here's my code! I hope someone can help simplify/fix this lol
    Code (CSharp):
    1.  
    2.     public GameObject blankCard;
    3.     private int shuffleNum;
    4.     public int rowsTotal = 5;
    5.     public int columnsTotal = 8;
    6.     public Vector2 gridStartTopLeft = new Vector2(-0.55f, 1.6f);
    7.     public float gridGapX = 1.1f;
    8.     public float gridGapY = 1.3f;
    9.     public float gridPaddingX = 0.1f;
    10.     public float scaleMod = 0.1f;
    11.  
    12. Start () {
    13. for (int r = 0; r < rowsTotal; r++)
    14.         {
    15.             int c = 0;
    16.             int cTmp = 0;
    17.             int tmpNum = 0;
    18.             bool flip = false;
    19.             while (c < columnsTotal)
    20.             {
    21.                 if (!flip)
    22.                 {
    23.                     shuffleNum = rnd.Next(0, cardIndexes.Count);
    24.                     GameObject newCard = Instantiate(blankCard, new Vector2(gridStartTopLeft.x - ((gridGapX * cTmp) - gridPaddingX *r), gridStartTopLeft.y - (gridGapY * r)), Quaternion.identity);
    25.                     newCard.transform.localScale = new Vector2(1 + (scaleMod * r), 1 + (scaleMod * r));
    26.                     c++;
    27.                     cTmp++;
    28.                     tmpNum--;
    29.                 }
    30.                 else
    31.                 {
    32.                     shuffleNum = rnd.Next(0, cardIndexes.Count);
    33.                     GameObject newCard = Instantiate(blankCard, new Vector2(gridStartTopLeft.x + ((gridGapX * cTmp) + gridPaddingX * r), gridStartTopLeft.y - (gridGapY * r)), Quaternion.identity);
    34.                     newCard.transform.localScale = new Vector2(1 + (scaleMod * r), 1 + (scaleMod * r));
    35.                     c++;
    36.                     cTmp++;
    37.                     tmpNum++;
    38.                 }
    39.  
    40.                 if (tmpNum < -(columnsTotal / 2) +1)
    41.                 {
    42.                     tmpNum = 0;
    43.                     cTmp = 0;
    44.                     flip = true;
    45.                 }
    46.             }
    47.             gridGapX += gridPaddingX;
    48.         }
    49. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,951
    You're always going to have a really hard time reasoning about hairy lines of code like the above.

    If you have more than one or two dots (.) in a single statement, you're just being mean to yourself.

    How to break down hairy lines of code:

    http://plbm.com/?p=248

    Break it up, practice social distancing in your code, one thing per line please.

    "Combining a bunch of stuff into one line always feels satisfying, but it's always a PITA to debug." - StarManta on the Unity3D forums

    You must find a way to get the information you need in order to reason about what the problem is.

    What is often happening in these cases is one of the following:

    - the code you think is executing is not actually executing at all
    - the code is executing far EARLIER or LATER than you think
    - the code is executing far LESS OFTEN than you think
    - the code is executing far MORE OFTEN than you think
    - the code is executing on another GameObject than you think it is
    - you're getting an error or warning and you haven't noticed it in the console window

    To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?
    - are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

    Knowing this information will help you reason about the behavior you are seeing.

    If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

    You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

    You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer or iOS: https://forum.unity.com/threads/how-to-capturing-device-logs-on-ios.529920/ or this answer for Android: https://forum.unity.com/threads/how-to-capturing-device-logs-on-android.528680/

    Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494
     
    snoboxstudio likes this.
  3. snoboxstudio

    snoboxstudio

    Joined:
    Oct 1, 2016
    Posts:
    3
    Thank you so much @Kurt-Dekker this is an incredible list of resources. I did assume that I was creating messy code, and this has now given me the ability to parse it all out. I think my first problem lies in the section of code you quoted too.

    However, with that said, there are no errors in the Log. I think the actual error is in my math logic and values.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,951
    Adding to the above, check out this ultimate Unity hack... and you can do this all the time in Unity.

    - let your code run and place the objects in the wrong spot

    - press pause

    - go into the scene and find the object(s)

    - find what values are on its transform (eg, what its position is)

    - reason about why they are that way.

    Keep in mind if these are RectTransform UnityEngine.UI objects, they are EXTREMELY fiddly to get right. The best way is to let a Layout component of some kind deal with it for you, such as a GridLayoutGroup for cards.

    And also, if they are UnityEngine.UI they MUST be correctly parented into the UI, otherwise they are invisible.

    To do this, always use the function overloads of Instantiate<T>() that take a
    Transform parent
    argument.
     
    snoboxstudio likes this.
  5. snoboxstudio

    snoboxstudio

    Joined:
    Oct 1, 2016
    Posts:
    3
    Le sigh. My switch over was actually overlapping on the first row item placement. Thank you so much. I was being lazy and didn't count my items properly. Just what I could see on the surface! I think I'm close to solving it now!

    Oh! And in regards to the resources you gave me earlier, simplifying my code is helping too. I had a few superfluous brackets in my position calculations which was throwing things off. I've just about solved it now. Thanks again!
     
    Last edited: May 4, 2022
    Kurt-Dekker likes this.