Author Topic: Best way to resize collider?  (Read 14502 times)

electrodruid

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 48
    • View Profile
Best way to resize collider?
« on: March 12, 2013, 07:33:08 AM »
I got a scene with a UIDraggable panel which I'm using to scroll through a series of full-screen elements (I'll call them "pages" here). Each page has a background sprite, scaled with a UIStretch to be as big as the screen, and then the other widgets are anchored to points relative to this background sprite. So far so good, except I'm trying to run this on a range of devices and resolutions, including iOS. The UIStretch manages to change the scale of the background sprite for the page and the anchors reposition everything correctly, but nothing causes the BoxColliders to recalculate. Obviously when going from an arbitrarily-sized window in the Editor to, say, an iPad 3 or 4, the effect can be pretty severe. You have to hunt around the screen for the area which is still covered by the un-resized collider in order to get things to scroll.

So, questions:

What's the generally-accepted way to make a collider recalculate after a UIStretch has resized its child element(s)? I guess you'd call NGUITools.AddWidgetCollider, but where and when do you call it? Is there a way of knowing (some kind of callback?) when a UIStretch has caused an element to resize? Or do I have to create a custom component that just resizes the collider every Update? If so, isn't that crazily inefficient? Why doesn't UIStretch already contain the functionality to optionally rescale colliders in the parent object? It seems like a pretty significant oversight that it doesn't, because it means you can never stretch an item which you want to be touchable and have it work properly.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Best way to resize collider?
« Reply #1 on: March 13, 2013, 01:27:03 AM »
Hmm. I'd say create a copy of UIStretch script and add code to it that will adjust your collider's size.

Malzbier

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 93
    • View Profile
Re: Best way to resize collider?
« Reply #2 on: March 14, 2013, 05:05:39 AM »
Not sure if this is exactly what you are looking for but i have created a script that changes the size of a collier to the set size of an UISlized sprite. (Use for buttons in different sizes)

I hope this helps.

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. [ExecuteInEditMode]
  5. [AddComponentMenu("NGUI/Helper/ColliderUpdater")]
  6. public class UpdateCollider : MonoBehaviour
  7. {
  8.        
  9.         public Transform targetTransform;
  10.         private BoxCollider cachedCollider;
  11.         public Vector2 sizeoffset = new Vector2 (1, 1);
  12.         public float depth;
  13.         /// <summary>
  14.         /// Getting Stuff Cached
  15.         /// </summary>
  16.         void Start ()
  17.         {
  18.                 if (targetTransform == null) {
  19.                         targetTransform = transform.FindChild ("Background");
  20.                 }
  21.                 if (this.GetComponent<BoxCollider> () != null) {
  22.                         cachedCollider = this.GetComponent<BoxCollider> ();
  23.                 }
  24.         }
  25.        
  26.         /// <summary>
  27.         /// Update the possition of the collider according to the sice of the target UISlicedSprite.
  28.         /// </summary>
  29.         void Update ()
  30.         {
  31.                
  32.                
  33.                 if (targetTransform != null) {
  34.                         cachedCollider.size = new Vector3 (sizeoffset.x * targetTransform.localScale.x, sizeoffset.y * targetTransform.localScale.y, targetTransform.localScale.z);
  35.                         cachedCollider.center = targetTransform.localPosition;
  36.                         if (targetTransform.GetComponent<UISlicedSprite> () != null) {
  37.                                 switch (targetTransform.GetComponent<UISlicedSprite> ().pivot) {
  38.                                 case UIWidget.Pivot.Bottom:
  39.                                         cachedCollider.center += new Vector3 (0, sizeoffset.y * targetTransform.localScale.y / -2, depth);
  40.                                         break;
  41.                                 case UIWidget.Pivot.BottomLeft:
  42.                                         cachedCollider.center += new Vector3 (+sizeoffset.x * targetTransform.localScale.x / 2, sizeoffset.y * targetTransform.localScale.y / 2, depth);
  43.                                         break;
  44.                                 case UIWidget.Pivot.BottomRight:
  45.                                         cachedCollider.center += new Vector3 (sizeoffset.x * targetTransform.localScale.x / -2, sizeoffset.y * targetTransform.localScale.y / 2, depth);
  46.                                         break;
  47.                                 case UIWidget.Pivot.Top:
  48.                                         cachedCollider.center += new Vector3 (0, sizeoffset.y * targetTransform.localScale.y / -2, 0);
  49.                                         break;
  50.                                 case UIWidget.Pivot.TopLeft:
  51.                                         cachedCollider.center += new Vector3 (sizeoffset.x * targetTransform.localScale.x / 2, sizeoffset.y * targetTransform.localScale.y / -2, depth);
  52.                                         break;
  53.                                 case UIWidget.Pivot.TopRight:
  54.                                         cachedCollider.center += new Vector3 (sizeoffset.x * targetTransform.localScale.x / -2, sizeoffset.y * targetTransform.localScale.y / -2, depth);
  55.                                         break;
  56.                                 case UIWidget.Pivot.Left:
  57.                                         cachedCollider.center += new Vector3 (sizeoffset.x * targetTransform.localScale.x / 2, 0, depth);
  58.                                         break;
  59.                                 case UIWidget.Pivot.Right:
  60.                                         cachedCollider.center += new Vector3 (sizeoffset.x * targetTransform.localScale.x / -2, 0, depth);
  61.                                         break;
  62.                                 case UIWidget.Pivot.Center:
  63.                                         cachedCollider.center += new Vector3 (cachedCollider.center.x, cachedCollider.center.y, depth);
  64.                                         break;
  65.                                 }
  66.                         }
  67.                 }
  68.         }
  69. }
  70.  

paulygon

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 11
    • View Profile
Re: Best way to resize collider?
« Reply #3 on: November 20, 2013, 06:29:16 PM »
I've rebuilt Malzbier's awesome code to work for the newer version of NGUI's width and height instead. Fair warning, I've only tested pivot left so far!

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. [ExecuteInEditMode]
  5. [AddComponentMenu("NGUI/Helper/ColliderUpdater")]
  6. public class UpdateCollider : MonoBehaviour
  7. {
  8.    
  9.     public Transform targetTransform;
  10.     public BoxCollider cachedCollider;
  11.     public Vector2 sizeoffset = new Vector2 (1, 1);
  12.     public float depth;
  13.        
  14.     /// <summary>
  15.     /// Getting Stuff Cached
  16.     /// </summary>
  17.     void Start ()
  18.     {
  19.         if (targetTransform == null) {
  20.             targetTransform = transform.FindChild ("Background");
  21.         }
  22.         if (this.GetComponent<BoxCollider> () != null) {
  23.             cachedCollider = this.GetComponent<BoxCollider> ();
  24.         }
  25.     }
  26.    
  27.     /// <summary>
  28.     /// Update the possition of the collider according to the size of the target UISlicedSprite.
  29.     /// </summary>
  30.     void Update ()
  31.     {
  32.        
  33.         if (targetTransform != null) {
  34.                         UISprite thisSprite = targetTransform.GetComponent<UISprite> ();
  35.  
  36.                         cachedCollider.size = new Vector3 (sizeoffset.x * thisSprite.width, sizeoffset.y * thisSprite.height, 1);
  37.             cachedCollider.center = targetTransform.localPosition;
  38.                        
  39.             if (thisSprite != null) {
  40.                                
  41.                                 switch (thisSprite.pivot) {
  42.                                 case UIWidget.Pivot.Bottom:
  43.                                         cachedCollider.center += new Vector3 (0, sizeoffset.y * thisSprite.height / -2, depth);
  44.                                     //cachedCollider.center += new Vector3 (0, sizeoffset.y * targetTransform.localScale.y / -2, depth);
  45.                                     break;
  46.                                 case UIWidget.Pivot.BottomLeft:
  47.                                         cachedCollider.center += new Vector3 (sizeoffset.x * thisSprite.width / 2, sizeoffset.y * thisSprite.height / 2, depth);
  48.                                     //cachedCollider.center += new Vector3 (+sizeoffset.x * targetTransform.localScale.x / 2, sizeoffset.y * targetTransform.localScale.y / 2, depth);
  49.                                     break;
  50.                                 case UIWidget.Pivot.BottomRight:
  51.                                         cachedCollider.center += new Vector3 (sizeoffset.x * thisSprite.width / -2, sizeoffset.y * thisSprite.height / 2, depth);
  52.                                     //cachedCollider.center += new Vector3 (sizeoffset.x * targetTransform.localScale.x / -2, sizeoffset.y * targetTransform.localScale.y / 2, depth);
  53.                                     break;
  54.                                 case UIWidget.Pivot.Top:
  55.                                         cachedCollider.center += new Vector3 (0, sizeoffset.y * thisSprite.height / -2, 0);
  56.                                     //cachedCollider.center += new Vector3 (0, sizeoffset.y * targetTransform.localScale.y / -2, 0);
  57.                                     break;
  58.                                 case UIWidget.Pivot.TopLeft:
  59.                                         cachedCollider.center += new Vector3 (sizeoffset.x * thisSprite.width / 2, sizeoffset.y * thisSprite.height / -2, depth);
  60.                                     //cachedCollider.center += new Vector3 (sizeoffset.x * targetTransform.localScale.x / 2, sizeoffset.y * targetTransform.localScale.y / -2, depth);
  61.                                     break;
  62.                                 case UIWidget.Pivot.TopRight:
  63.                                         cachedCollider.center += new Vector3 (sizeoffset.x * thisSprite.width / -2, sizeoffset.y * thisSprite.height / -2, depth);
  64.                                         //cachedCollider.center += new Vector3 (sizeoffset.x * targetTransform.localScale.x / -2, sizeoffset.y * targetTransform.localScale.y / -2, depth);
  65.                                         break;
  66.                                 case UIWidget.Pivot.Left:
  67.                                         cachedCollider.center += new Vector3 (sizeoffset.x * thisSprite.width / 2, 0, depth);
  68.                                         break;
  69.                                 case UIWidget.Pivot.Right:
  70.                                         cachedCollider.center += new Vector3 (sizeoffset.x * thisSprite.width / -2, 0, depth);
  71.                                     //cachedCollider.center += new Vector3 (sizeoffset.x * targetTransform.localScale.x / -2, 0, depth);
  72.                                     break;
  73.                                 case UIWidget.Pivot.Center:
  74.                                         cachedCollider.center += new Vector3 (cachedCollider.center.x, cachedCollider.center.y, depth);
  75.                                     //cachedCollider.center += new Vector3 (cachedCollider.center.x, cachedCollider.center.y, depth);
  76.                                     break;
  77.                                 }
  78.             }
  79.         }
  80.     }
  81. }
  82.  

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Best way to resize collider?
« Reply #4 on: November 20, 2013, 07:28:59 PM »
Widgets currently have a built-in option to automatically adjust the collider's dimensions.

paulygon

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 11
    • View Profile
Re: Best way to resize collider?
« Reply #5 on: November 21, 2013, 01:13:21 AM »
I looked for just that. A hint would have been cool. UpdateWidgetCollider? I'm still wobbling around with C# and couldn't find something HERE
This seems to do the trick and replace the earlier code:
NGUITools.UpdateWidgetCollider(gameObject.GetComponent<BoxCollider>());

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Best way to resize collider?
« Reply #6 on: November 21, 2013, 02:11:27 AM »
The new doc page for the widget talks about that option:

http://www.tasharen.com/forum/index.php?topic=6702

paulygon

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 11
    • View Profile
Re: Best way to resize collider?
« Reply #7 on: November 21, 2013, 10:47:45 AM »
That was an extremely helpful link, thanks! I overlooked the NGUI Documentation thread entirely.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Best way to resize collider?
« Reply #8 on: November 21, 2013, 01:58:37 PM »
That would be because I only created it yesterday :)

It ties in with the "Help" options on NGUI components in 3.0.6.