Dropdown Raised - MissingComponent

0 votes
asked Sep 27, 2016 in Issue by raydekk (530 points)

I've got a GameObject called GUIMenu and a Canvas GameObject under it. If I create a Raised Dropdown right under the Canvas I get the following error:

MissingComponentException: There is no 'Canvas' attached to the "GUIMenu" game object, but a script is trying to access it.
You probably need to add a Canvas to the game object "GUIMenu". Or your script needs to check if the component is attached before using it.
UnityEngine.Component.GetComponent[RectTransform] () (at C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineComponentBindings.gen.cs:48)
MaterialUI.CanvasExtension.Copy (UnityEngine.Canvas canvas, UnityEngine.GameObject gameObjectToAddTo) (at Assets/MaterialUI/Scripts/MaterialUtils/Extensions.cs:82)
MaterialUI.MaterialDropdown.Start () (at Assets/MaterialUI/Scripts/Components/MaterialDropdown.cs:669)

But there is a Canvas component on the Canvas GO. Any idea why this is happening?

I'm on MaterialUI 1.1.5, but with the Inputfield fix you sent me some time ago.

Raydekk

commented Oct 3, 2016 by anthonyioflux (610 points)
MissingComponentException: There is no 'Canvas' attached to the "SandboxController" game object, but a script is trying to access it.
You probably need to add a Canvas to the game object "SandboxController". Or your script needs to check if the component is attached before using it.
UnityEngine.Component.GetComponent[RectTransform] () (at C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineComponentBindings.gen.cs:48)
MaterialUI.CanvasExtension.CopySettingsToOtherCanvas (UnityEngine.Canvas canvas, UnityEngine.Canvas otherCanvas) (at Assets/MaterialUI/Scripts/MaterialUtils/Extensions.cs:116)
MaterialUI.MaterialDropdown.Show () (at Assets/MaterialUI/Scripts/Components/MaterialDropdown.cs:677)
UnityEngine.Events.InvokableCall.Invoke (System.Object[] args) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:153)
UnityEngine.Events.InvokableCallList.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:630)
UnityEngine.Events.UnityEventBase.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:765)
UnityEngine.Events.UnityEvent.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:53)
UnityEngine.UI.Button.Press () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:35)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:44)
UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:52)
UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:269)
UnityEngine.EventSystems.EventSystem:Update()

We have a canvas on an injected prefab and a drop down as the direct child or down the tree which is giving the same exception.

commented Oct 3, 2016 by anthonyioflux (610 points)
Recreated the scene that was giving issues and now it is working fine. Must be something that broke the component while editing the prefab.
commented Oct 4, 2016 by raydekk (530 points)
Well, if I create a dropdown from the menu in the root directory, a Dropdown Canvas gameobject is generated automatically. If I place the dropdown under the Dropdown Canvas GO it works fine, if I place it under my own canvas (where all my other elements are and they work) - the error above is shown.

It's very weird because the two canvases have the same parameters.
commented Oct 5, 2016 by anthonyioflux (610 points)

Got the exception again today. This time for an app bar dropdown.

If I remove the app bar from the scene all is fine. If I create one from the menu and I run the scene I get this exception. The app bar's parent is a canvas.

 

MissingComponentException: There is no 'Canvas' attached to the "ProfileSetupController" game object, but a script is trying to access it.
You probably need to add a Canvas to the game object "ProfileSetupController". Or your script needs to check if the component is attached before using it.
UnityEngine.Component.GetComponent[RectTransform] () (at C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineComponentBindings.gen.cs:48)
MaterialUI.CanvasExtension.Copy (UnityEngine.Canvas canvas, UnityEngine.GameObject gameObjectToAddTo) (at Assets/MaterialUI/Scripts/MaterialUtils/Extensions.cs:82)
MaterialUI.MaterialDropdown.Start () (at Assets/MaterialUI/Scripts/Components/MaterialDropdown.cs:669)

 

commented Oct 5, 2016 by raydekk (530 points)
Are you using Unity 5.4.x? I am.

Maybe something changed in 5.4, because I don't remember having this issue in 5.3.x. I think I'll test it out this weekend, downgrading is a pain :)
commented Oct 5, 2016 by anthonyioflux (610 points)
Yes I am also using 5.4.X.

I think it is line 669 in MaterialDropdown.cs that is the issue and doesn't play nicely. Trying something atm, Will let you know if it fixes it.
commented Oct 5, 2016 by anthonyioflux (610 points)

The problem lies in how the dropdown assumes that the canvas is the root game object.

This version looks for the first canvas up from the root all the way down to the dropdown.

 Add this static class.

using System;
using System.Collections.Generic;
using UnityEngine;

namespace MaterialUI
{
    public static class MaterialDropdownExtensions
    {
        /// <summary>
        /// Starts searching for a canvas from the root object of this transform down the tree and returns the first canvas found.
        /// </summary>
        /// <param name="transform"></param>
        /// <returns></returns>
        public static Canvas FindRootCanvas(this Transform transform)
        {
            if (transform == null)
            {
                return null;
            }

            Canvas canvas = null;
            Stack<Transform> parents = new Stack<Transform>();

            PopulateParents(transform, parents);

            while (parents.Count > 0)
            {
                Transform parent = parents.Pop();

                if (parent != null)
                {
                    canvas = parent.GetComponent<Canvas>();

                    if (canvas != null)
                    {
                        break;
                    }
                }
            }

            if (canvas == null)
            {
                throw new Exception("Could not find the root canvas.");
            }

            return canvas;
        }

        public static void PopulateParents(Transform transform, Stack<Transform> parents)
        {
            parents.Push(transform);

            if (transform.parent != null)
            {
                PopulateParents(transform.parent, parents);
            }
        }
    }
}

Change line 669 in MaterialDropdown to:
 

m_DropdownCanvas = transform.FindRootCanvas().Copy(m_DropdownCanvasGameObject);

and line 677 in MaterialDropdown to:

transform.FindRootCanvas().CopySettingsToOtherCanvas(m_DropdownCanvas);

 

commented Oct 11, 2016 by raydekk (530 points)
Thanks for the fix! Dropdown problem solved.

Hope the devs add this in the new version.
commented Oct 17, 2016 by admin (31,720 points)
Hey guys,

Looks like you're right, MaterialDropdown isn't factoring that the Canvas might not be in the root object.

Thanks for the help, I'll add a fix to the next version :)

~ Declan.
commented Oct 17, 2016 by anthonyioflux (610 points)
Hi Declan, anytime! Thanks for the great product and support! Keep up the good work.

1 Answer

+1 vote
answered Oct 15, 2016 by anthonyioflux (610 points)
selected Oct 16, 2016 by raydekk
 
Best answer
Fixed by using extension I provided for when the canvas is not on the root.
Welcome to MaterialUI support! Ask us anything :)
...