• Responsive UI Pro
  • OnChange mode doesn't work using initially hidden hierarchies and prefabs.

Here is a sample project:

I have included changes to Responsive Container that make it work to some extent, but it is not clean and you see things change sizes over multiple frames. If you comment out the PRISM_MODS define, you will see that it doesn't work at all.

When you press the "Process" button for the first time, you will see that objects show up in the wrong place initially and then over a few frames they resize and end up mostly correct.

It would be nice if the Responsive Container detected that it was being shown (either for the first time or after being hidden) and then calculate the entire hierarchy that is being show so that there is quick and clean transition to the new layout.

I also expect that OnChange would have problems with items that changed size due to content, like a text string, etc.

I prefer not to use OnUpdate mode since we have hundreds of objects and that would slow things down.

If you have any questions, please let me know.

    Here are the changes I have implemented. Things seem to work fairly well, other than a brief flicker (which I think is just a single frame being drawn incorrectly).

    I hope this helps.

    EDIT: You will have to add this to the top of the file: #define PRISM_MODS

      dtappe thanks for the report and demo, I will need a couple of days before being able to work on it, I will keep you posted. Thanks again

        dtappe Do you still get NaNs with these changes?
        I'm merging your edits and adding a few other things. Thanks for your contribution! I will credit you in the plugin and page.

          Anthony,
          It appears that I only get NaNs when when I mix responsive components with rect transform "stretch" or with layout groups.

            I also found that in Update() for OnChange, you need to set to add:

            if (activeChildren.Count != activeChildCount)
                m_bNeedsLateResize = true;

            So that all children also get resized if any sizes changed due to the new child count.

              And I think a helpful addition to Responsive item would be a way to also set the other axis as well. Example:

              If I have a RC for horizontal axis and on a child I have a responsive item set to 20%, it would also be nice to be able to set the vertical size with options:

              1. None (don't modify height) - This is the current action.
              2. Fill - size to same as parent container
              3. a percentage of the the parent container height

              You probably don't actually need #2 since you can get the same result with #3. Not sure if "Preferred" should be an option.

                dtappe Yes, this is what I actually added:

                          // Detects if children have been resized since last frame
                            // or if this container have been resized
                            // or if any children have been activated or deactivated
                            float newFlexibleSpace = CalculateSpaceBetweenItemsY(true, false,
                                out float totalFlexibleSpaceBetweenItemsPercent,
                                out float minContainerHeightNeeded);
                            newFlexibleSpace += CalculateSpaceBetweenItemsX(true, false,
                               out totalFlexibleSpaceBetweenItemsPercent,
                               out minContainerHeightNeeded);
                
                            float newContainerSize = container.GetHeight() + container.GetWidth();
                
                            // detect if active children count has changed since last frame
                            List<RectTransform> activeChildren = GetChildrenFirstDepth(container);
                            bool activeChildrenCountChanged = activeChildren.Count != activeChildCount;
                
                
                            if (lastRefreshItemsSpace != newFlexibleSpace ||
                                lastRefreshContainerSize != newContainerSize ||
                                activeChildrenCountChanged ||
                                needsLateResize)
                            {
                                Resize(activeChildrenCountChanged || needsLateResize);
                                lastRefreshItemsSpace = newFlexibleSpace;
                                lastRefreshContainerSize = newContainerSize;
                            }

                  Anthony float newContainerSize = container.GetHeight() + container.GetWidth();

                  Probably won't happen too often, but this will not always detect a size change. For example, if you started out with a square object and then reduced height by 5 and increased width by 5.

                  You may be better off just keeping both the height and width to do a comparison.

                    FYI, I did just find that

                    float changedVal = CalculateSpaceBetweenItemsY(...)

                    can return a NaN, and that causes continuous refreshes.

                    Taking a quick look at the code, it would return a NaN everytime activeChildCount was 1, and a negative number if it was 0. There may be other ways as well, I didn't look too close.

                      In the sample project I sent, you may want to change LoadFiles() to sometimes return an empty list so you can also test how the control changes. Something like the following is simple, but not very predictive:

                      var oFiles = (UnityEngine.Random.Range(0.0f, 1.0f) < 0.5f) ? new List<string>() : new List<string>()
                      {
                          "File_1",
                          "File_2",
                          "File_3",
                          "File_4",
                          "File_5",
                          "File_6",
                          "File_7",
                      };

                      You will see that as the new "error" row is added, the "Process" button moves up, but is not resized (nor are the other rows.

                        dtappe Can you download the last version of Touch Camera and try again? it should be released today.
                        If you still see that bug, could you prepare me a unitypackage with a sample scene demoing only the issue, without me needing to modify your code or understand the UI ?

                          Anthony,
                          I downloaded 1.0.4 and used it unmodified on the sample project. Here is a video that shows that when the "Process" button is pressed the newly visible objects are not properly contained within their parent containers.

                          I'm not sure how to make the sample project any simpler and still reproduce the issue. You should just be able to run it and press the "process" button to see this particular improper behavior.

                          The sample project is built to demonstrate using common Responsive UI prefabs in different UI layouts, which means the runtime view is different than the inspector view.

                          Here is the updated sample project as a package, with Exoa and TMP removed:

                          It will now toggle the behavior of "Process" between:

                          1. Showing progress bar of files being processed.
                          2. Showing an error that no files were found.

                          NOTE: The following functions still return NaNs when the division counts are 1, making a divide by 0 (Infinity) NaN. Also, if the counts are 0 or percentages are just over 100%, they make a Negative number which would also be bad. I believe these functions should only return >= 0 . This also applies to the "out" variables.

                          • CalculateSpaceBetweenItemsY
                          • CalculateSpaceBetweenItemsX
                          • CalculateFlexibleItemSpaceX
                          • CalculateFlexibleItemSpaceY

                          EDIT: I have some changes I made if you are interested in seeing them, just let me know where I should send them.

                          EDIT 2: I expect one problem may be that when the "Process" button is pressed and the active state of "Directory" and "Process" game object is changed, then parent of "Process" and "Directory" does not detect a change since there is still only 1 child active, but it is a different child than what was active previously. Possibly creating a hash of the active children using their UUID's may let this be detected.

                            I also notice that with the 1.0.4 update, the refresh type gets changed to "Manual", so no updates take place.

                              I'm not trying to offend you, just trying to offer some constructive criticism. You market this as a "Professional" tool, and as such, it needs the effort associated with a professional tool. This means you need to do full testing of changes, including edge cases and various scenarios, as well as regression testing so that you do not break existing projects when you post an update.

                              You have been very responsive to issues, which is VERY MUCH appreciated. You just need to spend more time verifying that changes work as expected and don't break other features or behavior of existing code.

                                dtappe Hi! Thanks for the feedback and new demo.
                                I tested my changes against my demo scenes and didn't notice issues. Now bugs and edge cases will always happen so that's why I opened this support forum and try to fix bugs as quick as possible.

                                Switching the refresh mode to manual on sub containers is a new feature to cascade the Resize() from parent to sub containers as you suggested.

                                I will look into your demo asap.
                                thanks!

                                  Image description

                                  ok so it turns out that this was causing the issue:

                                              ResponsiveContainer parentRC = transform.parent.GetComponent<ResponsiveContainer>();
                                              if (parentRC != null)
                                              {
                                                  refreshType = RefreshType.Manual;
                                              }

                                    Anthony,
                                    I figured that was an issue. Seemed like changing to "Manual" mode behavior should be more of a run time thing and not changing actual configuration. For me, "Manual" should mean that the user is responsible for calling Resize, not some other mode.

                                    Also FYI, on the above video, the button text is also not showing for the blue button. I believe this is also a responsive UI issue.

                                    Sorry for the late response, I somehow missed your post notification.

                                      dtappe, For the missing text for the blue button, I have also seen similar behavior when the prefab instance in the Canvas structure had NaN values saved and was fixed by just reverting all overrides.