Author Topic: Change sprite borders at runtime  (Read 12977 times)

Asse

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 70
    • View Profile
Change sprite borders at runtime
« on: August 01, 2012, 03:19:37 AM »
I want to make a progress bar and I'm using a UISlicedSprite. The problem is that when I scale it down to zero the size still remains as large as the borders are.

So can I change the borders at runtime somehow?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Change sprite borders at runtime
« Reply #1 on: August 01, 2012, 04:21:21 AM »
That's just how sliced sprite works. You can't scale the borders.

Asse

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 70
    • View Profile
Re: Change sprite borders at runtime
« Reply #2 on: August 01, 2012, 04:23:36 AM »
Damn  :-[

Any suggestions? I can't use a simple sprite since the borders are rounded..
« Last Edit: August 01, 2012, 04:34:26 AM by Asse »

akutruff

  • Guest
Re: Change sprite borders at runtime
« Reply #3 on: August 13, 2012, 03:59:46 PM »
We also have this issue, and its caused us quite a few problems.  I tried looking into possibly creating a new sprite or suggesting a patch, but it appears that the slider is rather coupled to filled sprite.  It seems like a new type of UIFilledSprite would be required, and all the helpers would have to be updated to be aware of the new type. Otherwise, filled sprite would have to be extended to optionally add slicing as well.

Either way, we would really like slicing support for our progress bars.  At the present, we have to create a new sprite for every progress bar in the game with a lot of wasted pixels in our atlases.  Right now, we have 5 different bars.

When the foreground is so small that the sliced sprite's borders have to be shrank, the sprite should behave exactly like a filled sprite, and shrink in the direction of "invert fill" setting. (wherever that may be.)
« Last Edit: August 13, 2012, 07:06:17 PM by akutruff »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Change sprite borders at runtime
« Reply #4 on: August 13, 2012, 08:06:49 PM »
The slider isn't tied to a sliced sprite. You can replace it with a regular sprite or a filled sprite if you wish. For rounded borders, I recommend using a filled sprite.

akutruff

  • Guest
Re: Change sprite borders at runtime
« Reply #5 on: August 13, 2012, 08:46:08 PM »
Thanks for replying Aren.  The problem is that to use a filled sprite, or any sprite that isn't as big as the progress bar itself for that matter, is that it's a bigwaste when adding slicing with directional boarder shrinking could save a ton of space in the atlas. Our game has giant progress bars for health on the top of the screen, and progress bars and meters everywhere.  To make things look nice, and we have been using filled sprites, but half of our atlases are just progress bar foregrounds so we can have rounded bars and not get stretching artifacts.

Even if we used square bars by simply stretching a solid square sprite, the edges will get blurry due to the atlas not being able to be set to point sampling.

Does that make sense?  Apologies if I'm not explaining well.
« Last Edit: August 13, 2012, 09:05:53 PM by akutruff »

Lando

  • Guest
Re: Change sprite borders at runtime
« Reply #6 on: August 14, 2012, 09:19:03 AM »
unless I'm missing something could you not just make the image inactive instead of trying to set the scale to zero? assuming you want to make the image disappear?

JRoch

  • Full Member
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 140
    • View Profile
Re: Change sprite borders at runtime
« Reply #7 on: August 14, 2012, 10:39:25 AM »
The problem with that idea is that the border is like size 3 to 7 or so depending upon how many pixels the radius of the rounded corners is.  This means that, with a sliced sprite, the smallest the sprite can be is the total border size (6 to 14 or so with our estimate numbers.)  This means that, in scaling terms, a full life bar is, say, 300 pixels in size, and a 1% life bar is ~18 pixels in size... meaning the transition from 1% to 0% is inordinately large due to the extra padding of the border.

This can be solved by using the live value indirectly, and scaling it to allow for the padding effects... but there's still a big jump from 1% to 0% visually.  I suppose you could use the UISlider for anything from 100% to about 4% life, and then switch over to custom code that uses pre-made UISprite items (not sliced or scaled) that handle the last little bit and ensures the proper visual presentation you are looking for.

Not exactly the easiest solution, but at least it would have the behavior you need.

akutruff

  • Guest
Re: Change sprite borders at runtime
« Reply #8 on: August 14, 2012, 12:07:30 PM »
JRoch hit the nail on the head.  It's the big jump that really gets us.

Even though I really hope that Aren shows mercy and adds support for this, I've been really trying to do the work without copy pasting UISlicedSprite or UISlider or deriving from them.  If I understand the code correctly, UISlicedSprite has the functionality that prevents itself from being scaled smaller than its border size, not the slider so I don't know of a way to create another widget or code that can hack around this without things getting hairy.  Theres code in NGUITools and NGUIMath that have special cases for sliced sprites, which adds to my reluctance to hacking.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Change sprite borders at runtime
« Reply #9 on: August 14, 2012, 03:34:18 PM »
Yup, UISprite can't get smaller than the size of its borders. How do you see it shrinking past that? Scaling the borders at this point would look odd, as your perfectly round corners would be getting squished. Slice them? Again kind of odd.

akutruff

  • Guest
Re: Change sprite borders at runtime
« Reply #10 on: August 14, 2012, 04:13:10 PM »
Ideally, the visual experience would be exactly like a filled sprite:

I'll explain by bad ascii art.  In this example, I'm making a progress bar 8 pixels long with a 5x5 sliced sprite with a 2 pixel border on the left and right as the foreground. 

Below, the parenthesis are border pixels in the sliced sprite and the dashes come from the center of the of the sliced sprite and are stretched to fill the progress bar.

Full health bar:
((----))

7/8 health bar:
((----)

For 7/8, the right border would have the same logic as if the entire right most border were a filled sprite.  The UV's of the vertices are adjusted as the vertices move left so that the rightmost slices of the boarder are steadily reduced.  The center region of the sprite would stay the same length and have the same number of pixels as the full health bar. The mesh would still be like a 9 slice sprite, but the rightmost quads would only be one pixel now, and be mapped with UVs that cover half of the pixels in the rightmost border of the sprite.

6/8 health bar:
((----

For 6/8 none of the right border should be shown.  The mesh now only has to be 6 quads:  3 for the left border, and 3 for the stretched middle.  The UVs of the 3 quads in the stretched middle would only map the center of my 5x5 sprite.

2/8 health bar:
((

Only 3 quads are required.  The quad's UV's are mapped entirely over the left border of the sprite.

1/8 health bar:
(

The vertices only map over 1 pixel of the left border.

I hope this helps clear things up.

Thanks,
Andy


ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Change sprite borders at runtime
« Reply #11 on: August 15, 2012, 02:10:20 AM »
So you want a sliced sprite to act like a filled sprite, basically?

akutruff

  • Guest
Re: Change sprite borders at runtime
« Reply #12 on: August 15, 2012, 09:11:42 AM »
Yep.  It would make NGUI's progress a thing of perfection.

thelemonpeople

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 3
    • View Profile
Re: Change sprite borders at runtime
« Reply #13 on: November 07, 2012, 07:14:38 AM »
I would agree with Akutruff on the need for a 9SliceFillSprite.

I can change the background sprite in my slider for a 9slice to keep the edges sharp but I am at a loss on how I could do the same with the fill-bar.

In my case the end of the fill-bar is covered with puck (sprite) but the rounded start still stretches in an unsightly fashion.

I could cover the start of the fill-bar up with 9slice duplicate but you'll understand it's not ideal. (^_^)

Thanks for any ideas or support,

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Change sprite borders at runtime
« Reply #14 on: November 07, 2012, 08:50:43 AM »