I’ve made a modal panel via the recent UI Modal Panel tutorial.
When I instantiate the modal window without some of the elements like the icon or only 1 button the elements in the layout group do not always adjust their sizes like they should.
If I try to adjust the size of the rect transform in the inspector it shows the value as editable, but if I change it then the value actually locks in and is driven by the layout group.
I’ve added Canvas.ForceUpdateCanvases() to the end of the Modal Window’s function that sets the elements active/inactive, but for the most part the modal panel still has issues.
This seems to happen mostly when other UI Canvases are showing.
Anyone have an idea?
EDIT: A bunch more details -
Code for modal panel (sorry for the lack of overrides, but this was the quickest way to set it up):
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using System.Collections;
public class ModalPanel : MonoBehaviour {
public Text question;
public Image iconImage;
public Button yesButton;
public Button noButton;
public Button cancelButton;
public Button iconButton;
public GameObject modalPanelObject;
private bool isShowing = false;
public bool IsShowing
{ get { return isShowing; } }
private static ModalPanel modalPanel;
public static ModalPanel Instance()
{
if (!modalPanel)
{
modalPanel = FindObjectOfType(typeof(ModalPanel)) as ModalPanel;
if (!modalPanel)
Debug.LogError("There needs to be one active ModalPanel script on a GameObject in your scene.");
}
return modalPanel;
}
// Yes/No/Cancel with image: A string, a sprite, no event, yes event, cancel event
public void Choice(string question, Sprite iconImage, UnityAction yesEvent, UnityAction noEvent, UnityAction cancelEvent)
{
this.question.text = question;
modalPanelObject.SetActive(true);
this.iconImage.gameObject.SetActive(false);
yesButton.gameObject.SetActive(false);
noButton.gameObject.SetActive(false);
cancelButton.gameObject.SetActive(false);
iconButton.onClick.RemoveAllListeners();
if (yesEvent != null)
{
yesButton.onClick.RemoveAllListeners();
yesButton.onClick.AddListener(yesEvent);
yesButton.onClick.AddListener(ClosePanel);
yesButton.gameObject.SetActive(true);
}
if (noEvent != null)
{
noButton.onClick.RemoveAllListeners();
noButton.onClick.AddListener(noEvent);
noButton.onClick.AddListener(ClosePanel);
noButton.gameObject.SetActive(true);
}
if (cancelEvent != null)
{
cancelButton.onClick.RemoveAllListeners();
cancelButton.onClick.AddListener(cancelEvent);
cancelButton.onClick.AddListener(ClosePanel);
cancelButton.gameObject.SetActive(true);
foreach (Transform t in cancelButton.transform)
{
if (t.name == "Text")
{
if (noButton == null && yesButton == null)
{
t.GetComponent<Text>().text = "OK";
}
else
{
t.GetComponent<Text>().text = "Cancel";
}
break;
}
}
}
if (iconImage != null)
{
this.iconImage.sprite = iconImage;
this.iconImage.gameObject.SetActive(true);
}
isShowing = true;
Canvas.ForceUpdateCanvases();
}
public void AssignIconButtonAction(UnityAction iconAction)
{
iconButton.onClick.RemoveAllListeners();
iconButton.onClick.AddListener(iconAction);
iconButton.onClick.AddListener(ClosePanel);
iconButton.gameObject.SetActive(true);
}
public void ClosePanel()
{
isShowing = false;
if (!isShowing)
Debug.Log("ModalPanel closed");
modalPanelObject.SetActive(false);
}
}
Images:
Initial way the dialogue appears - notice text is overrunning, moved to the right, cancel button is not stretched to fill parent.
Inspector view of the text object, notice the rect’s values are not locked yet.
Inspector view after manually attempting to change the rect’s values. Notice they are now locked as they should be. And “driven by layout group”
Here’s what the text should look like. The same issue happens with the button which should automatically fill the width.
And finally, here’s an image of the parent container’s setup. This should be driving the size of the text child object (which it does, but only after manually changing rect values).