Author Topic: Nested soft clip Panels in Flashplayer  (Read 5547 times)

Pasty

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 8
    • View Profile
Nested soft clip Panels in Flashplayer
« on: October 08, 2014, 12:36:50 PM »
There seems to be a Panel display bug in Flashplayer builds. If a UIPanel is the child of another UIPanel and both are set to Soft Clip, the child UIPanel will not render in Flashplayer builds.

This is not the case for unparented UIPanels set to Soft Clip. In some cases (i.e. while moving a scrollview) the bugged panel will render for a frame. I've attached an example scene, but you'll likely have to modify NGUI a bit to get it to run. NGUI does not seem to compile for Flashplayer out of the box and I had to make some modifications to fix that. I am using NGUI 3.7.1

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Nested soft clip Panels in Flashplayer
« Reply #1 on: October 08, 2014, 01:35:00 PM »
You should update your NGUI, it should compile just fine.

I'm not going to do any investigation of the Flash platform glitches anymore as Unity abandoned that platform over a year ago, and a lot of things simply don't work in it.

walterkognito

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 3
    • View Profile
Re: Nested soft clip Panels in Flashplayer
« Reply #2 on: October 09, 2014, 01:54:31 PM »
fyi, flash does not compile; you have a few typos.

Anyways I fixed it, another flash scope issue.  The IsVisible method in UIPanel needs to be slightly adjusted. 

It should be this:     
  1. public bool IsVisible(Vector3 x, Vector3 y, Vector3 z, Vector3 w)
  2. {
  3.         UpdateTransformMatrix();
  4.  
  5.         // Transform the specified points from world space to local space
  6.         Vector3 a = worldToLocal.MultiplyPoint3x4(x);
  7.         Vector3 b = worldToLocal.MultiplyPoint3x4(y);
  8.         Vector3 c = worldToLocal.MultiplyPoint3x4(z);
  9.         Vector3 d = worldToLocal.MultiplyPoint3x4(w);
  10.  
  11.                 mTemp[0] = a.x;
  12.                 mTemp[1] = b.x;
  13.                 mTemp[2] = c.x;
  14.                 mTemp[3] = d.x;
  15.  
  16.                 float minX = Mathf.Min(mTemp);
  17.                 float maxX = Mathf.Max(mTemp);
  18.  
  19.                 mTemp[0] = a.y;
  20.                 mTemp[1] = b.y;
  21.                 mTemp[2] = c.y;
  22.                 mTemp[3] = d.y;
  23.  
  24.                 float minY = Mathf.Min(mTemp);
  25.                 float maxY = Mathf.Max(mTemp);
  26.  
  27.                 if (maxX < mMin.x) return false;
  28.                 if (maxY < mMin.y) return false;
  29.                 if (minX > mMax.x) return false;
  30.                 if (minY > mMax.y) return false;
  31.  
  32.                 return true;
  33. }
  34.  


Or else corners below will get (incorrectly) overwritten after it checks the first clipped panel.

  1. public bool IsVisible (UIWidget w)
  2. {
  3.                 UIPanel p = this;
  4.                 Vector3[] corners = null;
  5.  
  6.                 while (p != null)
  7.                 {
  8.                         if ((p.mClipping == UIDrawCall.Clipping.None || p.mClipping == UIDrawCall.Clipping.ConstrainButDontClip) && !w.hideIfOffScreen)
  9.                         {
  10.                                 p = p.mParentPanel;
  11.                                 continue;
  12.                         }
  13.  
  14.                         if (corners == null) corners = w.worldCorners;
  15.                         if (!p.IsVisible(corners[0], corners[1], corners[2], corners[3])) return false;
  16.                         p = p.mParentPanel;
  17.                 }
  18.                 return true;
  19. }
  20.  

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Nested soft clip Panels in Flashplayer
« Reply #3 on: October 10, 2014, 02:36:58 AM »
The two functions you pasted are exactly how they are in 3.7.4.

As I mentioned, you needed to update.

walterkognito

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 3
    • View Profile
Re: Nested soft clip Panels in Flashplayer
« Reply #4 on: October 14, 2014, 10:20:39 AM »
They aren't exact, but close.  The issue is "a = worldToLocal.MultiplyPoint3x4(a);".  Due to scope bugs, Flash, in this instance, passes by reference and not by value.  Thus the second time around a/b/c/d are wrong.         

Also, even with 3.7.4 Flash does not compile.  I suppose since it doesn't compile due to a Unity bug you don't count it.  If I submit flash fixes to you will you merge them in?     

Original 3.7.4:
  1. public bool IsVisible (Vector3 a, Vector3 b, Vector3 c, Vector3 d)
  2. {
  3.                 UpdateTransformMatrix();
  4.  
  5.                 // Transform the specified points from world space to local space
  6.                 a = worldToLocal.MultiplyPoint3x4(a);
  7.                 b = worldToLocal.MultiplyPoint3x4(b);
  8.                 c = worldToLocal.MultiplyPoint3x4(c);
  9.                 d = worldToLocal.MultiplyPoint3x4(d);
  10.  
  11.                 mTemp[0] = a.x;
  12.                 mTemp[1] = b.x;
  13.                 mTemp[2] = c.x;
  14.                 mTemp[3] = d.x;
  15.  
  16.                 float minX = Mathf.Min(mTemp);
  17.                 float maxX = Mathf.Max(mTemp);
  18.  
  19.                 mTemp[0] = a.y;
  20.                 mTemp[1] = b.y;
  21.                 mTemp[2] = c.y;
  22.                 mTemp[3] = d.y;
  23.  
  24.                 float minY = Mathf.Min(mTemp);
  25.                 float maxY = Mathf.Max(mTemp);
  26.  
  27.                 if (maxX < mMin.x) return false;
  28.                 if (maxY < mMin.y) return false;
  29.                 if (minX > mMax.x) return false;
  30.                 if (minY > mMax.y) return false;
  31.  
  32.                 return true;
  33. }
  34.  

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Nested soft clip Panels in Flashplayer
« Reply #5 on: October 14, 2014, 03:17:19 PM »
Ah... curious. Thanks for pointing that out. I've made similar changes on my end:
  1. #if UNITY_FLASH
  2.         public bool IsVisible (Vector3 aa, Vector3 bb, Vector3 cc, Vector3 dd)
  3. #else
  4.         public bool IsVisible (Vector3 a, Vector3 b, Vector3 c, Vector3 d)
  5. #endif
  6.         {
  7.                 UpdateTransformMatrix();
  8.  
  9.                 // Transform the specified points from world space to local space
  10. #if UNITY_FLASH
  11.                 // http://www.tasharen.com/forum/index.php?topic=11390.0
  12.                 Vector3 a = worldToLocal.MultiplyPoint3x4(aa);
  13.                 Vector3 b = worldToLocal.MultiplyPoint3x4(bb);
  14.                 Vector3 c = worldToLocal.MultiplyPoint3x4(cc);
  15.                 Vector3 d = worldToLocal.MultiplyPoint3x4(dd);
  16. #else
  17.                 a = worldToLocal.MultiplyPoint3x4(a);
  18.                 b = worldToLocal.MultiplyPoint3x4(b);
  19.                 c = worldToLocal.MultiplyPoint3x4(c);
  20.                 d = worldToLocal.MultiplyPoint3x4(d);
  21. #endif
  22.                 mTemp[0] = a.x;
  23.                 mTemp[1] = b.x;
  24.                 mTemp[2] = c.x;
  25.                 mTemp[3] = d.x;
  26.  
  27.                 float minX = Mathf.Min(mTemp);
  28.                 float maxX = Mathf.Max(mTemp);
  29.  
  30.                 mTemp[0] = a.y;
  31.                 mTemp[1] = b.y;
  32.                 mTemp[2] = c.y;
  33.                 mTemp[3] = d.y;
  34.  
  35.                 float minY = Mathf.Min(mTemp);
  36.                 float maxY = Mathf.Max(mTemp);
  37.  
  38.                 if (maxX < mMin.x) return false;
  39.                 if (maxY < mMin.y) return false;
  40.                 if (minX > mMax.x) return false;
  41.                 if (minY > mMax.y) return false;
  42.  
  43.                 return true;
  44.         }
Is there anything else that needs to change?

walterkognito

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 3
    • View Profile
Re: Nested soft clip Panels in Flashplayer
« Reply #6 on: October 15, 2014, 12:38:22 PM »
For that bug, yes that's all.  If you truly want Flash to compile though...

In UIWidget change onRender to:

  1.        
  2. public UIDrawCall.OnRenderCallback onRender
  3. {
  4.                 get
  5.                 {
  6.                         return mOnRender;
  7.                 }
  8.                 set
  9.                 {
  10.                         if (!(mOnRender == value))
  11.                         {
  12. #if !UNITY_FLASH
  13.                                 if (drawCall != null && drawCall.onRender != null && mOnRender != null)
  14.                                         drawCall.onRender -= mOnRender;
  15. #endif
  16.                                 mOnRender = value;
  17.                                 if (drawCall != null) drawCall.onRender += value;
  18.                         }
  19.                 }
  20. }
  21.  

Doing "mOnRender != value" will get converted to roughly !(func1.Equals(func2)) in flash.  However flash does not support ".Equals()" in this case.  While Unity incorrectly converts .Equals()/!= on C# functions, it correctly converts ==.  So the workaround is simply "!(mOnRender == value)".

In UILabel change GetWordAtCharacterIndex (int characterIndex) to:

  1. public string GetWordAtCharacterIndex (int characterIndex)
  2. {
  3.         if (characterIndex != -1 && characterIndex < mText.Length)
  4.         {
  5.               int wordStart = LastIndexOfAny(mText, new char[] { ' ', '\n' }, characterIndex) + 1;//mText.LastIndexOfAny(new char[] {' ', '\n'}, characterIndex) + 1;
  6.               int wordEnd = IndexOfAny(mText, new char[] { ' ', '\n', ',', '.' }, characterIndex);//mText.IndexOfAny(new char[] { ' ', '\n', ',', '.' }, characterIndex);
  7.  
  8.               if (wordEnd == -1) wordEnd = mText.Length;
  9.  
  10.               if (wordStart != wordEnd)
  11.               {
  12.                   int len = wordEnd - wordStart;
  13.  
  14.                   if (len > 0)
  15.                   {
  16.                         string word = mText.Substring(wordStart, len);
  17.                         return NGUIText.StripSymbols(word);
  18.                   }
  19.               }
  20.         }
  21.         return null;
  22. }
  23.  
  24. public int LastIndexOfAny(string input, char[] any, int start)
  25. {
  26.         if (start >= 0 && input.Length > 0 && any.Length > 0 && start < input.Length)
  27.         {
  28.             for (int w = start; w >= 0; w--)
  29.             {
  30.                 for (int r = 0; r < any.Length; r++)
  31.                 {
  32.                     if (any[r] == input[w])
  33.                     {
  34.                         return w;
  35.                     }
  36.                 }
  37.             }
  38.         }
  39.         return -1;
  40. }
  41.  
  42. public int IndexOfAny(string input, char[] any, int start)
  43. {
  44.         if (start >= 0 && input.Length > 0 && any.Length > 0 && start < input.Length)
  45.         {
  46.             for (int w = start; w < input.Length; w++)
  47.             {
  48.                 for (int r = 0; r < any.Length; r++)
  49.                 {
  50.                     if (any[r] == input[w])
  51.                     {
  52.                         return w;
  53.                     }
  54.                 }
  55.             }
  56.         }
  57.         return -1;
  58. }
  59.  

LastIndexOfAny and IndexOfAny are not supported in flash (or only certain parameters are supported, I forget).  So you just have to manually implement them yourself.

After those two fixes, 3.7.4 compiles for me in Flash.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Nested soft clip Panels in Flashplayer
« Reply #7 on: October 16, 2014, 06:35:12 AM »
Thanks!