Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - doggan

Pages: [1]
NGUI 3 Support / Grids with thin (1 pixel) spacing
« on: August 11, 2015, 02:57:29 AM »
I am trying to make a scrollable grid with a very thin border between the cells. I was playing around with the NGUI Example 14 scene to try and prototype my idea. I notice that even with UIRoot set to flexible (pixel-perfect), I still get slight inconsistencies on different devices (currently testing with iPhone 5 and iPhone 6).

When you scroll to certain positions, the spacing sometimes looks larger than 1 pixel (see attached screenshot).

What is the best technique to avoiding this issue? Even if I can't achieve 1 pixel spacing, I would be happy with a solution that provides 2+ pixel spacing as long is it is consistent between all cells.

For reference, I'm using NGUI 3.9.1. Thanks.

NGUI 3 Support / Re: GC Alloc each frame
« on: March 03, 2014, 04:13:58 AM »
Not sure if this is related, but I've spent the past couple hours tracking down a GC spike in my application as well. If you have multiple panels active at the same time, a seemingly harmless change to a widget (that causes a re-draw) may cause the shared buffers of the two panels to fight with one another and cause alloc/GC issues:

NGUI 3 Support / Massive GC Spikes ('batting' UIPanels)
« on: March 03, 2014, 04:08:51 AM »

It seems that UIPanel stores it's vertex buffers as static, meaning they are shared between all UIPanels. The comment in code says 'Cached in order to reduce memory allocations'.

This creates massive performance issues when two or more panels are active at the same time, and they both have some animated widget that requires redraw.

For example, Panel A is a normal panel and Panel B is a sub-panel set up with clipping for a UITable or UIGrid. They are both active at the same time. In both panels A and B, you have a UILabel that animates its color every frame. This animation forces both panels to re-draw and rebuild their buffers every frame.

Since the buffers are all using NGUI's BetterList, they theoretically should be re-used and therefore minimize allocation. But the problem is exacerbated when the vertex count of Panel A and Panel B is very different.

For example, Panel A has 100 vertices and Panel B has 2000 vertices. When the panel submits its draw call (UIDrawCall::Set), setting the mesh's vertices requires calling BetterList::ToArray, which is then forced to call BetterList::Trim to resize the buffer.

When Panel A and Panel B get updated every frame, they will basically fight one another for the shared (static) UIPanel vertex buffers. Panel B will constantly need to re-alloc a larger buffer for 2000 vertices, and Panel A will constantly need to trim down to 100 vertices, causing large alloc and GC problems.

I've temporarily solved the issue locally by removing the 'static' modifier on the UIPanel's buffers. While this technically increases my initial alloc count, it gives me much smoother and stable performance overall.

Is there a better way to solve this issue (other than not animating the labels...)?

Thanks! :)

NGUI 3 Support / Re: problem updating free ver to a paid ver
« on: March 02, 2014, 11:24:13 AM »
Doesn't look like there's a UIButtonTween.cs in the latest version of NGUI. You probably still have some old files that didn't get deleted during your upgrade. The solution is probably the same as your previous problem (i.e. follow the instructions in the readme file):

NGUI 3 Support / Overlapping UIs - Forwarding Touches
« on: March 02, 2014, 11:12:21 AM »

I have two 2-D UIs in my scene - one in the foreground and one in the background. Both have their own camera, with the foreground camera depth being greater than the background camera depth.

The foreground UI has many different invisible buttons on it that take up the entire screen. Depending on which area the screen is clicked, different sounds play.

The background UI has other moving, visible widgets on it that react differently when clicked.

The problem I have is that the foreground UI intercepts all of the touch events, and the background UI will not receive any. What is the best way to 'forward' the touch event to the background UI camera so that it can handle the event as well?

Thank you!

NGUI 3 Support / Re: Positioning Objects Relative to a Scaling Background
« on: February 20, 2014, 09:39:27 PM »
Based off ArenMook's original script, the following code solves my problem, by making the manual height calculate based on the width of the screen:

  1. using UnityEngine;
  3. [RequireComponent(typeof(UIRoot))]
  4. public class UIRootAdjustment : MonoBehaviour
  5. {
  6.         public int targetHeight = 720;
  8.         UIRoot mRoot;
  10.         void Awake () { mRoot = GetComponent<UIRoot>(); }
  12.         void Update ()
  13.         {
  14.                 mRoot.manualHeight = Mathf.RoundToInt(targetHeight * ((float)Screen.height / Screen.width));
  15.         }
  16. }

Thanks for leading me in the right direction :)

NGUI 3 Support / Re: Positioning Objects Relative to a Scaling Background
« on: February 20, 2014, 09:10:31 PM »
Thanks for the replies.

I was correctly able to anchor my objects relative to the scaling background texture. I used the Unified anchor type with the background texture as the target, and custom anchor points specifying the relative offsets.

This still doesn't solve the scaling issue, though, since I need these objects to scale based on the background texture's width. I probably need to do something similar to manually adjusting the UIRoot as shown here:

Will post back when/if I figure it out.

NGUI 3 Support / Positioning Objects Relative to a Scaling Background
« on: February 20, 2014, 03:26:53 AM »
I have a 2d background that stretches with the screen size, while maintaining it's aspect ration (using aspectRation = BasedOnWidth, and an Advanced Anchor anchoring to the left/right sides of the screen).

I need to position/scale many other UI objects relative to this background.

For example, an object is positioned at (x = 100, y = 100) with a scale of (1.0, 1.0, 1.0) when the screen resolution is 960x640. When the screen is resized to 640x960, the background shrinks by 0.66 (changeInWidth = newWidth / prevWidth = 640 / 960 = 0.66). Therefore the new position of my object will be at (x = 66, y = 66) with a scale of (0.66, 0.66, 0.66).

I am wondering what the best way to do this in NGUI is?

I've tried creating a custom script and hooking in to the OnDimensionsChanged of the background's UIWidget, and then adjusting the positions/scales of the relatively positioned objects following the calculation above... while also handling edit mode screen resizes + remembering the previous settings before the screen change... etc. It seems to be getting overly complicated, so I'm wondering if there's a better way this. I'm thinking there may be some way to handle this with the new anchor system with Advanced / Custom settings, but I can't seem to figure it out.

Thanks in advance.


I simplified the code and came up with the solution below to calculate my positions relative to the background (_target widget). Still not sure what the best way to handle scale is though, since NGUI automatically scales the sprites due to the use of FixedSize (which is based on height). But in this case, I want to scale based on the width of the background texture, and not the height of the window...

  1.         [ExecuteInEditMode]
  2.         public class Positioner : MonoBehaviour
  3.         {
  4.                 /// <summary>
  5.                 /// The background target widget.
  6.                 /// </summary>
  7.                 [SerializeField]
  8.                 private UIWidget _target;
  9.                 [SerializeField]
  10.                 private Vector2 _relativePosition;
  12.                 private void Update ()
  13.                 {
  14.                         if (_target != null) {
  15.                                 Vector3 bottomLeft = _target.worldCorners [0];
  16.                                 Vector3 topRight = _target.worldCorners [2];
  17.                                 float width = topRight.x - bottomLeft.x;
  18.                                 float height = topRight.y - bottomLeft.y;
  20.                                 // Calculate world coordinates relative to bottom left of target widget.
  21.                                 Vector3 worldPos = new Vector3 (
  22.                                         bottomLeft.x + width * _relativePosition.x,
  23.                                         bottomLeft.y + height * _relativePosition.y,
  24.                                         0.0f);
  26.                                 this.transform.position = worldPos;
  27.                         }
  28.                 }
  29.         }

NGUI 3 Support / 3.0.9 f2 - Panel Clipping Issues
« on: January 20, 2014, 02:23:21 AM »
The following code that was added in 3.0.9 f2 in UIPanel.cs is causing weird clipping issues for me on some of my UIs. The panel has it's clipping set to None, but objects are still getting clipped.

  1. bool vis = forceVisible || (w.CalculateCumulativeAlpha(frame) > 0.001f && IsVisible(w));

Everything was working fine up to and including 3.0.9 f1, so I reverted the above code to the code below, and the problem was solved:

  1. bool vis = forceVisible ||
  2.         (mClipping == UIDrawCall.Clipping.None && !w.hideIfOffScreen) ||
  3.                 (w.CalculateCumulativeAlpha(frame) > 0.001f && IsVisible(w));

Is this a NGUI bug or is something not set up properly in my scene?


NGUI 3 Support / 3.0.8 f7 - ScrollBar localPosition is NaN
« on: January 15, 2014, 12:51:03 AM »
I am getting the following error when clicking on a Scroll Bar whose contents are completely contained in a subpanel:
  1. transform.localPosition assign attempt for 'SubPanel' is not valid. Input localPosition is { 0.000000, NaN, 0.000000 }.
  2. UnityEngine.Transform:set_localPosition(Vector3)

I am able to repro it in the NGUI Example 9 - Quest Log scene.

1). Open the Example 9 - Quest Log scene.
2). Find the "SubPanel" game object, and change it's UIScrollView show condition to "Always".
3). Press Play and enter game view.
4). Expand the top two quests so that the scroll bar foreground shrinks.
5). Collapse the two expanded quests so that the scroll bar foreground expands to full height.
6). Click on the scroll bar and try to drag and the error will occur.


NGUI 3 Support / Re: Non-looping UISpriteAnimation
« on: July 20, 2012, 07:03:44 AM »
Thank you for adding this functionality to the 2.1.0 release. :D

However, I tried to use it and I think it is bugged.

In UISpriteAnimation.cs, this:
  1. public bool isDone { get { return mActive; } }

... should be this:
  1. public bool isDone { get { return !mActive; } }

Making this change, it seems to work perfectly.

(Or, the accessor should be renamed from "isDone" to "isPlaying" or "isActive").


NGUI 3 Support / Re: Non-looping UISpriteAnimation
« on: July 02, 2012, 08:06:31 AM »
Awesome! Thanks for the quick response.

NGUI 3 Support / Non-looping UISpriteAnimation
« on: July 01, 2012, 05:54:38 AM »
I purchased NGUI a few weeks ago, and I am extremely pleased! It is very well designed and easy to use. Thanks for the great library.

In addition to my UI and gameplay, I am using NGUI for all of my particle effects.

For example, an explosion effect has 5 frames of animation data. Using UISpriteAnimation, I can get the desired effect I want.

However, it was not perfect, so I made changes locally to the NGUI library in order to get the behavior I want. My question is: Is there a better way to do this? If not, is it possible to request this type of functionality for a future version of NGUI?

Here is what I added:
  • Ability to set a non-looping UISpriteAnimation (single-shot) - The explosion should play once and then stop.
  • Public interface to query for when the animation is done playing - When the explosion is done playing, some other code looks at the “IsDone” flag and destroys the particle effect. (This could also be done with SendMessage, but I opted with the flag for performance reasons).
  • Public interface for resetting the animation to the first frame - All of my particle effects are pooled, so when an explosion is destroyed, it is recycled and used later, so I need to reset the animation.

Is this the correct way to approach this, or is there a better way? If not, is it possible to request this functionality?

Thanks for reading!

Pages: [1]