Search Unity

[RELEASED] Dynamic Panels - draggable, resizable, dockable and stackable UI panels

Discussion in 'Assets and Asset Store' started by yasirkula, Mar 22, 2018.

  1. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Hi there,

    This asset helps you create dynamic panels using Unity's UI system. These panels can be dragged around, resized, docked to canvas edges or to one another and stacked next to each other as separate tabs.

    Features
    • Supports all canvas modes (Screen Space and World Space)
    • Supports multiple canvases (panels can be moved between canvases by dragging)
    • Has an extensive Scripting API to create/manipulate panels by code
    • Each panel costs 3 additional batches (this number can increase with each tab using a custom icon)
    Asset Store: https://assetstore.unity.com/packages/tools/gui/dynamic-panels-114126
    Also available at: https://github.com/yasirkula/UnityDynamicPanels
    Discord: https://discord.gg/UJJt549AaV
    WebGL demo: http://yasirkula.net/DynamicPanelsDemo/
    GitHub Sponsors ☕




    (used external assets in screenshots: In-game Debug Console and Runtime Inspector & Hierarchy)

    Enjoy!
     
    Last edited: May 31, 2023
    crekri, tar_max, razzraziel and 9 others like this.
  2. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Now available on GitHub! Don't forget to check out the WebGL demo.
     
    Grenqa and demock like this.
  3. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Now available on Asset Store!
     
    Grenqa and demock like this.
  4. Grenqa

    Grenqa

    Joined:
    Jun 6, 2018
    Posts:
    5
    Wow! Thats really cool! Thank you. Maybe i will use this in my project
     
    yasirkula likes this.
  5. dpizzle

    dpizzle

    Joined:
    Feb 2, 2013
    Posts:
    31
    Excellent asset, you should charge for it! I think I found a bug though. Open up the demo scene and try to drag a tab so it sits next to the blue tab. Not possible. Tried several Unity versions, happens both in editor and export. Curiously, your webgl demo does not suffer from this issue, maybe you made some updates since building that.
     
  6. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    That's because the canvas anchor zone obscures that panel's tabs. You can e.g. decrease CanvasLeft's "Canvas Anchor Zone Length" to 15 to eliminate this issue.
     
  7. MaximeTEAMIW

    MaximeTEAMIW

    Joined:
    Jul 9, 2018
    Posts:
    5
    Veryyy wonderfull asset !
    Just one question, is it possible to delete the default free space on Docked Panels ? I won't have free space, only panel. I tried to set Minimum free space to 0 but it keep the free space.
     
  8. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    You can add
    dummyPanel.Detach();
    to the end of the DynamicPanelsCanvas.Start function.
     
  9. MaximeTEAMIW

    MaximeTEAMIW

    Joined:
    Jul 9, 2018
    Posts:
    5
    You are a genious ! Thank for you reply.
     
    yasirkula likes this.
  10. SweatyChair

    SweatyChair

    Joined:
    Feb 15, 2016
    Posts:
    140
    Thanks for the great plugin and it's a good fit into our game!

    There's 2 features we really want and see if you can implement them, please:
    1. Add a default size setting for tab: the tab is first shown as the default size. (e.g. min width 300 and default width 600) (I looked into the code and it seems not as easy as it sounds)
    2. Persistent - all positions and sizes of tabs and tab groups are saved and recovered after each game exit / scene swtich.
     
    Last edited: Nov 19, 2018
  11. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Hi! As you said, there is no default size per tab but it is possible to set the default size of a panel via its FloatingSize property. Tabs detached from that panel will inherit their FloatingSize values from that panel, as well. Currently, for a more complex control over the tabs' sizes, you can register to the PanelNotificationCenter.OnPanelCreated event, check the content of the panel and then set the panel's FloatingSize value accordingly.

    To be able to serialize/deserialize the panels' properties sounds like a useful idea. I'll see what I can do.
     
    SweatyChair likes this.
  12. AGaballo

    AGaballo

    Joined:
    Dec 10, 2018
    Posts:
    3
    Is there a way to customize the pane's tab aspect? For example editing the color, the font etc.
    To give you a real example, I have a round image in my panel and I'd like to keep the transparency so I can see the panel below.
     
    Last edited: Dec 11, 2018
  13. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Are you trying to make only one tab's background transparent? If so, there is currently no way to do that. Otherwise, you can simply make changes to the prefab(s) located inside the Resources subdirectory.
     
  14. AGaballo

    AGaballo

    Joined:
    Dec 10, 2018
    Posts:
    3
    When you say only one tab you mean a single tab in a group or a panel in general? Because probably I only need one of the panel to be transparent but I could live with all the others being the same.
    Another question, is it possible to customize also the tab title bar (e.g changing the color, extending it to the whole panel width)?
     
  15. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    I meant a single tab in a group. The problem with making only a single tab/panel transparent is that, when you detach all tabs from that panel, it will automatically get destroyed. So you should change the DynamicPanel prefab instead.

    Tab title bar prefab is named DynamicPanelTab. You can adjust it as you wish to change the background color or the text color. To extend a tab to the whole panel width, you can enable the DynamicPanel prefab's PanelHeader-Horizontal Layout Group-Child Force Expand Width property.
     
    AGaballo likes this.
  16. AGaballo

    AGaballo

    Joined:
    Dec 10, 2018
    Posts:
    3
    Thank you! One last thing, how do I deactivate a panel from the script API? I tried SetActivate but I get :
    `DynamicPanels.Panel` does not contain a definition for `SetActive`
     
  17. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Simply calling
    panel.gameObject.SetActive
    should do the trick.
     
    AGaballo likes this.
  18. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    @SweatyChair I'd like you to know that, despite my long inactivity, I didn't forget about the persistency feature request and am working on a way to serialize the panels. I've made quite some progress already.
     
    SweatyChair likes this.
  19. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    @SweatyChair I've attached an updated version of the plugin.

    After importing the unitypackage to your project, you should add DynamicPanelsSerialization component to an object in your scene and populate its fields. You shouldn't change the order of the panels in DynamicPanelsSerialization's Panels variable because serialization system depends on this order; the same goes for the canvases, as well.

    Now, you can call the Serialize/Deserialize functions of DynamicPanelsSerialization to save/load the panels via PlayerPrefs. Or, you can use SerializeToArray/DeserializeFromArray functions to save/load the serialized data via a custom medium.

    PROTIP: Simply uncomment the DynamicPanelsSerialization.Update function to quickly test the system.
     

    Attached Files:

  20. SweatyChair

    SweatyChair

    Joined:
    Feb 15, 2016
    Posts:
    140
    Sweet~ I try to test it within these two days when I have time!
    Once it's working, I believe it can be sell for $10+ and people would still love it.
     
  21. mleeShearwater

    mleeShearwater

    Joined:
    Aug 14, 2017
    Posts:
    2
    Hi YasirKula,

    Your work is amazing! Thanks so much for providing this, it's exactly what we need!
    Cheers!
     
    yasirkula likes this.
  22. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Just updated the asset on GitHub: https://github.com/yasirkula/UnityDynamicPanels

    Asset Store version will be updated soon. Here's the changelog:
    • Added PanelSerialization for runtime serialization (it is simpler to use than the temporary solution I've posted in my previous message)
    • Added an option to completely remove the free space from the canvas
    • Added initial size property to docked panels
    • Exposed PanelTab class for modifying tabs
    NOTE: after upgrading your project, it is recommended that you save your scene(s) with dynamic panels at least once for the IDs of the tabs and the canvases to be serialized (needed by PanelSerialization).
     
  23. RvieiraShearwater

    RvieiraShearwater

    Joined:
    Feb 12, 2019
    Posts:
    1
    Hi

    Great work on your asset, it's really great, saved us a lot of time.

    However, is there a way to prevent the user from create floating panels?
     
  24. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
  25. NeedHydra

    NeedHydra

    Joined:
    Sep 18, 2016
    Posts:
    2
    What function do i need to call to make a new tab in a script while the game is running(not in editor)

    Edit: Never mind i was just looking in the wrong class. Somehow i missed it the first time i was looking in Panel.cs
     
    Last edited: Mar 26, 2019
  26. StarCoop

    StarCoop

    Joined:
    Nov 26, 2016
    Posts:
    44
    Hi there,

    awesome asset man! However, I have three questions or requests:
    1. Is there a way to prevent certain docking positions, e.g. the user can dock panels on right, bottom, left, but not at the top edge of the rectangle?
    2. I would like to scale my freespace in the middle of the dockable panels, depending on their size. Up to now, I realized the free space as a panel in the middle, but this way the user can drag and drop it, which must not happen. How would you do that?
    3. I have a panel at the left and one at the right. Left panel has minimum x = 222, right panel has minimum x = 160. However, when I undock the right panel and dock the one which was left, it uses the min x = 222 and not the x = 160. How could I define docking zones with certain min sizes?
     
  27. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    1. If it is the edge of the canvas, you may try commenting out one of these lines, otherwise it is not possible.
    2. The free space is indeed a panel in the middle but it is marked as dummy internally, so a user can't drag and drop it. You can make this variable public to access the free space panel.
    3. There is no neat solution for this, however feel free to make modifications to the code to achieve this. You'll probably have to tweak at least PanelManager.AnchorPanel.
     
  28. StarCoop

    StarCoop

    Joined:
    Nov 26, 2016
    Posts:
    44
    Hi,
    thanks for your reply! Nr. 1 worked with some additional minor changes.
    The others I'll have at them.
     
  29. HiAvatar

    HiAvatar

    Joined:
    Jan 9, 2015
    Posts:
    5
    great work!! its Useful to me.
     
    yasirkula likes this.
  30. cyberbum

    cyberbum

    Joined:
    Nov 11, 2017
    Posts:
    3
    Hi! This asset looks really impressive, i played around with the webgl version, really neat.

    I have a few questions:
    1- Can you hide the tab widget so that you only see the panel? (Even if by modifying code, I don’t mind)
    2- Can you drag a panel by clicking anywhere in the window, rather than just the tab?

    Thanks!
     
  31. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Yes, with a little modification, it is possible to achieve these.

    1- Modify DynamicPanels/Resources/DynamicPanel.prefab as follows:
    a) set DynamicPanel/Content/RectTransform/Top value to 2
    b) set DynamicPanel/PanelHeader/RectTransform/Height value to 0

    2- Add the following script to the content of your panel:

    Code (CSharp):
    1. using DynamicPanels;
    2. using UnityEngine;
    3. using UnityEngine.EventSystems;
    4.  
    5. public class PanelDragFromWithin : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
    6. {
    7.     private PanelHeader panelHeader;
    8.    
    9.     private void Awake()
    10.     {
    11.         panelHeader = GetComponentInParent<Panel>().GetComponentInChildren<PanelHeader>();
    12.     }
    13.  
    14.     public void OnBeginDrag( PointerEventData eventData )
    15.     {
    16.         panelHeader.OnBeginDrag( eventData );
    17.     }
    18.  
    19.     public void OnDrag( PointerEventData eventData )
    20.     {
    21.         panelHeader.OnDrag( eventData );
    22.     }
    23.  
    24.     public void OnEndDrag( PointerEventData eventData )
    25.     {
    26.         panelHeader.OnEndDrag( eventData );
    27.     }
    28. }
     
    cyberbum likes this.
  32. cyberbum

    cyberbum

    Joined:
    Nov 11, 2017
    Posts:
    3
    Whoa thanks for the quick reply!! I'll be trying this tonight!
     
    yasirkula likes this.
  33. Turtwiggy

    Turtwiggy

    Joined:
    Jun 18, 2017
    Posts:
    7
    Is there a way to keep the panels rendering when they're outside a canvas? Had a bit of success with custom shaders but wondering what the best approach would be

    Example below :)
     
    Last edited: Aug 30, 2019
  34. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Turtwiggy likes this.
  35. Turtwiggy

    Turtwiggy

    Joined:
    Jun 18, 2017
    Posts:
    7
    Thanks so much! Works perfectly
     
    yasirkula likes this.
  36. Tommy-Core

    Tommy-Core

    Joined:
    Jan 24, 2014
    Posts:
    21
    Hi @yasirkula!

    Amazing job on the asset. You just saved me a whole lot of time and effort. Your work is very much appreciated.
     
    yasirkula likes this.
  37. reillydonovan

    reillydonovan

    Joined:
    Jun 25, 2019
    Posts:
    1
    thanks for this asset! Quick question- is there a way to have a panel resize from the center anchor of a ui object? For example, if I grab the right side of a panel to resize it I would like to have the left and right side scale in or out simultaneously. Let me know, thanks!
     
  38. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    I think it can be achieved by modifying the Panel.OnResize function. Hope it helps!
     
  39. tlee8988

    tlee8988

    Joined:
    Feb 4, 2020
    Posts:
    1
    How did you get the scene to appear in the top left panel? I like how it's scalable without distorting the image.
     
  40. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
  41. NaveenSellamuthu

    NaveenSellamuthu

    Joined:
    Aug 27, 2019
    Posts:
    4
    Hi @yasirkula :)
    Thank you giving the wonderful asset. This is what i need !. Quick Question : I had added two panels one on left and another on right. In the right side panel i have added two tabs as (Tab 1 & Tab 2 ). When switching from tab 1 to tab 2 , tab 2 get activated and tab 1 get deactivated. But for my functionality tab 1 should not get deactivated , it should be in active. (My Assumption Idea : when tab 2 get activated it automatically overlap the tab 1 so no necessary to deactivate tab 1 ). Revert me if have any idea on this.

    Thanks in Advance!!! .
     

    Attached Files:

  42. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Hi! You can try changing this line as follows:
    Code (CSharp):
    1. CanvasGroup canvasGroup = Content.gameObject.GetComponent<CanvasGroup>();
    2. if( !canvasGroup )
    3.     canvasGroup = Content.gameObject.AddComponent<CanvasGroup>();
    4.  
    5. canvasGroup.alpha = activeState ? 1f : 0f;
    6. canvasGroup.blocksRaycasts = activeState;
    7. canvasGroup.interactable = activeState;
     
  43. abababbb

    abababbb

    Joined:
    Dec 6, 2019
    Posts:
    1
    Hi

    This asset doesn't seem to work in unity 2020.1.
    Even in the included demo scene, when I hover over the game view window, it spams the console with the following error:
    MissingComponentException: There is no 'CanvasRenderer' attached to the "ResizeZoneLeft" game object, but a script is trying to access it.
    You probably need to add a CanvasRenderer to the game object "ResizeZoneLeft". Or your script needs to check if the component is attached before using it.


    Works on older versions though.
     
  44. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    I'll check it out, thanks for reporting it.
     
  45. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    @huhinchang You can change Plugins/DynamicPanels/Scripts/Helpers/NonDrawingGraphic.cs as follows:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. namespace DynamicPanels
    5. {
    6.     // Credit: http://answers.unity.com/answers/1157876/view.html
    7.     [RequireComponent( typeof( CanvasRenderer ) )]
    8.     public class NonDrawingGraphic : Graphic
    9.     {
    10.         public override void SetMaterialDirty() { return; }
    11.         public override void SetVerticesDirty() { return; }
    12.  
    13.         protected override void OnPopulateMesh( VertexHelper vh )
    14.         {
    15.             vh.Clear();
    16.             return;
    17.         }
    18.     }
    19. }
    I've submitted a bug report for this issue since it affects a number of my plugins and possibly some of the other UI related plugins out there, as well (we can see that it had affected TextMesh Pro, too).
     
    abababbb likes this.
  46. arturmandas

    arturmandas

    Joined:
    Sep 29, 2012
    Posts:
    240
    @yasirkula this asset is amazing. Thank you very much.
     
    yasirkula likes this.
  47. xpzhang

    xpzhang

    Joined:
    Jul 23, 2020
    Posts:
    17
    Hi,I want to separate the paneltab from the panel,because i want to control the panel by Dragging the button,can you give me some advice
     
  48. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Could you post a screenshot of how the panel will look like without the paneltab and where the button will be placed at so that I can visualize this scenario in my mind?
     
  49. xpzhang

    xpzhang

    Joined:
    Jul 23, 2020
    Posts:
    17
    excuse me,the picture is my rough sketch,i want to drag the button to the right canvas,and the panel will move to
    the right canvas automatically,can you give me some advice
     

    Attached Files:

  50. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,879
    Seems to me that you need 2 DynamicPanelsCanvas objects: one for the left area and one for the right area. And you'll need 3 references:
    Code (CSharp):
    1. public GameObject panelContents; // The grey object
    2. public DynamicPanelsCanvas leftCanvas;
    3. public DynamicPanelsCanvas rightCanvas;
    When you move the button to the right area, you should call
    panelContents.GetComponentInParent<Panel>().DockToPanel(rightCanvas.RootPanelGroup, Direction.Top);


    As for how to drag the button from one area to the other, it really is up to you; it is outside the scope of DynamicPanels. You can find plenty of UI drag&drop tutorials online.

    P.S. If you aren't interested in any of the fancy DynamicPanels stuff like tab stacking, horizontal/vertical panel layouts, then I'd recommend you to simply call
    panelContents.transform.SetParent(rightZone.transform, false);
    and not use DynamicPanels at all.