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 - bac9

Pages: [1] 2 3 ... 8
P.S.: It's probably worth checking for character index and not adding spacing to the outermost character to prevent widget border growing needlessly on the outer edge, will do that next.
Turns out it's not possible to do that with simple index check (you need to modify quad size too, otherwise one will fall out to a new line), so disregard that. Some spacing-sized excess width on one side of a label doesn't hurt anyone.

Still curious why only negative spacing was allowed under updated NGUIText size calculation, though. :)

Seemed to be an easy fix, all you need to do to make it work again is to remove the strange check for finalSpacingX being negative before addition of spacing to width (which, for some reason, is only done for non-symbol branch). It's located in NGUIText.cs at line 1015. I changed that line like this:

  1. // if (finalSpacingX < 0f) w += finalSpacingX;
  2. w += finalSpacingX;

Which made everything work like it used to, as far as I can see:

Am I missing anything? What was the reason for disabling spacing influence on spacing values above zero?

P.S.: It's probably worth checking for character index and not adding spacing to the outermost character to prevent widget border growing needlessly on the outer edge, will do that next.

Simple to reproduce: just make a label, type something ("lorem ipsum"), set label mode to Resize Freely, then drag the X spacing around. Previously, calculated widget size accounted for it, now it stays exactly the same no matter the spacing, leading labels to break on more and more lines as spacing grows:

It's probably related to new changes in NGUIText and UILabel, checking how simple it is to fix now.

NGUI 3 Support / Re: Looks like Unity 5.6 broke atlas generation
« on: May 05, 2017, 08:36:21 PM »
Alright, looks like Unity 5.6 packer is broken while "custom packer" from NGUI works correctly. Check out the result of adding aforementioned 3 48x48 .png files to the same atlas using the custom packer:

It's perfect. The only quirk is the fact that sprites in the scene do not update on atlas rebuild from Unity packer to NGUI packer, so for a brief moment everything in your scene looks completely broken, but restarting the scene updates everything to look correctly.

So, based on this, it's probably worth adding a #if UNITY_5_6 check to Atlas Maker and killing "Unity Packer" option there until Unity fixes their packer; as well as checking existing atlases for that toggle if they are modified for the first time under a Unity 5.6 project. What do you think? :)

NGUI 3 Support / Re: Looks like Unity 5.6 broke atlas generation
« on: May 05, 2017, 08:28:16 PM »
Here are some screenshots of the issue. First, the list of atlas sprites under Unity 5.5, for reference on their real proportions (e.g. notice how all icon_issue* sprites are strictly square):

Now, here is Unity 5.6 atlas after 48x48px icon_data_01.png was added to it (ignore a few more icons like icon_help being present, Unity 5.5 example just happened to have them trimmed):

Notice how icon_data_01 sprite was generated incorrectly (it is not square at all and has incorrect border) and how icon_issue* sprites started losing their square dimensions? Next, here is a screenshot after two more 48x48px sprites are added to the atlas in Unity 5.6 (icon_data_02 and icon_data_03):

Now distortion affects more than a dozen of sprites. I have no idea how to fix this and this corrupts any UI where widget sizes are driven by native sprite resolutions, so I had to revert all my atlases and UI prefabs and started using Unity 5.5. to update them. Judging from the severity of the bug being dependent on the number of new sprites, I'd wager a guess that atlas update misreads the borders and dimensions of sprites around areas where new sprites are packed in. Going to experiment with switching to non-native packer to see if this goes away.

Thanks for wrapping this in !UNITY_5_5_OR_NEWER in the new release, that's one thing less to merge in after NGUI updates! :)

NGUI 3 Support / Looks like Unity 5.6 broke atlas generation
« on: May 05, 2017, 01:33:22 AM »
Fairly easy to reproduce, just regenerate the atlas over and over again (e.g. by making small changes to one of the bitmaps included into it and invoking the add to atlas context option) - random sprites have a chance of getting corrupted boundaries and dimensions - for example, a number of 48x48px .png files which were previously correctly imported into an atlas turned into 30x30px sprites and 23x16px sprites in some cases. Not sure what triggers that, maybe 5.6 changed something NGUI relied on to determine image dimensions?

Simple example: let's say you have a GameObject in your DontDestroyOnLoad hierarchy which you move to various world-space positions you want a UI widget to be anchored to. Internally, that case works like this: a scene-rendering camera is retrieved and used for world to screen pos conversion of position of that GameObject to position of the anchored widget. Example in motion (line endpoints and big white marker are all done this way).

^ WebM, click to open

There is one case where current implementation fails, though, and that's when your game has an "immortal" (DontDestroyOnLoad) UI hierarchy travelling trough multiple scenes, each scene with it's own scene camera. Scene camera used for anchor conversions is fetched on Awake of a widget once, so that camera reference goes null immediately after you load another scene, permanently disabling world space anchoring on a widget.

It's pretty simple to fix, though. Just add this to the top of UIRect.GetLocalPos method:
To this:

  1. protected Vector3 GetLocalPos (AnchorPoint ac, Transform trans)
  2. {
  3.     if (ac.targetCam == null) ac.targetCam = Camera.main;
  4.     ...

With this, UIRect will recover the target camera once it becomes null. Maybe there is more elegant way of doing that, but this fixed our issues with world space anchored widgets becoming inert on every scene load. Might be worth adding to the next patch. :)

Thanks, that helps! Enforcing parenting (dependent elements are always under referenced elements) and forcing anchor update from the panel in the right order does the trick, allowing me to never use OnUpdate anchors, pushing updates only on frames where I actually change UI content.

Let's say I have a label which grows vertically to fit texts of different length - for example, item descriptions. Anchored to the label, there is a widget offset by, say, -24 on the left, 24 on the right, 24 on the top, -24 on the bottom. In turn, anchored to the top, left and right (never bottom) of that widget are various secondary child elements, like a clamped header with an item name, item preview images, fixed-size lines with item stats and so on. To illustrate, here is how this looks:

Game camera view:

Scene view of the primary label and sole widget directly parented to it:

Scene view of the secondary elements anchored to the boundary widget:

There is a small problem with that sort of setup. While it works like you see on the gifs in Edit mode, Play mode is a different story. Unless you make set every single anchor to OnUpdate refresh mode (which you definitely don't want to do if you want to avoid GC from anchoring operations generated every frame), there is no way to actually force a refresh on all those elements after you change the text on that label. I've tried a lot of methods exposed by NGUI UIPanel and looked at how on-anchor refreshing is done in UIRect/UIWidget/UIPanel and I think there is no standard way to do that for OnEnable/OnStart anchors.

Please correct me if I'm wrong and actually missed some method on UIPanel or other NGUI class meant to force refresh of all anchored widgets. I went on with an assumption that no such method exists and tried to force it manually, with my own methods. I focused on an attempt to devise a method that would force correctly ordered anchor refresh on every single widget under a certain panel - while forcing an anchoring update of an individual widget is easy, it's not a useful approach, since it would require every anchoring-influencing object to keep explicit references to all anchored dependent objects. I just wanted to call something like panel.ForceAnchorRefresh () from my label, which keeps the UI nicely decoupled. Here is what I got:

  1. public void ForceAnchorRefresh ()
  2. {
  3.     ForceAnchorRefreshRecursive (transform);
  4. }
  6. private void ForceAnchorRefreshRecursive (Transform parent)
  7. {
  8.     UIRect rect = parent.GetComponent<UIRect> ();
  9.     if (rect != null)
  10.         rect.UpdateAnchors ();
  12.     for (int i = 0; i < parent.childCount; ++i)
  13.         ForceAnchorRefreshRecursive (parent.GetChild (i));
  14. }

This works great, with sole exception of cases where widgets influencing other widgets but not being their parents aren't guaranteed to update first. But that's easy to prevent if you structure your UI with strict parenting reflecting anchoring dependencies. Is there anything wrong with this approach, or it's a sound way to force refresh of OnStart/OnEnable anchored widgets after their dependency was resized?

I don't think I'm getting any new behavior in terms of updates firing, it's all the same as it ever was back to oldest versions of Unity, with LateUpdate only firing when you do something in an inspector or drag something in the Scene view.
Here is what I'm encountering - you can see on the gif below how I get a spike every time I move a label:

The spike is not originating at the " || !Application.isPlaying" point, of course - it just allows the content of LateUpdate to execute every single time if you're in the Editor. As you can see here, the time taken by something starting in LateUpdate is a sum of operations on every UIPanel in the scene (I have around 40 of them to avoid redraws on move animations and such):

LateUpdate is not an endpoint where all that time is taken, of course, it's just a limit of how far profiling goes. Can't do a deep profile outside of play mode, Unity 5.5.0 seems to dislike that and crashes, but I'm fairly sure that this bit explains where all the load comes from:

  1. for (int i = 0, imax = list.Count; i < imax; ++i)
  2.     list[i].UpdateSelf();

So, my question is - why is everything updated every LateUpdate, when that's seemingly unnecessary (everything continues to update fine after I removed " || !Application.isPlaying") and triggers a costly panel update every single frame? Am I missing some hidden problem with Unity Editor that makes such a frequent and unfiltered updating of all panels necessary?

To be specific, I'm referring to this piece of code in UIPanel:

  1.         void LateUpdate ()
  2.         {
  3.                 #if UNITY_EDITOR
  4.                 if (mUpdateFrame != Time.frameCount || !Application.isPlaying)
  5.                 #else
  6.                 if (mUpdateFrame != Time.frameCount)
  7.                 #endif
  8.                 {
  9.                     ...

I am getting enormous, 300-400ms long interruptions in Editor window redraws every frame whenever I edit a label or move a UI widget, which is seemingly caused by this snippet above starting the redraw process for every single panel in the whole UI hierarchy if you are using the Editor (!Application.isPlaying case). Not sure why this is necessary - commenting out !Application.isPlaying case and only letting the method to continue if the first condition is satisfied doesn't seem to cause any issues whatsoever - all panels are correctly rebuilt when necessary, but widget editing is no longer triggering lag from whole UI rebuilding. Am I missing something? Is there a reason to redraw whole UI every LateUpdate in the Editor without any additional conditions?

NGUI 3 Support / PSA: WorldToViewportPoint used by NGUI seems to be broken
« on: November 05, 2016, 05:15:30 AM »
Just wanted to give a heads up: Camera.WorldToViewportPoint seems to be returning incorrect results whenever you hold a mouse button when called from certain points in execution order, e.g. from LateUpdate on a script with execution position 0. This might be linked to the bizarre OSX issue you have already encountered and worked around of with Unity 5.4 (reported screen size going wrong whenever mouse is pressed). So far we have reproduced it on two Windows PCs with Unity 5.4.2f1. I'm not yet sure which Unity 5.4 versions beyond 5.4.2f1 it affects, haven't tested the latest patches yet.

The interesting detail about the issue is that only LateUpdate calls to Camera.WorldToViewportPoint seem to return incorrect coordinates - FixedUpdate and Update usually return proper ones (unless we're checking Update on late-executing scripts), even when the mouse is pressed. Might be worth going through NGUI code to check if there are any calls to Camera.WorldToViewportPoint from LateUpdate.

NGUI 3 Support / Re: UITexture randomly gets changed into a UISprite
« on: November 05, 2016, 04:51:53 AM »
Yeah, ideally it should not be the default behaviour, or at the very least it should never happen without a popup window requiring confirmation for replacement. I change this line after every single update to NGUI. :)

So, to confirm: somewhere, NGUI code finds all Camera objects in a scene and then selects the first one with the UI layer visible, and that's the source of the issue, right?

Curious about it because while it wouldn't be an issue for my current scene, that might have implications for scenes with multiple UI hierarchies/cameras.

Pages: [1] 2 3 ... 8