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.

Topics - Ferazel

Pages: [1] 2 3
NGUI 3 Support / Scrollbar not respecting CancelIfDragFits
« on: December 15, 2014, 06:33:46 PM »
Hi Aren,

I was looking into a problem today where if the scrollbars are set to always visible, and the content of a scrollview doesn't fill the content area there are some problems.

One is that the scrollbar will show the extra space on the content area.
Two is that the scrollbar will not respect the cancelIfDragFits property and will allow you to scroll the scrollview.

Could you update the code so that always visible scrollbars will respect this property and not allow scrolling internally?

If you make a code change can you post it here until the next version is available?

NGUI 3 Support / Momentumless ScrollWheel?
« on: November 12, 2014, 03:11:24 PM »

I was digging around the code for UIScrollView today because it was requested that the mouse ScrollWheel not have any momentum to it when it moves a ScrollView. From what I was able to determine it appears that the code for UIScrollView does a momentum shift on it regardless of the input Axis value received and the momentum value on the scrollview. I want it to work like a PC scrollbar where it will stop immediately after the scroll wheel stops moving.

Is there an easy way that I can turn ScrollWheel momentum off? (Ideally through existing properties so that it isn't overwritten via NGUI updates)

Also as an optimization, I noticed that you're using a mMomentum.magnitude check in the LateUpdate() where a mMomentum.sqrMagnitude should be fine.

NGUI 3 Support / UIPanels no longer offset internal widgets
« on: October 10, 2014, 10:27:46 AM »
I just recently noticed that this was a new bug. However, there seems to have been some change in 3.7.4 behavior of the NGUI panels no longer changing the internal local positions of their children.

NGUI Panel (Soft Clip or Contrain but no clip)

If I anchor the panel to a widget that is anchored to the camera's bottom left, the UIGrid's position doesn't seem to update when I change the aspect ratio. As a work around I am adding a widget to the UIGrid object and anchoring that to the UIGrid's parent. Was this an intended change? Did anyone else notice this problem?

NGUI Version: 3.7.4
Unity Version: 4.5.4p3


We upgraded our project to NGUI 3.7.4 and we started experiencing some problems with an exception that is being thrown when in development build.

Unhandled Exception: System.ArgumentException: PropertyToID can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.

We believe that the problem is that on line 636 of UIDrawCall you create the references via

  2. static int[] ClipRange =
  3.         {
  4.                 Shader.PropertyToID("_ClipRange0"),
  5.                 Shader.PropertyToID("_ClipRange1"),
  6.                 Shader.PropertyToID("_ClipRange2"),
  7.                 Shader.PropertyToID("_ClipRange4"),
  8.         };
  10. static int[] ClipArgs =
  11.         {
  12.                 Shader.PropertyToID("_ClipArgs0"),
  13.                 Shader.PropertyToID("_ClipArgs1"),
  14.                 Shader.PropertyToID("_ClipArgs2"),
  15.                 Shader.PropertyToID("_ClipArgs3"),
  16.         };

I think these arrays be created in the Awake() if possible and not as an initializers.

We were able to reproduce the crash in a naked project. Import NGUI. Set player settings to be FAST & NO Exceptions. In the build settings check for "Development build" and build onto the device. When the scene starts to load this exception will be thrown and crash the app.
NGUI 3.7.4 (Downloaded and upgraded on September 29th)
Unity 4.5.4f1
XCode 6.0.1
Multiple devices running both iOS 7 and iOS 8 exhibited this behavior.

Let me know if you need additional information.

TNet 3 Support / (1.9.6b) iOS Freeze/Crash on Sleep
« on: August 05, 2014, 06:52:33 PM »
We're running into a problem when we put our devices to sleep the device will be unresponsive when we awake. We did a test on the examples and it is happening there as well. We're only targeting iOS and Editor right now in a LAN-only connection environment.

We deploy the example on an iOS device, and we connect to a server fine. However, as soon as the app is put to sleep the app becomes unresponsive. We haven't spent a lot of time digging into the problem but it seems to affect all of our iOS devices (various iPads and iPhones) so I figure you'd be able to replicate the problem fairly easily.

Connect to a server, launch and example, do some network sends, put the device to sleep (tapping the wake/sleep button), give it 5 seconds, and then rewake the device by tapping the wake/sleep again. The Connect dialog will appear, but the app will not pull up the server list nor is the other UI is not responsible. We've tried it on our project (which uses NGUI) and the same problem happens there in our lobby browser.

We'll continue to do more digging and update this topic with more information when we can get it to you. In the meantime, could you try to look into this problem and see if it is happening on your hardware? I looked through the docs, but I didn't see a best practice in regards to how we need to close sockets or handle the sleep functionality so that the app doesn't freeze.

We've tried with multicasting on and off, and it doesn't seem to affect the problem.


TNet 3 Support / TNObject where rebuildMethodList = false?
« on: August 01, 2014, 11:33:54 AM »
Hey Aren,

We recently started using TNET for adding multiplayer to our product crazy late in the dev process. Amazingly, the process has been pretty good. Which I attribute to the quality of the TNET plugin.

We're concerned with the overhead of rebuilding the RFC method list (mainly since it checks public/private/instance methods on the game object). The main reason we want a TNObject on our objects was because we wanted a network synced UID that we could use to find units on each of the end-users's machine.

So to confirm our understanding of how this works, unless the object receives an RFC that it manages, the method list isn't recomputed for the entire hierarchy? If we add a TNObject with a 0 UID to the unit's GameObject that we sync with a TNManager.Create, it would only rebuild the method list if that unit received an RFC call, right? In our case, there aren't any RFCs on the unit (since the UID is the only thing we care about) so the method list shouldn't be rebuilt?

If it does execute the rebuild method, is there a way you can recommend that we create a TNObject with a rebuildMethodList = false so that we can make sure we don't spend the reflection time to find all of the RFC calls?


NGUI 3 Support / 3.5.8 Old-Style Localization Bug
« on: April 21, 2014, 11:02:47 AM »
Hi ArenMook,

I noticed that there is a bug when using the old key=value localization approach. In the SelectLanguage() in UILocalize it only checks the "new" dictionary instead of mOldDictionary. So, we should also probably check the old dictionary size before cleaning up and returning null.

I think it should check both, maybe something similar to this:

  1.         static bool LoadAndSelect (string value)
  2.         {
  3.                 if (!string.IsNullOrEmpty(value))
  4.                 {
  5.                         if (mDictionary.Count == 0 && !LoadDictionary(value)) return false;
  6.                         if (SelectLanguage(value)) return true;
  7.                 }
  9.                 //NEW - If we have loaded an old dictionary we are OK here too
  10.                 if(mOldDictionary.Count > 0) {
  11.                         return true;
  12.                 }
  14.                 // Either the language is null, or it wasn't found
  15.                 mOldDictionary.Clear();
  16.                 mDictionary.Clear(); //NEW - We should probably clear the new dictionary too
  17.                 if (string.IsNullOrEmpty(value)) PlayerPrefs.DeleteKey("Language");
  18.                 return false;
  19.         }

Are you planning on removing the Key=Value localization in the future? Our games can use thousands of keys and loading all of the languages associated with these keys in the dictionary would use unnecessary RAM and increase the size of the GC heap (thus reducing GC performance). Keeping the lower overhead Key=Value suits our needs better, but if it's going to be inevitable I guess I'd like to know so we can go through the process now.

NGUI 3 Support / UITweener.Play Implementation Question
« on: April 16, 2014, 05:39:39 PM »
Hi Aren,

We're using your tween library a lot in our game, which seems to be working pretty well except for a situation that occurs sometimes. When we are using a tween's PlayForward and PlayReverse we sometimes run into situations where the mFactor not being reset when calling PlayForward or PlayReverse would cause the tweens to sometimes not play because the first update would think that it is already done. This would occur in situations where you call PlayForward and then call PlayForward again. It would not start from the beginning but rather just immediately terminate.

Is there a reason why the UITweener's mFactor is not reset in the Play() method like so?
  1. public void Play (bool forward)
  2. {
  3.         mAmountPerDelta = Mathf.Abs(amountPerDelta);
  4.         if (!forward) mAmountPerDelta = -mAmountPerDelta;
  5.         mFactor = (mAmountPerDelta < 0f) ? 1f : 0f; //NEW CODE HERE
  6.         enabled = true;
  7.         Update();
  8. }

Without that I found us doing things like this which ended up rather ugly.
  1. mTweenVisible.PlayForward(); //Need to put the delta amount in the correct direction
  2. mTweenVisible.ResetToBeginning(); //Reset the mFactor
  3. mTweenVisible.PlayForward(); //Now play through correctly

NGUI 3 Support / Optimization Tweaks?
« on: March 31, 2014, 03:58:23 PM »
Hi ArenMook,

We're doing an optimization pass on our game and there were a couple things that I was seeing that might be candidates for optimization.

Currently in UICamera 1239 there is an alloc that is happening every frame due to:
inputHasFocus = (mCurrentSelection != null && mCurrentSelection.GetComponent<UIInput>() != null);
It's appearing as a 0.6KB GC alloc in the profiler. Would it be possible to check/remember the current selection's input by doing that check only when the selection is changed in Changed Selection? It appears that ProcessTouch/Mouse() methods set mCurrentSelection directly, but I'm wondering if they could go through the ChangeSelection coroutine and then only check for UIInput if a new selection was made?

My UI as a whole is consuming about 10% of my CPU frame time:
6% UIPanel.LateUpdate
3.1% UIRect.Update
1% UICamera.Update

These aren't awful by any means, but I notice that you were using the standard Update() on the UIRect. In the profiling tests that I've done, directly calling a MyUpdate() from a manager object is faster than relying on Unity's Update() call (which I would assume is using a slower reflection call). Since all widgets are managed by a UIPanel in the sense of draw calls, would it be possible to have each panel call a MyUpdate() on the widgets instead of relying on a Unity's Update()?

If I'm misinformed, please let me know.

Misc Archive / NGUI for UE4?
« on: March 21, 2014, 06:25:10 PM »
Like most people, I am extremely tempted to do more research into Unreal Engine 4 with their new pricing model. I am a UI guy and spend a majority of my days in NGUI. I briefly looked at UE4's UI (SLATE) and had me realizing just how easy I have it with NGUI and Unity. I was wondering if ArenMook might consider making an NGUI for UE4 and releasing it on the Marketplace? Knowing that there was a tool as great as NGUI waiting for me on the otherside would be great.

I realize that most people would want to have Scaleform (GFx) integration for UE4, but I've never been a big fan of Scaleform (DIE FLASH DIE!). However, there doesn't seem to be a great indie UI solution for devs on UE's side?

NGUI 3 Support / 3.5.1 Bitmapped UIFont Corruption
« on: February 25, 2014, 08:07:37 PM »
Thanks for your continued work on NGUI. I updated our in-development project from 3.4.9 to 3.5.1 and we're having a problem.

I'm experiencing what appears to be a bug with bitmapped UIFonts (old school). It appears that when I make a UIFont that appears on the Atlas it will initially work, but when I rebuild the atlas for any reason the bitmapped UIFont will have corrupt UV coordinates. The only way to fix this is to delete the UIFont object and remove it from the atlas and rebuild and recreate the UILabels? Can you see if you can reproduce?


NGUI 3 Support / 3D UI Anchor Question/Problem
« on: December 18, 2013, 03:00:29 PM »
I'm trying to get a 3D UI setup in NGUI. However, I want to have static 2D UI on this 3D camera as well in the corners to allow me to have a 2D overlay in my 3D camera. I don't really need another 2D UI in the scene (at least I don't think I do). However, I'm basically just trying to figure out how to properly anchor sprites using a 3D UI system.

I have the following scene
--UICamera (perspective 3D camera)
----TopLeftPositionedSprite (Anchored to UICamera top left)

The problem appears to be that if the z depth isn't 0.5 of the camera's clip plane the calculations are off. It seems that the anchor system depends on this by the following code:
  1. Mathf.Lerp(cam.nearClipPlane, cam.farClipPlane, 0.5f)

There seems to be a lot of this in the code for determine World or Viewport points. So I'm curious if we need to position anchors with 3D do we need to make sure that the UIWidgets are in a z-space that is exactly 1/2 of the camera's near/far clipping depth in order to get these elements positioned properly? Is this a known limitation? Wouldn't it make more sense to get the depth of the object by performing a target.position.z - camera.position.z?

NGUI 3 Support / 3.0.7f3 TweenAlpha UIRect
« on: December 18, 2013, 01:23:20 PM »
We upgraded our components and we found that our game crashed due to changes in how TweenAlpha finds its UIRect. I just want to bring it to your attention so you can be made aware.

In most tween classes the target is found via GetComponentInChildren but in TweenAlpha it is only GetComponent. Were you going to change the other tweens to use GetComponent or was it a mistake in TweenAlpha? Or is there a reason why one uses one method and one uses the other?


NGUI 3 Support / 3.0.7f2 - Problems Anchoring to Screen Positions
« on: December 12, 2013, 12:12:23 PM »
Hi, I upgraded to f2 and now I'm having problems figuring out how to get widgets to parent to screen coordinates (top-left) for example.

My 2D hierarchy is the following

When I try to anchor, it correctly finds the UIPanel GameObject. However, when I try to specify Advanced and set only the top and left coordinates in the anchor settings it is sticking it in my main camera's space and not in the UI space. Am I doing something wrong from what anyone can tell? It seemed to be working properly in f1 so was there a change that I need to do in order to get sprites to screen anchors in F2?

A second question. Are you going to deprecate the old UIAnchor script? While I find the new anchoring system powerful, I find a little cumbersome to use. (A lot of selecting NONE for simple point anchoring using Advanced) I also miss being able to anchor non-widget GameObjects in the new system as I often have a "ViewController" GameObject that will contain a controller script that manages the widgets underneath it.

NGUI 3 Support / 3.0.6f7 LateUpdate Optimization
« on: December 06, 2013, 06:23:40 PM »
Yet another LateUpdate performance thread. Using NGUI 3.0.6f7 we were doing some performance testing and it appears that there is significant overhead involved here. We have about 1000 widgets in our scene. None of the widgets move so the panels are marked as static. We were doing some profiling and we ran into a question that I'm curious if you could look at.

Our first test:
----(An additional 11 sprites here)
----(An additional 11 sprites here)

There were 94 panels of these 11 sprite sets to equate to about 1000 UIWidgets. The idea was that we could use the panels to determine if they were visible or not on the camera and disable and enable it. However, just having them all visible produced some very disturbing profiling results. Our late update call was taking 13ms or 87% of a naked scene's CPU and was already causing frame rate problems in the editor. We looked at the deep profile of it and it was spending 98% of the time inside of the LateUpdate -> UpdateWidgets() call.

Then we did the following layout (basically all the widgets were parented to one panel)

We expected this to be faster (obviously fewer panels and draw calls), but we found that the profiler said it was < 1ms (7%)! Meaning it was upwards of 13x faster than sticking them on sub panels so I went to investigate what might be happening.

Inside of a UIPanel.LateUpdate() there is a loop that is confusing me, that I'm hoping you might be able to shed some implementation light on.

  1. UIPanel.LateUpdate() {
  2.    // Only the very first panel should be doing the update logic
  3.    if (list[0] != this) return;
  5.    // Update all panels
  6.    for (int i = 0; i < list.size; ++i)
  7.    {
  8.         UIPanel panel = list[i];
  9.         panel.mUpdateTime = RealTime.time;
  10.         panel.UpdateTransformMatrix();
  11.         panel.UpdateLayers();
  12.         panel.UpdateWidgets();
  13.    }
  14. ...
  15. }

Then inside of the UIPanel.UpdateWidgets() this is happening

  1. UIPanel.UpdateWidgets() {
  2. ....
  3.   for (int i = 0, imax = UIWidget.list.size; i < imax; ++i)
  4.   {
  5.         UIWidget w = UIWidget.list[i];
  6.         // If the widget is visible, update it
  7.         if (w.panel == this && w.enabled)
  8.         .....
  9.   }
  10. ....
  11. }

So the problem I have is that if you have a lot of panels there is significant overhead iterating through every widget that many times (even if not much is done because it checks the equality on the w.panel vs this).

My recommendation would be to iterate through all of the widgets only once and check their parent panel for information relating to their visibility. As there are likely significantly more widgets than panels. Something like this

  1. UIPanel.LateUpdate() {
  2. if (list[0] != this) return;
  4.                 // Update all panels
  5.                 for (int i = 0; i < list.size; ++i)
  6.                 {
  7.                         UIPanel panel = list[i];
  8.                         panel.mUpdateTime = RealTime.time;
  9.                         panel.UpdateTransformMatrix();
  10.                         panel.UpdateLayers();
  11.                         // REMOVE THIS panel.UpdateWidgets();
  12.                 }
  14. // Update Widgets - Update all widgets only once, instead of iterating through the list once per panel
  15.                 for (int i = 0, imax = UIWidget.list.size; i < imax; ++i)
  16.                 {
  17.                         UIWidget w = UIWidget.list[i];
  19.                         // If the widget is visible, update it
  20.                         if (w.panel.enabled)
  21.                         .....
  22.                  }
  23. ...
  24. }

I hope that makes sense. If I'm wrong about this implementation I'd appreciate any information you can provide on why it was implemented as described above.

Thanks for your time!

Pages: [1] 2 3