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. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174

    uDialog
    is a complete dialog solution for the Unity UI.

    With uDialog, you can:
    - Create and customize message boxes with optional titles, icons, and buttons
    - Create and customize menus
    - Create notification messages
    - Wrap UI content in themed, draggable, and resizeable windows!

    WebGL Demo
    Asset Store Page

    Features:
    ▶ Full source code included
    ▶ Show message boxes, confirm dialogs, menus, and content windows
    ▶ Use built-in themes and color schemes, or build your own
    ▶ Easy to set up and use in the editor
    ▶ Easy to create and customize dynamically via code (using a Fluent API)
    ▶ Add buttons easily in the editor, or using code
    ▶ Show notification stacks with message queueing
    ▶ Various show and close animations available
    ▶ Dialogs can be draggable, via the title or via the entire dialog/window
    ▶ Dialogs can be resizeable, from any direction(s) you choose
    ▶ Optional focus on click or on mouse over
    ▶ Play audio when dialogs are shown, closed, or when any of their buttons are clicked (with optional AudioMixerGroup integration)


    API Documentation
    User Guide
    WebGL Demo

    Screenshots:

    uDialog v1.00 is now available on the Unity Asset Store!

    Please feel free to post any questions here!
     
    Last edited: Apr 20, 2016
  2. dkillins

    dkillins

    Joined:
    Apr 20, 2016
    Posts:
    4
    How do you explicitly set the size of the buttons? When changing from Portrait to Landscape the dialog and buttons need to be resized.
     
  3. DaceZA

    DaceZA

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

    The buttons are created based on a child GameObject which is used as a template, so you'll need to change the dimensions of that template. The template can be accessed through the uDialog objects GO_ButtonTemplate field.

    Here is a short example of how the buttons size can be changed when the RectTransform dimensions change:
    (this MonoBehaviour is attached directly to the uDialog)

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using UI.Dialogs;
    4.  
    5. [ExecuteInEditMode, RequireComponent(typeof(uDialog))]
    6. public class uDialog_ResizeButtonsExample : MonoBehaviour
    7. {
    8.     uDialog uDialog = null;  
    9.  
    10.     void OnRectTransformDimensionsChange()
    11.     {
    12.         if(uDialog == null) uDialog = this.GetComponent<uDialog>();
    13.  
    14.         var buttonTemplate = uDialog.GO_ButtonTemplate;
    15.         var buttonTemplateLayoutElement = buttonTemplate.GetComponent<LayoutElement>();
    16.  
    17.         buttonTemplateLayoutElement.preferredHeight = 64;
    18.         buttonTemplateLayoutElement.preferredWidth = 256;
    19.  
    20.         // This function forces the buttons to be rebuilt using the updated template
    21.         uDialog.ForceButtonUpdate();
    22.     }
    23. }
    Please note that the uDialog Menu prefab approach uses a slightly different - the buttons are instead in a VerticalLayoutGroup with expand child width/height set to true, so if you want to explicitly set the dimensions of those buttons, then you will need to first disable the child width/height expand value like so:

    Code (CSharp):
    1. var layoutGroup = uDialog.GO_ButtonContainer.GetComponent<VerticalLayoutGroup>();
    2. layoutGroup.childForceExpandHeight = false;
    3. layoutGroup.childForceExpandWidth = false;
    I hope this helps!
     
  4. dkillins

    dkillins

    Joined:
    Apr 20, 2016
    Posts:
    4
    Thanks for the quick reply. Modifiying buttonTemplateLayoutElement.preferredHeight and buttonTemplateLayoutElement.preferredWidth works when displayed in the Unity Editor, but does not change the button size when applied to a physical Android device. Any ideas?
     
  5. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi,

    It looks like you've found a bug , sorry - I'll get to work on releasing a fixed version ASAP.

    In the meantime, I do have a working stop-gap solution - if you call ForceButtonUpdate(), then wait a frame and call it again, it seems to work fine.

    Here's a slight modification to the earlier example, where I've added two buttons, each one set up to call SetButtonSize() - one passing a true value, one false. I've tested this on android and it worked for me.

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4. using UI.Dialogs;
    5.  
    6. [ExecuteInEditMode, RequireComponent(typeof(uDialog))]
    7. public class uDialog_ResizeButtonsExample : MonoBehaviour
    8. {
    9.     uDialog uDialog = null;
    10.  
    11.     public void SetButtonSize(bool alt)
    12.     {
    13.         if (uDialog == null) uDialog = this.GetComponent<uDialog>();    
    14.  
    15.         var buttonTemplate = uDialog.GO_ButtonTemplate;
    16.         var buttonTemplateLayoutElement = buttonTemplate.GetComponent<LayoutElement>();
    17.  
    18.         if (alt)
    19.         {
    20.             buttonTemplateLayoutElement.preferredHeight = 48;
    21.             buttonTemplateLayoutElement.preferredWidth = 160;
    22.         }
    23.         else
    24.         {
    25.             buttonTemplateLayoutElement.preferredHeight = 32;
    26.             buttonTemplateLayoutElement.preferredWidth = 128;
    27.         }
    28.  
    29.         uDialog.ForceButtonUpdate();
    30.         StartCoroutine(DelayedButtonUpdate());
    31.     }
    32.  
    33.     IEnumerator DelayedButtonUpdate()
    34.     {
    35.         // wait one frame
    36.         yield return null;
    37.         uDialog.ForceButtonUpdate();
    38.     }
    39. }
    40.  
    If you'd like, if you send an e-mail to my support address (support@digital-legacy.co.za) I can send you the updated version directly as soon as it is available (so that you don't have to wait for it to be approved on the Asset Store). (or alternatively you could PM me your e-mail address)

    Edit: I've managed to fix the issue - I'll send it through to you as soon as I have your e-mail address.
     
    Last edited: Apr 20, 2016
  6. dkillins

    dkillins

    Joined:
    Apr 20, 2016
    Posts:
    4
    Thank you. I've sent email.
     
  7. DaceZA

    DaceZA

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

    I haven't received your e-mail yet (sometimes my e-mail service can be a bit slow), so I've PM'd you a download link you can use.

    Hope it helps :)
     
  8. juyanith

    juyanith

    Joined:
    Jan 22, 2015
    Posts:
    8
    I am trying to figure out how to implement a dialog window that can be minimized (or maximized) but not closed. I was thinking that maybe I could do something with Event_On_Close but I'm not sure how I would "cancel" the close and minimize instead. Perhaps I'm going about this the wrong way?
     
  9. DaceZA

    DaceZA

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

    Are you attempting to a) prevent the close entirely (i.e. prevent default close behavior and handle the minimize yourself?) or b) allow uDialog to close, but still be able to be shown again?

    If b) then it should be fairly easy. By default, uDialog instances are not destroyed after being closed - just made inactive (although this behavior can be changed using the uDialog.DestroyAfterClose property). As such they can be shown again at any time using the uDialog.Show() method.

    If a) then it is slightly more complicated, but shouldn't be too difficult.
    • If the uDialog has been added to the scene as a prefab, then you simply need to modify the uDialog object slightly.
      Within the uDialog object you will find Dialog / Container / Title / Close Button. This is the uDialog close button itself - its Button component has an onClick event which calls uDialog.Close(). If you change this event-trigger, you can have it fire any event of your choice instead of closing the dialog. You can also change it's appearance so that it looks more like a minimize button if you wish.

    • If the uDialog has been instantiated via code, then the best course of action is to duplicate the uDialog_Default prefab (UI/Resources/Prefabs/) , modify its close button (as above), and then instruct uDialog to use that prefab when instantiating the object e.g.

      Code (CSharp):
      1. var dialog = uDialog.NewDialog("myNewPrefab");

    Hope this helps!

    PS: I'll also try and make sure that the next uDialog update contains a built-in minimize button :)
     
  10. juyanith

    juyanith

    Joined:
    Jan 22, 2015
    Posts:
    8
    Thank you for your quick reply. I was really trying option a) although there is really nothing wrong with option b) as long as I make it easy for the user to find the dialog again. I may try that before I spend too much time on it. I think it would be awesome if you added minimize support to uDialog!
     
  11. juyanith

    juyanith

    Joined:
    Jan 22, 2015
    Posts:
    8
    While I'm making feature requests I have another one. I'd like to be able to add an OnClick event to notifications so that I can allow the user to do something based on the notification.
     
  12. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Sure, I'll add that to the todo list :)

    Edit: Just had a thought - are you using the default notification behavior (close when clicked)? If so, you can trigger your code with the notifications Event_OnClose. I'll still be adding an onClick event, but if this does work for you, at least you won't have to wait :)
     
    Last edited: Apr 29, 2016
  13. juyanith

    juyanith

    Joined:
    Jan 22, 2015
    Posts:
    8
    Thanks! I thought about that but wouldn't the onClose event fire if the notification timed out? In my case I wouldn't want it to execute unless the user clicked on the notification.
     
  14. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Ah, yes, that is a good point :)
     
  15. DaceZA

    DaceZA

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

    I've added an onClick event to uDialog for you. I've PM'd you a download link.

    You can add onClick events with:

    Code (CSharp):
    1. uDialog.AddOnClickEvent()
    As with the other uDialog events, this method accepts either a simple Action e.g. () => { someAction(); } or an Action<uDialog> e.g. (u) => { u.SomeUDialogMethod(); } (where u is the uDialog instance for which the event belongs to).

    I also fixed a minor bug in uDialog_NotificationPanel.AddNotification() where one of the overloads didn't return a reference to the notification object. With that fixed, you can now add onClick events to the returned notification object.

    I haven't done the minimize button just yet, but it is on my list :)

    Hope this helps!

    Regards,
    Dace
     
  16. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    v1.03 has been submitted to the Unity Asset Store!

    It should be available in the next few days.

    v1.03 Changelist:
    - Added uDialog_TaskBar (essentially, an optional Task Bar you can use to show/focus/minimize your uDialog windows)
    - Added the ability to "minimize" a uDialog (to the Task Bar)
    - Fixed a few bugs related to Canvas Scalers

    The updated demo is live @ http://www.digital-legacy.co.za/Static/uDialog/Demo/

    Using the new Task Bar:

    The Task Bar can be added to the scene as with other uDialog prefabs - the prefab is located GameObject menu @ UI/uDialog/uDialog Task Bar.

    You can attach uDialog instances to the Task Bar in the editor by adding them to its Tasks list. You can add them at runtime by calling either the uDialog method AddToTaskBar(taskbar) or the uDialog_TaskBar method AddTask(dialog).

    By default, a uDialog Task Bar will behave in the following manner:
    - Clicking on a minimized task will show it and focus it,
    - Clicking an active but non-focused task will focus it
    - Clicking on an active and focused task will minimize it

    You can change remove the second behaviour by clearing the Focus Dialog When Clicked property.

    You can also choose whether or not to show: Active Tasks, The Focused Task, and Inactive Tasks through their respective properties on the uDialog_TaskBar.

    Styling the task bar:
    Unlike uDialog instances, the task bar must be styled manually (note: this may change in later versions). Any graphical styles/sizes/etc. you set for the task bar will be applied as you set them, and are not in danger of being overwritten by uDialog themes.

    The uDialog task bar provides three hidden task templates - one for each possible task state. Modify these templates as you choose to adjust how the resulting tasks will look at runtime.

    By default, the task bar uses a HorizontalLayoutGroup to position the tasks, but you can replace this with any layout group of your choice.

    Enjoy! Please let me know if you have any issues or other feedback!
     
    Last edited: May 2, 2016
  17. juyanith

    juyanith

    Joined:
    Jan 22, 2015
    Posts:
    8
    Thank you for the updates! I will try them out as soon as I get a chance.
     
  18. jesska47

    jesska47

    Joined:
    Mar 20, 2014
    Posts:
    7
    Hello,

    I have just started using this asset, and am not a very experienced coder. Currently I am trying to create a NewDialog (from a uDialog prefab I have created, called "uDialog_DialoguePanel") when my player enters a trigger.

    In my controller script, I have this code:
    Code (CSharp):
    1. using UnityEngine;
    2. using UI.Dialogs;
    3. using System.Collections;
    4.  
    5. public class TutorialController : MonoBehaviour {
    6.  
    7.     public void ShowSteveIntro ()
    8.     {
    9.         uDialog.NewDialog("uDialog_DialoguePanel")
    10.                .SetTitleText("S.T.E.V.3")
    11.                .SetContentText("Hello? Who's there?");
    12.     }
    13. }
    And then I have a script on my trigger that says:
    Code (CSharp):
    1. //Reference to TutorialController.cs
    2.     TutorialController tutorialController;
    3.  
    4.     void Start ()
    5.     {
    6.         tutorialController = FindObjectOfType<TutorialController>();
    7.     }
    8.  
    9.     public void OnTriggerEnter(Collider _other)
    10.     {
    11.         if(_other.tag == "Player")
    12.         {
    13.             Debug.Log("Trigger entered!");
    14.  
    15.             //Show SteveIntro dialogue
    16.             tutorialController.ShowSteveIntro();
    17.  
    18.             //Destroy trigger
    19.             DestroyObject(gameObject);
    20.         }
    21.     }
    However, when the player enters the specified trigger, I get a the error, NullReferenceException: Object reference not set to an instance of an object SteveIntroTrigger.OnTriggerEnter. This is referring to the line in the second script, which reads: tutorialController.ShowSteveIntro();

    I feel like this may be a simple mistake, but I cannot figure it out. Any help would be greatly appreciated, thank you so much!

    -Jess
     
  19. DaceZA

    DaceZA

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

    If the NullReferenceException is referring to this line:
    tutorialController.ShowSteveIntro();

    It seems likely that the 'tutorialController' variable hasn't been populated - perhaps it was not found by by FindObjectOfType<TutorialController>() ? Are you sure that there is a TutorialController present in your scene? (FindObjectOfType will return null if there isn't). You can test to see if FindObjectOfType found a value by adding the following line after FindObjectOfType:

    Code (CSharp):
    1. void Start()
    2. {
    3.      tutorialController = FindObjectOfType<TutorialController>();
    4.      Debug.Log("tutorialController value = "  + tutorialController);
    5. }
    If this outputs "tutorialController value = null" to the console, then you'll know that the TutorialController object was not found.

    As an alternative to FindObjectOfType, I'd recommend perhaps trying to manually assign the tutorialController variable by a) Making it public, and then b) assigning it a value via the script's inspector (public class members are generally visible directly in the editor, if you have a GameObject with a TutorialController component, you can then just drag that object from the hierarchy into the script's inspector to assign the reference directly). However, FindObjectOfType should still work fine provided that there is a GameObject in the scene with a TutorialController component.

    Hope this helps!
     
  20. jesska47

    jesska47

    Joined:
    Mar 20, 2014
    Posts:
    7
    Thank you so much! This was the exact problem. Such a silly mistake- I apologize.

    However, the error is gone but the new dialog box is still not appearing. When I play the scene, no new object appears in the hierarchy. I thought it might be because I was using a custom prefab, but even if I tried to call the default uDialog, nothing appears either. I added a Debug.Log here to check if the function was being called and it is:
    Code (CSharp):
    1. public void ShowSteveIntro ()
    2.     {
    3.         uDialog.NewDialog("uDialog_DialoguePanel")
    4.                .SetTitleText("S.T.E.V.3")
    5.                .SetContentText("Hello? Who's there?");
    6.         Debug.Log("New dialogue panel created");
    7.     }
    But nothing on screen. Any ideas?

    Thank you so much for the timely responses!
     
  21. DaceZA

    DaceZA

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

    That's odd, that should be working. Are there any errors in the console log?

    I've just created an empty scene with this MonoBehaviour in t:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UI.Dialogs;
    4.  
    5. public class Test : MonoBehaviour
    6. {
    7.      void Start ()
    8.      {
    9.           uDialog.NewDialog()
    10.                  .SetTitleText("S.T.E.V.3")
    11.                  .SetContentText("Hello? Who's there?");
    12.      }
    13. }
    And the dialog appeared as expected - naturally I don't have your prefab to test with, but if you tried it without using a custom prefab as well then I can't think of a reason off-hand why it wouldn't have worked - perhaps you could send me a zipped copy of the project so I can try debugging it? (If you can, please e-mail it to support@digital-legacy.co.za).

    If you do, I'll be sure to have a look at it first thing in the morning (sorry, it's 2AM here :))
     
  22. jesska47

    jesska47

    Joined:
    Mar 20, 2014
    Posts:
    7
    Hey Kyle!

    Currently I am trying to code a dialog box with a custom icon, and I am a bit confused on how to do so. I have my icon saved in the same folder as the default ones, and it is named "Icon_Countdown". When creating a new dialog box through script with a custom icon, would I use .SetIcon(eIconType.Custom)? If so, how would I specify what custom icon to call?

    Thanks again for any help you can provide!
     
  23. DaceZA

    DaceZA

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

    In addition to the overload which accepts the icon type (eIconType), the SetIcon method also has an overload which accepts a unity Sprite object, so in code you would have to do something like this:

    Code (CSharp):
    1.  // the icon must be located somewhere within a Resources folder if loaded this way, e.g.
    2. // Resources/Icons/MyIcon.png (the default icons are not located within a Resources folder)
    3. var sprite = Resources.Load<Sprite>("Icons/MyIcon"); // the file extension is not required
    4. dialog.SetIcon(sprite);
    5.  
    6. // If you'd like, uDialog also provides a method which can be used to load resources which
    7. // caches them (useful for performance if you'll be using the  same icon/etc.
    8. // more than once)
    9. var sprite = uDialog_Utilities.LoadResource<Sprite>("Icons/MyIcon");
    10. dialog.SetIcon(sprite);
    11.  
    12. // Alternatively you can create a public Sprite member on your MonoBehaviour and assign it
    13. // directly through the editor e.g:
    14. public class CustomIconTest : MonoBehaviour
    15. {
    16.      public Sprite mySprite = null; // set this via the inspector
    17.  
    18.      void ShowDialog()
    19.      {
    20.           uDialog.NewDialog()
    21.                  .SetIcon(mySprite);
    22.                  // etc.
    23.      }
    24. }
     
  24. jesska47

    jesska47

    Joined:
    Mar 20, 2014
    Posts:
    7
    Fantastic. I'll give this a shot.

    Also, another thing I've noticed. Sometimes when trying to change what text a prefab says (in Viewport > Message > Text) or even what size the text is, when I hit apply to store the changes in the prefab, it will reset back to the previous value. This problem with the text itself was remedied by changing the text in the parent under the U Dialog controls (Content dropdown > Content Text), but since there is no option to set the size of the text here, I'm not sure how to get it to stick, other than setting the text size in code.
     
  25. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi,

    The controls for font, style, size/etc. are all located in the Theme section - this is probably the best way to control the appearance of any text within the dialog (as uDialog will override any changes made directly to the text elements with these values).

    uDialog_Theme.jpg

    Additionally, as the text components use rich text, you can also control the font size using rich text-tags (http://docs.unity3d.com/Manual/StyledText.html)
     
  26. jesska47

    jesska47

    Joined:
    Mar 20, 2014
    Posts:
    7
    Hello again Kyle!

    I'm wondering if you could help me with a bit of a bump I've run into.

    I'm working on a tutorial system, and have a series of prefabs that fill up the entire screen with text and an image that trigger one right after the other when you click. I am trying to get time to freeze in the game so the player cannot move or look around while the panels are on screen. I attached a picture to show you what it looks like in game.

    Some of my code looks like this:
    Code (CSharp):
    1. //Player approaches Teleporter -> series of images appear
    2.     public void ShowCountdown()
    3.     {
    4.         dialog = uDialog.NewDialog("uDialog_CountdownPanel", mainCanvasTransform)
    5.                         .AddOnClickEvent(() => ShowLabTeleporter());
    6.     }
    7.  
    8.     public void ShowLabTeleporter()
    9.     {
    10.         dialog = uDialog.NewDialog("uDialog_TeleporterPanel", mainCanvasTransform)
    11.                         .AddOnClickEvent(() => ShowModulePlacement());
    12.     }
    13.  
    14.     public void ShowModulePlacement()
    15.     {
    16.         dialog = uDialog.NewDialog("uDialog_ModulePanel", mainCanvasTransform)
    17.                         .AddOnClickEvent(() => ShowForceField());
    18.     }
    And etc. If I add Time.timeScale = 0 in my ShowCountdown() function time freezes just fine, the problem is figuring out where to put Time.timeScale = 1 to unfreeze the time. I considered doing the Queue method, as putting
    Time.timeScale = 0 in ShowConversation() and Time.timeScale = 1 in NextConversationLine() works perfectly. However, I want to be able to access these panels at any time in the form of a menu that players can look at if they want to read any part of the tutorial again, so it seemed to make sense to have each one as prefabs.

    Any ideas as to how I can get timeScale to work with the format of the code I have now? As always, thank you so much for your help. Your asset is working wonderfully and is really becoming a great addition to our game.

    Best,
    Jess
     

    Attached Files:

  27. DaceZA

    DaceZA

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

    If you want to integrate this into the Prefab so that you don't have to change anything in your scene or scene code, then this is how I would do it:

    1. Create a new MonoBehaviour (I'll call it uDialog_PauseGame although you can call it whatever you like)
    2. Add the uDialog_PauseGame component to your prefab
    3. Then code the component as follows:
    Code (CSharp):
    1. using UnityEngine;
    2. using UI.Dialogs;
    3.  
    4. [RequireComponent(typeof(uDialog))]
    5. class uDialog_PauseGame : MonoBehaviour
    6. {
    7.     void Awake()
    8.     {
    9.         var dialog = this.GetComponent<uDialog>();
    10.  
    11.         dialog.AddOnShowEvent(() => { Time.timeScale = 0; });
    12.         dialog.AddOnCloseEvent(() => { Time.timeScale = 1; });
    13.     }  
    14. }
    This component will then locate the uDialog component and add OnShow/OnClose events which manipulate the timescale as you need. Because this will be attached to the prefab, there should be no need to make any changes to your existing code.

    One thing to beware of here though is that if multiple instances of this prefab are active at once, then closing any one of them would return the timescale to 1. If that is potentially a problem, then perhaps use this code instead:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using UI.Dialogs;
    5.  
    6. [RequireComponent(typeof(uDialog))]
    7. class uDialog_PauseGame : MonoBehaviour
    8. {
    9.     // keep a static list of all active instances
    10.     static List<uDialog_PauseGame> instances = new List<uDialog_PauseGame>();  
    11.  
    12.     void Awake()
    13.     {
    14.         var dialog = this.GetComponent<uDialog>();
    15.  
    16.         dialog.AddOnShowEvent(() =>
    17.         {
    18.             Time.timeScale = 0;
    19.  
    20.             if(!instances.Contains(this)) instances.Add(this);
    21.         });
    22.  
    23.         dialog.AddOnCloseEvent(() =>
    24.         {
    25.             if(instances.Contains(this)) instances.Remove(this);
    26.            
    27.             // if instances is empty, then there are no longer any active dialogs,
    28.             // we can safely resume the game
    29.             if(!instances.Any()) Time.timeScale = 1;
    30.         });
    31.     }  
    32. }
    Hope this helps!
     
  28. jesska47

    jesska47

    Joined:
    Mar 20, 2014
    Posts:
    7
    Thank you so much! The second one worked.

    Just curious, all the prefabs are named different things, but they are essential the same just with different icons/text. Because of this, does that mean they are technically multiple instances of the same prefab? Because the first script didn't work so wondering if that was the case.
     
  29. DaceZA

    DaceZA

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

    You're welcome :)

    Just curious, all the prefabs are named different things, but they are essential the same just with different icons/text. Because of this, does that mean they are technically multiple instances of the same prefab? Because the first script didn't work so wondering if that was the case.

    Based on the code you provided, it appears that you have single instances of multiple prefabs. (Essentially, yes, you do have multiple instances, just not of the same prefab - unless you call functions like ShowCountdown() etc. more than once). There shouldn't be any problem with this - although seeing as they each appear to be used once-off (at least in the code), there's
    a) no reason to store a reference to them (instead of dialog = new uDialog() - you can just use new uDialog()),
    and b) it's probably best to have them destroy themselves after closing, e.g.:


    Code (CSharp):
    1.     public void ShowCountdown()
    2.     {
    3.          uDialog.NewDialog("uDialog_CountdownPanel", mainCanvasTransform)
    4.                 .AddOnClickEvent(() => ShowLabTeleporter())
    5.                 .SetDestroyAfterClose(true); // *
    6.     }
    Destroying them isn't a big deal, but it will save a (very) small amount of memory/etc.

    * You can also do this directly on the prefab by changing its settings (Misc -> Destroy After Close).

    If you'd prefer to use a single instance, that'd be fine too, although a single instance can only use one prefab - which you'd then edit at runtime using code (like we did with the first script).
     
  30. jesska47

    jesska47

    Joined:
    Mar 20, 2014
    Posts:
    7
    Hey Kyle,

    So I have a panel that I have set to be visible on start. I'm having it Auto Close after five seconds, and on the prefab I set the Event_On Close to uDialog.Show another prefab I have in the scene that is not visible on start. However, this does not work, as the prefab I want to be shown remains inactive after the first panel closes.

    I got around this before (except with the Event_On Click) by triggering the next panels through script, but I am curious to know why the other method does not work?

    Thanks again!
     
  31. DaceZA

    DaceZA

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

    I've just tested this out on a demo scene and it seems to work fine - here's how I set it up:

    uDialog_EventOnClose.png

    Can you compare your settings and see if they match up? (The uDialog.Show method should probably have the 'true' value passed to it by checking the checkbox in the event [this value indicated whether or not the uDialog should trigger any OnShow events it might have]).

    If you're still stuck, then you may need to send me your project again so I can test it.

    Hope this helps!
     
    Last edited: Jun 14, 2016
  32. antsonthetree

    antsonthetree

    Joined:
    May 15, 2015
    Posts:
    102
    Hello. I am trying to understand the content wrapping functions in your example code. I see where you've created a panel in your scene called "Example Content" and that it has a Nested Dialog. And I see in your uDialog_ExampleController where you define a RectTransform called contentWindowContent and then in ShowContentWindowExample you add it with SetContent(content,400).

    What I do not understand is where/how the panel called Example Content ever gets associated to the RectTransform called contentWindowContent. How does SetContent(content,400) know that it needs to add the panel named "Example Content"? What if I were to add a new panel called "Example Content 2"? How would I make the content WindowContent reference that panel instead of the original panel?

    Sorry if these are basic questions. I'm a bit new to this. Thanks
     
    Last edited: Sep 14, 2021
  33. DaceZA

    DaceZA

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

    Thanks for purchasing uDialog!

    The "contentWindowContent" member used in the example controller has been populated in the editor using the Inspector - basically, it was dragged from the Hierarchy window into the field indicated in the screenshot below:

    uDialog_ContentWindow.jpg

    This is usually the easiest and way to populate fields like this, however, it doesn't matter how you locate the RectTransform, uDialog will still wrap it for you if you need - e.g. you could use
    Code (CSharp):
    1. GameObject.Find("Example Content").GetComponent<RectTransform>()
    to populate the "contentWindowContent" member at runtime, or using any of the various other methods to locate GameObjects and Components in Unity.

    I hope this helps!
     
  34. antsonthetree

    antsonthetree

    Joined:
    May 15, 2015
    Posts:
    102
    Perfect - Thank you for that!
    I was looking all in the other objects and never even thought to look in the controller.
     
  35. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    You're welcome, glad I was able to help :)
     
  36. antsonthetree

    antsonthetree

    Joined:
    May 15, 2015
    Posts:
    102
    Hello - How would I make a dialog that has tabbed content inside it? Would the built in content wrapping functions work for this? Could I dynamically switch out the content in a dialog that is already open?
     
  37. DaceZA

    DaceZA

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

    If you already have an element containing tabs and their content (e.g. using a third party asset such as 'New UI Widgets'), it should work fine if wrapped by uDialog.

    If, however, you'd like to build a custom tab system in a uDialog window then yes, you can dynamically set new content for a uDialog window that is already open (although I'll admit that I haven't tried it yet). After glancing quickly at the code though, I think that you'll probably need to destroy the existing content first - I'll modify the code so that in future this won't be necessary, but for now you should be able to do so by executing the following code:

    Code (CSharp):
    1. var existingContent = uDialog.GO_Content.transform.GetChild(0);
    2. Destroy(existingContent);
    3.  
    4. // now you should be able to set new content
    5. uDialog.SetContent(newContent);
    EDIT: Just a thought, it may be advisable to just disable the existing content rather than destroy it if you'd like the user to be able to see it again, e.g.

    Code (CSharp):
    1. existingContent.gameObject.SetActive(false);
     
    Last edited: Nov 1, 2016
  38. antsonthetree

    antsonthetree

    Joined:
    May 15, 2015
    Posts:
    102
    Thanks again- this is a very nice product. I'd like to make another request if you're going to be in the code anyway. Would it be possible to add a "Default Control" field to the base dialog class? This would be the control that has initial focus when the dialog is first opened.
     
  39. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Sure - I'll add that to my to-do list :)
     
  40. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    I've made the changes as requested, and submitted a new version to the Unity Asset Store - it should be available in the next few days.

    V1.06
    ------------------------------------------------------------------------------
    - You can now force uDialog to focus a button with the new SetFocusedButton()
    method, which accepts either a uDialog_Button object, or a text string which will be used to find a button using its text value.
    This can be called at any time.

    - Additionally, buttons may now be focused as they are created with the new
    'focusThisButton' parameter provided by the uDialog.AddButton() methods

    - SetContent() now has an additional parameter which allows you to specify what should
    be done with any existing content (if anything) [Available options: Nothing, Disable, Destroy]
    ------------------------------------------------------------------------------
     
  41. antsonthetree

    antsonthetree

    Joined:
    May 15, 2015
    Posts:
    102
    I think I found a bug. Calling SetShowAnimation() does not seem to have an effect for anything other than Grow. The only show animation that seem to work is the default "Grow". The following code should fade in a dialog but it only grows it. FYI the fade out function works just fine.

    uDialog.NewDialog()
    .SetShowAnimation(eShowAnimation.FadeIn)
    .SetCloseAnimation(eCloseAnimation.FadeOut)
    .SetModal(true, false)
    .SetCloseWhenAnyButtonClicked(true)
    .AddButton("Yes", () => { Application.Quit(); })
    .AddButton("No", (dialog) => { dialog.Close(); });
     
  42. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Yes, I see that you're right. Sorry about that - it looks like the uDialog selects and begins playing its show animation before the SetShowAnimation() value takes effect.

    I'll look into it and get it fixed asap.

    For now, I do have a quick workaround:

    Code (CSharp):
    1. var dialog = uDialog.NewDialog()
    2.                     .SetShowAnimation(eShowAnimation.FadeIn)
    3.                     .SetCloseAnimation(eCloseAnimation.FadeOut)
    4.                     .SetModal(true, false)
    5.                     .SetCloseWhenAnyButtonClicked(true)
    6.                     .AddButton("Yes", () => { Application.Quit(); })
    7.                     .AddButton("No", (dialog) => { dialog.Close(); })
    8.                     .SetVisibleOnStart(false);
    9.  
    10. dialog.Show();
    EDIT: I've fixed it, I'll be pm'ing you a link where you can download the updated version without waiting for it to hit the Asset Store.
     
    Last edited: Nov 2, 2016
  43. pl_ayground

    pl_ayground

    Joined:
    Dec 17, 2015
    Posts:
    60
    Hi Guys, great work! I really appreciate it. Two questions.

    1) Any plans to add more than a single button color?
    2) I experience a strange blurred area on the button borders - see attachment. Any ideas how to get this fixed?

    Thanks in advance!

    PS. I want to use uDialog on iOS and Android.
     

    Attached Files:

  44. DaceZA

    DaceZA

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

    1) I'll admit that I hadn't considered that - perhaps that is something that I can add in later versions. For now, however, you can still change the button colors directly using code, for example, here is a modified version of the scene's ExampleController.ShowConfirmDialogExample() method:

    (Please note that this requires uDialog v1.06 or higher - I'll send you a download link for the latest version)
    Code (CSharp):
    1. var dialog = uDialog.NewDialog()
    2.                     .SetTitleText("Confirmation Dialog")
    3.                     .SetContentText("Would you like to continue?")
    4.                     .SetThemeImageSet(ImageSet)
    5.                     .SetColorScheme(ColorScheme)
    6.                     .SetOutlineMode(OutlineMode)
    7.                     .SetDimensions(468, 192)
    8.                     .SetModal()
    9.                     .SetShowTitleCloseButton(false)
    10.                     .AddButton("Yes",
    11.                       () => { ShowSimpleDialog("Information",
    12.                              "You clicked <b><color=green>Yes</color></b>.",
    13.                               true, eIconType.Information); })
    14.                     .AddButton("No",
    15.                       () => { ShowSimpleDialog("Information",
    16.                              "You clicked <b><color=red>No</color></b>.",
    17.                               true, eIconType.Information); })
    18.                     .SetCloseWhenAnyButtonClicked(true)
    19.                     .SetDestroyAfterClose(true)
    20.                     .SetParent(DialogContainer);
    21.  
    22. // This waits until the end of the current frame
    23. // (so that the uDialog has finished setting itself up)
    24. uDialog_Timer.DelayedCall(0f, () =>
    25. {
    26.     // find the uDialog_Button_Data object (this is using LINQ, so make sure you have
    27.     // 'using System.Linq;' at the top of your file)
    28.     var yesButton = dialog.Buttons.FirstOrDefault(b => b.ButtonText == "Yes");
    29.  
    30.     // note: if yesButton is null, then this means that the button wasn't found
    31.     // using the text provided
    32.  
    33.     // access the uDialog_Button object, which gives us access to 'buttonComponent'
    34.     // which is a standard Unity button
    35.     yesButton.Button.buttonComponent.colors = new UnityEngine.UI.ColorBlock
    36.     {
    37.         normalColor = new Color(0.05f,0.75f,0.05f),
    38.         highlightedColor = new Color(0.15f,0.85f, 0.15f),
    39.         pressedColor = new Color(0.15f, 0.9f, 0.15f),
    40.         colorMultiplier = 1 // this is important, as the default value is 0
    41.                             // (which will make your button transparent)
    42.     };
    43.  
    44.     // You can also locate the text object and change its properties as follows
    45.     var yesButtonText = yesButton.Button.GetComponentInChildren<UnityEngine.UI.Text>();                
    46.     yesButtonText.color = Color.yellow;
    47.  
    48. }, dialog);
    49.  
    2) I have encountered this problem before - in my case it turned out to be a problem with the quality settings - it didn't show up in the editor, but on platforms such as Android and WebGL I was getting the blurred edges. I'd suggest you take a look at your quality settings and see if anything seems off - in my case, the quality settings defaulted to low quality ("Fastest") which was causing the problem on those platforms (although oddly enough, not on Windows or in the Editor).
    I've been trying to duplicate the issue again, but I haven't had any luck so far, sorry.

    Hope this helps!
     
  45. pl_ayground

    pl_ayground

    Joined:
    Dec 17, 2015
    Posts:
    60
    Thanks for quick reply - I already got #2 fixed on Android by changing "Pixels Per Unit" on Button Texture .
     

    Attached Files:

  46. CplMulder

    CplMulder

    Joined:
    May 12, 2014
    Posts:
    52
    Although I have used uDialog before... I am now having a problem...

    I added uDialog to a new project and the nams of my colour schemes and content text within the example project has been replaced by random numbers..... I have removed the package and re-imported it but been unable to get this sorted...

    uDialog Color Schemes.jpg uDialog Menu.JPG

    *UPDATE - the content of most of the demo dialogs are also replaced with random numbers. I have tried removing the package from my project, manually deleting it from the download folder, re-downloading it from the asset store and then re-importing it.... every time the same result.
     
    Last edited: Nov 28, 2016
  47. DaceZA

    DaceZA

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

    That's very strange. I thought it might be a problem with the .unitypackage file itself, but I've downloaded it from the Asset Store and tested it out and it worked fine - still, it probably won't hurt to try another copy just in case, I'll PM one to you.

    I have had a client experience this issue once before, and unfortunately it does seem to be an issue with Unity serialization - as for why it only seems to affect seemingly random fields on some Unity installations, I don't know. It has affected other packages as well, e.g. https://forum.unity3d.com/threads/unity-5-3-5-yaml-string-corruption.411295/#post-2681449

    If the package I send through to you doesn't help, then I'd recommend trying to reinstall Unity. What version are you using?

    Edit: For some reason the Unity forums won't allow me to send direct messages to you. Can you please send an e-mail to support@digital-legacy.co.za, and I'll e-mail you the link instead.
     
  48. CplMulder

    CplMulder

    Joined:
    May 12, 2014
    Posts:
    52
    Thanks for the prompt reply DaceZA... and apologies for my slow response... been at the day-job

    My Unity version is up to date at 5.4.2.f2

    I could try to re-install Unity although it is a real pain... I couls also try to copy the folders across from a project where uDialog is working fine ...

    I'll send you the e-mail first and we can try the package in raw emailed format but I suspect this is a Unity bug decompressing, decrypting or deserialising assets.

    Thanks a million,

    Chris
    London
     
  49. basmith

    basmith

    Joined:
    Nov 10, 2011
    Posts:
    17
    Hey, just curious: does this have any relation to your XmlLayout product? do they 'integrate'?
     
  50. DaceZA

    DaceZA

    Joined:
    Dec 19, 2014
    Posts:
    174
    Hi,

    Sorry for the delay in getting back to you!

    No, the two products are unrelated. They have some overlapping functionality (e.g. you could build a menu with both uDialog and XmlLayout) but how you get there is very different. While there's nothing stopping you from using both products in one project (e.g. you could have XmlLayout code call uDialog code to show a confirmation dialog or a notification or something like that), I'd normally recommend picking one or the other.

    I hope this helps!