How to determine scale to increase sprite width to screen width

I have been able to use Transform.localScale to increase the width of a sprite. How can I determine the scale to increase the width (of a sprite on both sides ) till it fills the screen width?

Firstly, can you use a Canvas object to fill the screen? Does this need to be a world-space sprite?

If it really does, with little bit of math you can figure that out.

A scale is a multiplier for the dimensions of the gameObject. So a 100px wide sprite with a scale of 2 would be 200px pixels wide.

So the calculation is (SpriteWidth * Scale = ScreenWidth). We already know what the SpriteWidth and the ScreenWidth are, so we need to know what Scale is.

So math tells us we need to divide both sides of the equals sign by SpriteWidth in order to solve for Scale.

so “Scale = ScreenWidth / SpriteWidth”.

The tricky part is that all these numbers need to end up in world-space units instead of pixels.

So here’s a script that gets the screen width in world space, and divides it by the sprite width in world space.

// get the sprite width in world space units
float worldSpriteWidth = GetComponent<SpriteRenderer>().sprite.bounds.size.x;

// get the screen height & width in world space units
float worldScreenHeight = Camera.main.orthographicSize * 2.0f;
float worldScreenWidth = (worldScreenHeight / Screen.height) * Screen.width;

// initialize new scale to the current scale
Vector3 newScale = transform.localScale;

// divide screen width by sprite width, set to X axis scale
newScale.x = worldScreenWidth / worldSpriteWidth;

// apply scale change
transform.localScale = newScale;
4 Likes

Thanks, now I get it. I am using the following code to increase the sprite width over a period of time in conjunction with what you explained above (scaling to screenwidth), but when I scale the sprite it extends off the screen. How can I make the sprite width scale to the screen width so it appears fully on the screen regardless of the position before scaling?

bool isScaling = false;

IEnumerator scaleToX(SpriteRenderer spriteToScale, float newXValue, float byTime)
{
    if (isScaling)
    {
        yield break;
    }
    isScaling = true;

    float counter = 0;
    float currentX = spriteToScale.transform.localScale.x;
    float yAxis = spriteToScale.transform.localScale.y;
    float ZAxis = spriteToScale.transform.localScale.z;

    Debug.Log(currentX);
    while (counter < byTime)
    {
        counter += Time.deltaTime;
        Vector3 tempVector = new Vector3(currentX, yAxis, ZAxis);
        tempVector.x = Mathf.Lerp(currentX, newXValue, counter / byTime);
        spriteToScale.transform.localScale = tempVector;
        yield return null;
    }

    isScaling = false;
}

Do you mean that the sprite becomes too wide to fit on screen, or that your sprite is at an offset position so it extends off screen just on one side once it scales up?

The latter, my sprite is at an offset position so it extends off screen just on one side once it scales up

Alright, then I believe you’ll have to subtract that offset from the “worldScreenWidth” variable in my example. The offset being the difference between the sprite’s position and the camera’s position in 2D. If it’s horizontal only then it’s the difference of the X positions.

However, if you want the sprite to scale to both sides of the screen, while still maintaining the positional offset, that’s not quite possible unless you change the sprite’s pivot so that it scales non-uniformly. There are probably better ways to do that depending on the end result you’re looking for.

Actually for my case I need to scale it on both sides. I started exploring changing the pivot but
“GetComponent ().sprite.pivot” is only a getter not a setter. I am not sure how to set this property. Also I am open to other approaches to achieve the same result if you have any suggestions.

One way would be to make the sprite a child of a parent object which represents the pivot, scaling the parent would scale the child relative to the parent as if it were the pivot. The challenging part is positioning the child inside the parent such that it scales in the proper proportion to fill the screen. I imagine you may need the child sprite’s local offset to be the opposite of the world offset from the camera. Unfortunately I’ve never tried to do anything like that with any degree of accuracy so I can’t help much more than that, but that’s the idea.

May I ask what the effect you’re going for is, and why you need this sprite to stretch to fill the screen at an offset position?

I need to make a game objects that can extend to fill the screen width, this plays a significant role in my design.

Just to clarify, your design calls for the object to maintain an offset position, and scale more on one side in order to fill the screen?

Not necessarily to maintain an offset position but to just to scale on both sides to fill the screen from any given position.

If the offset position isn’t necessary, then you may want to both scale to the screen width, as well as translate the sprite’s position to the camera’s 2D position at the same time. So your sprite will end up scaled to screen width, as well as centered on screen, so it shouldn’t extend past the camera bounds.

1 Like

Sorry for not replying earlier. Thanks, it’s working. I tried to scale the sprite down to it’s original size after expansion using the scale code you provided above. The only change I made was

newScale.x = worldSpriteWidth/worldScreenWidth;

now dividing sprite width by the screen width, but it didn’t reduce the scale back the the original. It remained unchanged. Why is this the case?

The original scale will be lost once you apply the new scale. If the original scale is not just (1,1,1), then you should save the original scale beforehand, and then reapply it later, there’s no need to calculate the original scale.

1 Like

I just realised that when the sprite position is not in the center (Camera’s 2D position) it still scales off screen.

Yes, the sprite is scaling to the screen’s width, even when it’s not centered on screen. I’m not sure what kind of behavior you envision, but you may want to start a new thread with further questions based on your progress and see if someone else maybe has some more suggestions.

Okay, a new more specific thread might help. I was expecting the sprite to scale just enough on each side to fill the screen width without exceeding it (the screen bounds), meaning that if the sprite isn’t at the center it would have to scale more on one side than the other, but it seems to be scaling equally on both sides, that’s why it’s going off the screen when it’s not in the center.