Search Unity

How to make random scale on XY axis preserve ratio?

Discussion in 'Getting Started' started by Neikke, Aug 21, 2017.

  1. Neikke

    Neikke

    Joined:
    Jun 23, 2017
    Posts:
    72
    Hi, please help..

    I have a spawner script which generates objects (let's say tall pillars) and is able to generate them in random scale provided Min and Max scale values, and here's a few lines of code controlling if I want to preserve Ratio of this random scaling or not. The problem is if I turn on Preserve Ratio ON it produces Tall and Short pillars, scaling them uniformly along all axis. But I want them to stay same height on Z axis and differ only in thickness (XY axis). So when I turn Preserve Ratio Off, it produces pillars squashed in XY which is due to the fact that X gets some random value let's say 8 while Y gets 16. What I;m struggling with - how do I make those XY axis to produce same (uniform) values?

    Code (CSharp):
    1.  
    2. Vector3 newScale;
    3.             if (!PreserveRatio)
    4.             {
    5.                 newScale = new Vector3 (UnityEngine.Random.Range (MinimumSize.x, MaximumSize.x), UnityEngine.Random.Range (MinimumSize.y, MaximumSize.y), UnityEngine.Random.Range (MinimumSize.z, MaximumSize.z));
    6.             }
    7.             else
    8.             {
    9.                 newScale = Vector3.one * UnityEngine.Random.Range (MinimumSize.x, MaximumSize.x);
    10.             }
    11.             nextGameObject.transform.localScale = newScale;        
     
  2. FMark92

    FMark92

    Joined:
    May 18, 2017
    Posts:
    1,243
    This is alredy incorrect.
    Z is not height, it's depth.
    Y is not depth, but height
    And x is width.

    Across all of them? use a global variable.
     
  3. Neikke

    Neikke

    Joined:
    Jun 23, 2017
    Posts:
    72
    I know, but.. probably the model was rotated/oriented and exported this way..

    Nope, across XY only, but I want random value of X to be same for random value of Y. So I don't get horizontally squashed pillars. Any way of doing it?
     
  4. FMark92

    FMark92

    Joined:
    May 18, 2017
    Posts:
    1,243
    You mean something like this?
    Code (CSharp):
    1. float someReusableRandon = UnityEngine.Random.Range (MinimumSize.xy, MaximumSize.xy);
    2. newScale = new Vector3 (someReusableRandon, someReusableRandon, UnityEngine.Random.Range (MinimumSize.z, MaximumSize.z));
     
    Kiwasi and Neikke like this.
  5. Neikke

    Neikke

    Joined:
    Jun 23, 2017
    Posts:
    72
    Sorry I forgot to mention that I'm a noob in coding :) Could you please show exactly how these code strings would look with my example?
     
  6. FMark92

    FMark92

    Joined:
    May 18, 2017
    Posts:
    1,243
    Ooh. Well slight problem is that I don't know your whole spawning code.
    first example: you want X and Y to receive the same random value with different Z. This will make each pillar have different X and Y scale values, but X and Y of each pillar will be the same values.
    Code (CSharp):
    1.  
    2. Vector3 newScale;
    3. if (!PreserveRatio)
    4. {
    5.    //creating a random that we will use for X and Y
    6.    float someReusableRandom = UnityEngine.Random.Range ((MinimumSize.x+MaximumSize.y)/2, (MinimumSize.x+MaximumSize.y)/2);
    7.    //assing new scale with same X and Y arguments and random Z
    8.    newScale = new Vector3 (someReusableRandom, someReusableRandom, UnityEngine.Random.Range (MinimumSize.z, MaximumSize.z));
    9. }
    10. else
    11. {
    12.    newScale = Vector3.one * UnityEngine.Random.Range (MinimumSize.x, MaximumSize.x);
    13. }
    14. nextGameObject.transform.localScale = newScale;
    15.  
    If you want ALL pillars that you spawn to have the same random X and Y values, you'll need to define that float globally and assign it on Start().

    Code (CSharp):
    1. //creating a random that we will use for X and Y
    2. float someReusableRandom;
    3.  
    4. void Start(){
    5.     ...
    6.     //assigning the random value that will be the same for the lifetime of this monobehaviour
    7.     float someReusableRandom = UnityEngine.Random.Range ((MinimumSize.x+MaximumSize.y)/2, (MinimumSize.x+MaximumSize.y)/2);
    8.     ...
    9. }
    10.  
    11. void nextPillar(...){
    12.     ...
    13.     Vector3 newScale;
    14.     if (!PreserveRatio)
    15.     {
    16.         //assing new scale with same global X and Y arguments and random Z
    17.         newScale = new Vector3 (someReusableRandom, someReusableRandom, UnityEngine.Random.Range (MinimumSize.z, MaximumSize.z));
    18.     }
    19.     else
    20.     {
    21.         newScale = Vector3.one * UnityEngine.Random.Range (MinimumSize.x, MaximumSize.x);
    22.     }
    23.     nextGameObject.transform.localScale = newScale;
    24.     ...
    25. }
     
  7. Neikke

    Neikke

    Joined:
    Jun 23, 2017
    Posts:
    72
    Thanks a lot FMark92, but unfortunately it didn't work for some reason, though reading your code it should have been working precisely the way I wanted.. That's what I did:

    Code (CSharp):
    1.    
    2. /// if set to true, the random size will preserve the original's aspect ratio on all three axis
    3.         public bool PreserveRatio=false;
    4. /// if set to true, some random number will be generated along X and Y only and preserving their aspect ratio. Z will be random
    5.         public bool PreserveRatioXY=false;
    6.  
    7.  
    8.  
    9.  
    10. /// we rescale the object according to first uniform scaling method
    11. Vector3 newScale;
    12. if (!PreserveRatio)
    13. {
    14. newScale = new Vector3 (UnityEngine.Random.Range (MinimumSize.x, MaximumSize.x), UnityEngine.Random.Range (MinimumSize.y, MaximumSize.y), UnityEngine.Random.Range (MinimumSize.z, MaximumSize.z));
    15. }
    16. else
    17. {
    18. newScale = Vector3.one * UnityEngine.Random.Range (MinimumSize.x, MaximumSize.x);
    19. }
    20. nextGameObject.transform.localScale = newScale;    
    21.  
    22.  
    23.  
    24.  
    25. /// we rescale the object according to second non-uniform scaling method
    26.  
    27. Vector3 newScaleXY;
    28. if (!PreserveRatioXY)
    29. {
    30.     //creating a random that we will use for X and Y
    31.     float someReusableRandom = UnityEngine.Random.Range ((MinimumSize.x+MaximumSize.y)/2, (MinimumSize.x+MaximumSize.y)/2);
    32.     //assing new scale with same X and Y arguments and random Z
    33.     newScaleXY = new Vector3 (someReusableRandom, someReusableRandom, UnityEngine.Random.Range (MinimumSize.z, MaximumSize.z));
    34. }
    35. else
    36. {
    37.     newScale = Vector3.one * UnityEngine.Random.Range (MinimumSize.x, MaximumSize.x);
    38. }
    39. nextGameObject.transform.localScale = newScaleXY;
    40.  
    41.  
    42.  
    Any ideas where I took the wrong path?
     
    Last edited: Aug 22, 2017
  8. FMark92

    FMark92

    Joined:
    May 18, 2017
    Posts:
    1,243
    I seem to have made a mistake here:
    Code (CSharp):
    1. float someReusableRandom = UnityEngine.Random.Range ((MinimumSize.x+MaximumSize.y)/2, (MinimumSize.x+MaximumSize.y)/2);
    should be
    Code (CSharp):
    1. float someReusableRandom = UnityEngine.Random.Range ((MinimumSize.x+MinimumSize.y)/2, (MaximumSize.x+MaximumSize.y)/2);
    Other than that I don't see what could be wrong.
     
  9. Neikke

    Neikke

    Joined:
    Jun 23, 2017
    Posts:
    72
    Thanks! I'll give it a try now
     
  10. Neikke

    Neikke

    Joined:
    Jun 23, 2017
    Posts:
    72
    Nope.. not working ((
    No problem, I will just skip this issue and continue building other things for now. Thanks a lot anyway !