Author Topic: How do I keep a UISprite from going off-screen?  (Read 2407 times)

Seith

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 37
    • View Profile
    • SeithCG
How do I keep a UISprite from going off-screen?
« on: June 11, 2014, 03:17:35 AM »
Hello,

I have a UISprite which follows an NPC character (an "alerted" icon) and currently if I turn away from the NPC the UISprite goes off screen (because the character is now behind us).

But I would like to actually keep the UISprite on screen, just hugging and sliding along the sides of the screen rather than disappearing altogether. What would be the best way to achieve this behavior?

Thanks,
Seith
SeithCG.com

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: How do I keep a UISprite from going off-screen?
« Reply #1 on: June 11, 2014, 05:43:52 AM »
Math, pretty much. If you have HUDText, have a look at the UIFollowTarget script. There it's able to hide the children of a game object if it's off-screen. In your case you wouldn't do it, and instead you'd simply clamp the X and Y position to be between -halfWidth / -halfHeight and +halfWidth / +halfHeight. Or between zero and screen size, depending on which coordinate system you're using and how.

Seith

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 37
    • View Profile
    • SeithCG
Re: How do I keep a UISprite from going off-screen?
« Reply #2 on: June 11, 2014, 08:23:59 AM »
Thank you ArenMook! So I added this in a LateUpdate() to get the desired behavior:

  1.                         // Clamp the position of the alerted icon so it doesn't disappear if it's behind the camera.
  2.                         float clampX = Mathf.Clamp(iconAlerted.transform.localPosition.x, -Screen.width, Screen.width);
  3.                         float clampY = Mathf.Clamp(iconAlerted.transform.localPosition.y, -Screen.height, Screen.height);
  4.                         iconAlerted.transform.localPosition = new Vector3(clampX, clampY, 0f);
  5.  

It works fine for the most part. The only problem is that when I'm running away from the NPC sometimes the icon comes back towards the middle of the screen as if I were facing the NPC (although he's in my back).

So I would need a method to keep the icon from leaving the screen's edges if the NPC is behind the camera. If you have any suggestions about that then please do let me know... :)
SeithCG.com

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: How do I keep a UISprite from going off-screen?
« Reply #3 on: June 12, 2014, 01:59:30 AM »
Do a dot product check to see if the target lies in front of your camera or behind your camera.

Seith

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 37
    • View Profile
    • SeithCG
Re: How do I keep a UISprite from going off-screen?
« Reply #4 on: June 13, 2014, 02:50:45 AM »
Thanks, that's what I'll do.

However I've encountered what looks like a bug: the method I'm using (the code from my previous post) works fine when the game panel is not maximized. But if I start the game with the "Maximize on Play" option then it doesn't work: the icon's position on screen is NOT clamped to the edges of the screen. And so it disappears if the camera doesn't look at the character.

I don't understand why it doesn't work when the game starts in full-screen mode, but it does if the game window is in a multi-panel layout. Do you have any idea what could cause this issue?
SeithCG.com

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: How do I keep a UISprite from going off-screen?
« Reply #5 on: June 13, 2014, 05:14:59 AM »
Depending on the setting of UIRoot and any anchoring you've used, the local position of a widget may not match screen coordinates.

For example, fixed size UIRoot means the local positions will be using virtual pixels, not actual pixels... so you setting the value using Screen.width and height won't give expected results. You need to actually transform from screen space to world space, then inverse transform to local space.

Again, UIFollowTarget script has the math for all this.