# Prevent a number from getting subtracted bellow 0?

This topic is 411 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

## Recommended Posts

I'm trying to create a simple difficulty system for a game I'm making, the main point of the game is to click on objects which are falling, before they fall out of the cameras viewing rect.

The difficulty system simply makes the objects smaller by scaling them as time passes.

This is how I'm currently doing it :

        Vector2 newScale = new Vector2();
newScale.x = 1 - (float)timeSinceStart * 0.3f;
newScale.y = 1 - (float)timeSinceStart * 0.3f;
instantiatedObject.transform.localScale = (Vector3)newScale;


timeSinceStart is the amount of time (in seconds) since the current match was started.

But this results in after a few seconds or so, the objects start getting bigger because the scaling value has gone negative.

What I want the objects to do is to just continue scaling them down infinitely, getting smaller and smaller.

But I can't seem to figure out a way to do this.

#### Share this post

##### Share on other sites

Either clamp to 0 as follows:

if (newScale.x < 0) newScale.x = 0; // and do the same for y

Or divide by time passed, which will give a non-linear scaling (but which may be more visually pleasing):

newScale.x = 1.0f / ((float) timeSinceStart * 0.3f));

The 2nd one fixed the problem, however the objects spawn in too big and get small too fast :/

Played around with the numbers some but I can't seem to get the right balance.

#### Share this post

##### Share on other sites

You can do a mix of clamping and mhagain's suggestion as well.

float NewScale = 1.0f / ((float) timeSinceStart * 0.3f);
if (NewScale > 1.0f) //Clamp max scale, don't scale higher than original scale.
NewScale = 1.0f;

Adjusting the 0.3f value will adjust how quickly it scales down.

#### Share this post

##### Share on other sites

You can do a mix of clamping and mhagain's suggestion as well.

float NewScale = 1.0f / ((float) timeSinceStart * 0.3f);
if (NewScale > 1.0f) //Clamp max scale, don't scale higher than original scale.
NewScale = 1.0f;

Adjusting the 0.3f value will adjust how quickly it scales down.

Is i lower the 0.3f value the objects become bigger when they spawn, and if I make it higher they become good size in the beginning but they scale down way too fast.

#### Share this post

##### Share on other sites

Is i lower the 0.3f value the objects become bigger when they spawn,

If you've clamped scale (like I did in my post), it should not scale up beyond the original scale (assuming original scale is 1).

#### Share this post

##### Share on other sites

Try squaring it or raising it to some other power; alternatively take a square root (or raise to another fractional power).  Between your 0.3 factor and this you should be able to tweak it to a result that meets your requirement.

#### Share this post

##### Share on other sites

Is i lower the 0.3f value the objects become bigger when they spawn,

If you've clamped scale (like I did in my post), it should not scale up beyond the original scale (assuming original scale is 1).

I don't want it to stay the same scale though.

I want it to get smaller as time passes, but I don't want it to get too small too fast, and I don't want it to be too big in the beginning of the game.

Or Lerp, with a min and a max scale chosen by the designer.

Lerp might work, however I can't get that to work either >.>

This is how my Lerp looks :

        newScale.x = Mathf.Lerp(minScale, maxScale, 5);
newScale.y = Mathf.Lerp(minScale, maxScale, 5);

minScale is 0.5 and maxScale is set to 50.

But the object stays at the same scale at all times.
Edited by BiiXteR

#### Share this post

##### Share on other sites

I don't want it to stay the same scale though. I want it to get smaller as time passes, but I don't want it to get too small too fast, and I don't want it to be too big in the beginning of the game.

Did you try the code I posted? The code I posted would:

A) Not allow the object to scale larger than 1.0f. If this is too large, set it to a smaller number.

B) Scale down over time. If it scales too quickly or too slowly, change the 0.3f value.

#### Share this post

##### Share on other sites

Or Lerp, with a min and a max scale chosen by the designer.

Lerp might work, however I can't get that to work either >.>

This is how my Lerp looks :

        newScale.x = Mathf.Lerp(minScale, maxScale, 5);
newScale.y = Mathf.Lerp(minScale, maxScale, 5);

minScale is 0.5 and maxScale is set to 50.

But the object stays at the same scale at all times.

You want to pass a changing t value to Lerp.  Your passing in a constant value, so you're getting a constant back.  Something like Mathf.Lerp(max,min, Mathf.Clamp( timeNow / timeToMinSize), 0, 1).   Note that I flipped your min/max, as I believe you wanted everything to get smaller.  Depending on what Mathf.Lerp is, it might already make that clamp.  (Unity's Mathf.Lerp is clamped)

EDIT: Oh silly me, it is Unity.  So just Mathf.Lerp(max, min, timeSinceStart  / HowLongYouWantToTakeToGetToMinSize);  And if you want to get fancy with how the size shrinks, I suggest using an AnimationCurve.

Edited by ferrous

#### Share this post

##### Share on other sites

Or Lerp, with a min and a max scale chosen by the designer.

Lerp might work, however I can't get that to work either >.>

This is how my Lerp looks :

        newScale.x = Mathf.Lerp(minScale, maxScale, 5);
newScale.y = Mathf.Lerp(minScale, maxScale, 5);

minScale is 0.5 and maxScale is set to 50.

But the object stays at the same scale at all times.

You want to pass a changing t value to Lerp.  Your passing in a constant value, so you're getting a constant back.  Something like Mathf.Lerp(max,min, Mathf.Clamp( timeNow / timeToMinSize), 0, 1).   Note that I flipped your min/max, as I believe you wanted everything to get smaller.  Depending on what Mathf.Lerp is, it might already make that clamp.  (Unity's Mathf.Lerp is clamped)

EDIT: Oh silly me, it is Unity.  So just Mathf.Lerp(max, min, timeSinceStart  / HowLongYouWantToTakeToGetToMinSize);  And if you want to get fancy with how the size shrinks, I suggest using an AnimationCurve.

That worked, perfect result, too.

I'll go ahead and look into AnimationCurves too, even if I probably won't use it in this project.

Thanks a lot.

I don't want it to stay the same scale though. I want it to get smaller as time passes, but I don't want it to get too small too fast, and I don't want it to be too big in the beginning of the game.

Did you try the code I posted? The code I posted would:

A) Not allow the object to scale larger than 1.0f. If this is too large, set it to a smaller number.

B) Scale down over time. If it scales too quickly or too slowly, change the 0.3f value.

I did paste your code into my project, but the scale was just constantly at 0.

I tried increasing 0.3f and decreasing, still stuck at 0. :/

Edited by BiiXteR

#### Share this post

##### Share on other sites

And even if you end up not using animationCurves, you can play with your Lerp by doing many of the things mentioned in previous posts.  You can square or squareroot the third parameter to get a less linear behavior.

float t = timeSinceStart  / HowLongYouWantToTakeToGetToMinSize;

Mathf.Lerp(max, min, t*t);

OR

Mathf.Lerp(max, min, Mathf.sqrt(t));

OR

Mathf.Lerp(max, min, t*t*t*t);

I like https://www.desmos.com/calculator for looking at how the curve changes.

#### Share this post

##### Share on other sites

This topic is 411 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account

## Sign in

Already have an account? Sign in here.

Sign In Now