Search Unity

[RELEASED] uDialog: Dialogs, Menus, and Notifications for the Unity UI

Discussion in 'Assets and Asset Store' started by DaceZA, Mar 14, 2016.

  1. bourriquet

    bourriquet

    Joined:
    Jul 17, 2012
    Posts:
    181
    Hi and thanks for the plugin.
    I would like to have a custom dialog that has additional parameters to be set while building it by code. Say for example a 2nd icon.
    What would be the good way to do this with your plugin? Is there something built in to help this type of customization?
     
  2. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi there,

    I'd say that there are two approaches you could use to handle this sort of thing:

    a) You could create a copy of an existing uDialog prefab, and modify it so that it includes the additional items (such as your second icon). Then, you'd create an instance of that prefab instead of the default uDialog ones (you can use the uDialog_Utilities.InstantiatePrefab() helper if you'd like).
    You'd need to add code to customize these additional items, so it'd probably be helpful to add references to them so you can access them easily in code (you'd need to add a custom component to keep track of these).

    b) This approach is a bit simpler, but would require you to take full control of all of the content of the uDialog:
    You can create the content of your uDialog from scratch in whatever way you prefer, and then replace the existing content of the uDialog with uDialog.SetContent(RectTransform newContent). You wouldn't be able to customize this content with the existing uDialog functionality, but you can modify it both before and after setting it as the content of the uDialog as you would any other UI content.
     
  3. bourriquet

    bourriquet

    Joined:
    Jul 17, 2012
    Posts:
    181
    I am going for the first approach, as this doesn't seem to be the point of SetContent.
    But I see 2 options for the 1st approach to add the custom parameters:
    • Inheriting uDialog
    • Adding another component next to the uDialog
    I felt like the inheritance was the best design, so I tried it.
    I added a new type MyCustomDialog : uDialog, with the additional parameter and a SetCustom2ndIcon function. I then had to add a custom editor script for this new type that inherits uDialog_Editor, and draws the new property on top of the base GUI. Then I needed to add a creation menu button because adding the MyCustomDialog manually loses all the objects references.
    (I also added a generic NewDialog<DialogType> function so you can call NewDialog<MyCustomDialog> and get a MyCustomDialog object so you can call SetCustom2ndIcon on it using the same nice chain way you have with uDialog, but that's just sugar)

    In the end that was too much trouble so I went for the 2nd option. I just added a MyCustomDialog : MonoBehavior component next to the uDialog, and I do .GetComponent<MyCustomDialog>().SetCustom2ndIcon() to set it in the chain code. That's much easier, no need for editor code.

    Any idea on all that?
    Maybe a possible improvement of the plugin would be to prepare uDialog for easy inheritance, although I don't know how important that is for most users.
     
  4. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    a) The references used by uDialog are stored in the prefab, so if you were to inherit from uDialog, it would be necessary to replace the original uDialog component with a new one, and then set the references again unfortunately.

    b) However, I think the 2nd option that you've gone for is better - and generally fits within Unity's component composition approach. For most of my products, I'd normally recommend this approach over inheritance, where possible - at least, when working with Unity.
     
  5. bourriquet

    bourriquet

    Joined:
    Jul 17, 2012
    Posts:
    181
    I think there is a problem with SetIcon(Sprite).
    There is a
    void SetIcon(Sprite) 
    method in the uDialog class, additional to the
    uDialog SetIcon(Sprite)
    uDialog_Fluent extension method.
    The original void one is taken in priority, making it impossible to use SetIcon in the Fluent style.
    Nothing crazy problematic, but figured I'd let you know.
     
  6. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Oops, I see what you mean. Thanks for pointing it out :)

    I've renamed uDialog's method to 'SetIconSprite', and marked it as 'internal' so that it should be inaccessible outside of the UI.Dialogs namespace. The fluent method remains more-or-less unchanged, so you should be able to use it properly now.

    I'll send you a link to the update shortly.
     
  7. dsb7

    dsb7

    Joined:
    Jan 19, 2018
    Posts:
    7
    When using the Wrap Content functionality, are the standard dialog buttons still available? (either through the editor or through code - AddButton())
     
  8. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi there!

    Yes, they are - all regular uDialog functionality is still available when wrapping content. You can see this in action in the 'Content Window' example here: http://digital-legacy.co.za/Static/uDialog/Demo/

    Note: by default, wrapped content will be below the rest of the dialog content; if you'd like to change this, you can create a copy of a uDialog prefab ['UI/uDialog/Resources/Prefabs/uDialog_Default' is the default for regular dialogs], adjust the positioning of the elements as you require, and then use that prefab instead when instantiating a new uDialog, e.g.

    Code (CSharp):
    1. uDialog.NewDialog("MyPrefabPath")
    2.        .SetContent(myContentTransform)
    3.        .AddButton("Close", (d) => d.Close());
    4.  
    If you do the above, make sure that your new prefab is stored in a Resources/Prefabs folder (any will do, it doesn't have to be the one in the uDialog folder) e.g. "Resources/Prefabs/MyPrefabPath"

    If you're interested, here is the code used by the 'Content Window' example:


    Code (CSharp):
    1.      
    2.         public void ShowContentWindowExample()
    3.         {
    4.             // We could use contentWindowContent directly here, but it's best in this case if we clone it instead
    5.             // (that way, we can use it over and over again for this example)
    6.             var content = Instantiate(contentWindowContent) as RectTransform;
    7.             uDialog_Utilities.FixInstanceTransform(contentWindowContent, content);
    8.  
    9.             var window = uDialog.NewDialog()
    10.                                 .SetThemeImageSet(ImageSet)
    11.                                 .SetColorScheme(ColorScheme)
    12.                                 .SetOutlineMode(OutlineMode)
    13.                                 .SetContentText(
    14.                                     "uDialog.SetContent(RectTransform transform) allows you to place existing GUI elements within a uDialog window. "
    15.                                     + "In this example, the nested uDialog has been created manually, in advance, and then set as the content of this dynamically created window."
    16.                                     )
    17.                                 .SetContentFontSize(10, 22)
    18.                                 .SetButtonFontSize(10, 14)
    19.                                 .SetButtonSize(150, 64)
    20.                                 .SetTitleText("Content Window")
    21.                                 .SetDimensions(640, 480)
    22.                                 .SetAllowDragging(true, false)
    23.                                 .SetResizeable()
    24.                                 .SetMinSize(320, 240)
    25.                                 .SetContent(content, 400)
    26.                                 .SetDestroyAfterClose(true)
    27.                                 .SetCloseWhenAnyButtonClicked(false)
    28.                                 .SetShowTitleMinimizeButton(true)
    29.                                 .AddToTaskBar(TaskBar)
    30.                                 .SetParent(DialogContainer);                              
    31.            
    32.             window.AddButton("Hide this message",
    33.                 () =>
    34.                 {
    35.                     window.SetContentText("");
    36.                     window.SetIcon(eIconType.None);
    37.                     window.SetShowButtons(false);
    38.                 });          
    39.         }
    I hope this helps!
     
  9. dsb7

    dsb7

    Joined:
    Jan 19, 2018
    Posts:
    7
    Awesome - thanks!
     
  10. ashlar640

    ashlar640

    Joined:
    Nov 1, 2018
    Posts:
    4
    Hello,

    I just bought uDialog and I have a question. On my dialog I have a OK button that I made and it for some reason is always disabled. I noticed in the Button properties in the Inspector the Interactable checkbox is unchecked. If I check it it becomes unchecked again after I run my game. Do you know why this is happening?

    BTW...I wish you had your own message boards...


    Edit:
    I am going to answer my own question. My dialog had Interactable unchecked which was causing my button's Interactable to become unchecked. So checking my dialog's Interactable fixed my issue. I am gonna thank myself now and pat myself on the back.
     
    Last edited: Jan 2, 2019
  11. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi Ashlar640,

    I'm glad you managed to sort it out! :)
     
  12. Raeion

    Raeion

    Joined:
    Jul 5, 2016
    Posts:
    38
    Hello, I know this might be a simple fix, but I've tried to hide notifications that appear after few seconds with the default setting ( auto hide ) but it doesn't seem to hide at all. when I do click a notification it hides them ( although the instantiated object is still active ), Once it's truely hidden, I want the next notification to take its place so it doesn't appear under the hidden one. I have also tried to destroy them completely by using the
    uDialog_NotificationPanel.NotificationTemplate.DestroyAfterClose= true
    but it doesn't seem to take effect and nothing gets destroyed, resulting in more notifications popping up below all the " empty hidden notifications"
    I simply want it to work just like the web gl demo you had on the store. the example scene in Unity doesn't do what the web gl demo did either.
    Can you please help me out ?
    Thank you in advance.
     
  13. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi there,

    Sorry to hear that you're having trouble with uDialog.

    I've tried to replicate the issue you're describing, but it appears that in all the versions I test with, the notifications are correctly destroyed after the hide animations are complete. Looking at the code for the hide/destroy process (uDialog.cs line 1136), it looks to me like the only things I can think of off-hand which would stop this process is if the notification object was somehow disabled before reaching the end of the method (which would stop the coroutine from running), or possibly if an exception was thrown somewhere down the line.

    Are you seeing any error messages?

    Which version of Unity are you using? (I've tested this with 5.4.3, 2018.2, and 2019.1 today and all seemed to be fine).

    If I can't replicate the issue, I could try changing the timing code used for this process to use the uDialog_Timer class instead of a coroutine to see if that makes any difference.
     
  14. Raeion

    Raeion

    Joined:
    Jul 5, 2016
    Posts:
    38
    Hello, thank you for replying and keeping it alive. It is wonderful to see good support <3
    For the time being, I skipped the issue by using uDialog.NewNotification() in my custom script and didn't insert the UI> uDialog > Notification Panel - right in the hierarchy
    this has allowed me to enable auto hide and or destroy to suit my needs for now.
    I will get back to you with more details later.
     
  15. Raeion

    Raeion

    Joined:
    Jul 5, 2016
    Posts:
    38
    Hello, I have a new question.

    During my testing, I have implemented a series of notifications to pop up at launch for the first time. I have successfully shown the notifications. I now want to show the content of those notifications in a seperate panel for users to view their notifications whenever and then clear it. sort of like facebook notification panel where it drops down with a list of notifications.
    Now I understand this might not be directly related, but I have no one else to turn to. I'm hoping there is a way to get reference back to all the notifications shown and have them shown in some kind of a list.
    Hope it makes sense.
    Thank you in advance.
    Code (CSharp):
    1. public void OnSendInternalNotification(int notiId)
    2.         {
    3.          
    4.             NotificationFrame.gameObject.SetActive(true);
    5.             foreach (var reminder in _GeneralReminders)
    6.             {
    7.                 var  notification = uDialog.NewNotification();
    8.              
    9.                 notification.ContentText = reminder.notificationContent;
    10.                 string text = notification.ContentText;
    11.                 Debug.Log(reminder.notificationContent);
    12.                 _notificationAmount++;
    13.                 for (int i = 0; i < _notificationAmount; i++)
    14.                   {
    15.                      previewNotificationTxT[i].text = text;
    16.                   }
    17.                 #region NotificationSettings
    18.  
    19.                 notification.ColorScheme = "Blue Highlight";
    20.                 notification.gameObject.transform.SetParent(_canvas.transform);
    21.                 notification.UpdateDisplay();
    22.                 notification.gameObject.transform.position = SpawnPointObject.gameObject.transform.position;
    23.                 notification.gameObject.transform.SetParent(SpawnPointObject.transform);
    24.                 notification.SetDimensions(250, 100);
    25.                 notification.AutoClose = true;
    26.                 notification.AutoCloseTime = 9f;
    27.        
    28.  
    29.                 #endregion
    30.             }
    31.            // notification.ContentText = _BookingNotifications[notiId].notificationText;
    32.          
    33.          
    34.  
    35.             notificationAmountTxT.text = _notificationAmount.ToString();
    36.         }
    As you can see, with the code above, I can show all the different notifications from my _GeneralReminders but I can't link it to a text to hold the strings.
     
  16. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi there,

    I think I understand what you're going for. Off the top of my head, I can think of two approaches for this:

    1.
    a) Set 'Destroy After Close' to false for the notification (either on the template, or in your code)
    b) You can then get a reference to all notifications that have been shown by iterating through all uDialog instances contained by the parent (normally this would be a uDialog_NotificationPanel, but it looks like in your code this would be 'SpawnPointObject'), so something like this:
    Code (CSharp):
    1. // Get all 'uDialog' components in gameobjects that are children of 'SpawnPointObject', including inactive objects
    2. uDialog[] notifications = SpawnPointObject.GetComponentsInChildren<uDialog>(true);
    3.  
    4. // you can then access the 'ContentText' property of each object, e.g.
    5. foreach(var notification in notifications)
    6. {
    7.      Debug.Log(notification.ContentText);
    8. }
    You could also maintain a property of type List<uDialog> in your code and add your notification instances to it when you show notifications rather than using GetComponentsInChildren() to find the instances (that'd be a little better for performance) - List<> tutorial (if you're unfamiliar with generic lists)

    2. Alternatively, you could store a list of strings (or structs, if you need more information), and add to it whenever you show a notification - this could be similar to your _GeneralReminders collection (or, perhaps, you could use the _GeneralReminders collection directly if you aren't removing records from it). Then you could use the strings directly from the collection, bypassing uDialog entirely. This would probably be the better solution performance-wise, as keeping a lot of uDialog instances in the scene (even if they are inactive) just to read some of their properties (ContentText) is a bit memory-inefficient.

    I hope this helps!
     
  17. UnusAutomationSystems

    UnusAutomationSystems

    Joined:
    Jul 15, 2019
    Posts:
    49
    Hello

    I am going to buy
    DatePicker for UnityUI
    but there is not any forum thread for Q & A.

    Can you give me a link for forum thread if it is available?
    if not, is it possible to create forum thread for DatePicker for UnityUI asset?
     
  18. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    UnusAutomationSystems likes this.