How to make random scale on XY axis preserve ratio?

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?

Vector3 newScale;
            if (!PreserveRatio)
            {
                newScale = new Vector3 (UnityEngine.Random.Range (MinimumSize.x, MaximumSize.x), UnityEngine.Random.Range (MinimumSize.y, MaximumSize.y), UnityEngine.Random.Range (MinimumSize.z, MaximumSize.z));
            }
            else
            {
                newScale = Vector3.one * UnityEngine.Random.Range (MinimumSize.x, MaximumSize.x);
            }
            nextGameObject.transform.localScale = newScale;

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.

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?

You mean something like this?

float someReusableRandon = UnityEngine.Random.Range (MinimumSize.xy, MaximumSize.xy);
newScale = new Vector3 (someReusableRandon, someReusableRandon, UnityEngine.Random.Range (MinimumSize.z, MaximumSize.z));
2 Likes

Sorry I forgot to mention that I’m a noob in coding :slight_smile: Could you please show exactly how these code strings would look with my example?

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.

Vector3 newScale;
if (!PreserveRatio)
{
   //creating a random that we will use for X and Y
   float someReusableRandom = UnityEngine.Random.Range ((MinimumSize.x+MaximumSize.y)/2, (MinimumSize.x+MaximumSize.y)/2);
   //assing new scale with same X and Y arguments and random Z
   newScale = new Vector3 (someReusableRandom, someReusableRandom, UnityEngine.Random.Range (MinimumSize.z, MaximumSize.z));
}
else
{
   newScale = Vector3.one * UnityEngine.Random.Range (MinimumSize.x, MaximumSize.x);
}
nextGameObject.transform.localScale = newScale;

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().

//creating a random that we will use for X and Y
float someReusableRandom;

void Start(){
    ...
    //assigning the random value that will be the same for the lifetime of this monobehaviour
    float someReusableRandom = UnityEngine.Random.Range ((MinimumSize.x+MaximumSize.y)/2, (MinimumSize.x+MaximumSize.y)/2);
    ...
}

void nextPillar(...){
    ...
    Vector3 newScale;
    if (!PreserveRatio)
    {
        //assing new scale with same global X and Y arguments and random Z
        newScale = new Vector3 (someReusableRandom, someReusableRandom, UnityEngine.Random.Range (MinimumSize.z, MaximumSize.z));
    }
    else
    {
        newScale = Vector3.one * UnityEngine.Random.Range (MinimumSize.x, MaximumSize.x);
    }
    nextGameObject.transform.localScale = newScale;
    ...
}

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:

/// if set to true, the random size will preserve the original's aspect ratio on all three axis
        public bool PreserveRatio=false;
/// if set to true, some random number will be generated along X and Y only and preserving their aspect ratio. Z will be random
        public bool PreserveRatioXY=false;




/// we rescale the object according to first uniform scaling method
Vector3 newScale;
if (!PreserveRatio)
{
newScale = new Vector3 (UnityEngine.Random.Range (MinimumSize.x, MaximumSize.x), UnityEngine.Random.Range (MinimumSize.y, MaximumSize.y), UnityEngine.Random.Range (MinimumSize.z, MaximumSize.z));
}
else
{
newScale = Vector3.one * UnityEngine.Random.Range (MinimumSize.x, MaximumSize.x);
}
nextGameObject.transform.localScale = newScale;    




/// we rescale the object according to second non-uniform scaling method

Vector3 newScaleXY;
if (!PreserveRatioXY)
{
    //creating a random that we will use for X and Y
    float someReusableRandom = UnityEngine.Random.Range ((MinimumSize.x+MaximumSize.y)/2, (MinimumSize.x+MaximumSize.y)/2);
    //assing new scale with same X and Y arguments and random Z
    newScaleXY = new Vector3 (someReusableRandom, someReusableRandom, UnityEngine.Random.Range (MinimumSize.z, MaximumSize.z));
}
else
{
    newScale = Vector3.one * UnityEngine.Random.Range (MinimumSize.x, MaximumSize.x);
}
nextGameObject.transform.localScale = newScaleXY;

Any ideas where I took the wrong path?

I seem to have made a mistake here:

float someReusableRandom = UnityEngine.Random.Range ((MinimumSize.x+MaximumSize.y)/2, (MinimumSize.x+MaximumSize.y)/2);

should be

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.

Thanks! I’ll give it a try now

Nope… not working ((
No problem, I will just skip this issue and continue building other things for now. Thanks a lot anyway !