コード例 #1
0
        private void Awake()
        {
            List <Assembly> assemblies = new List <Assembly>();

            foreach (string assemblyName in BHRoot.Assemblies)
            {
                var asName = new AssemblyName();
                asName.Name = assemblyName;
                Assembly asm = Assembly.Load(asName);
                if (asm == null)
                {
                    Debug.LogWarning("Unable to load " + assemblyName);
                    continue;
                }
                assemblies.Add(asm);
            }


            if (m_menuPanel == null)
            {
                m_menuPanel = gameObject;
            }

            if (m_topMenu == null)
            {
                m_topMenu = gameObject;
            }

            if (m_menuButtonPrefab == null)
            {
                Debug.LogError("Set Menu Button Prefab");
                return;
            }

            if (m_menuPrefab == null)
            {
                Debug.LogError("Set Menu Prefab");
                return;
            }

            bool wasButtonPrefabActive = m_menuButtonPrefab.gameObject.activeSelf;
            bool wasMenuPrefabActive   = m_menuPrefab.gameObject.activeSelf;

            Dictionary <string, Menu> menuDictionary = new Dictionary <string, Menu>();
            Dictionary <string, List <MenuItemWithPriority> > menuItemsDictionary = new Dictionary <string, List <MenuItemWithPriority> >();

            Menu[] menus = m_menuPanel.GetComponentsInChildren <Menu>(true);
            for (int i = 0; i < menus.Length; ++i)
            {
                if (!menuDictionary.ContainsKey(menus[i].name))
                {
                    menuDictionary.Add(menus[i].name, menus[i]);

                    if (menus[i].Items != null)
                    {
                        List <MenuItemWithPriority> menuItemsWithPriority = new List <MenuItemWithPriority>();
                        for (int priority = 0; priority < menus[i].Items.Length; ++priority)
                        {
                            MenuItemInfo menuItemInfo = menus[i].Items[priority];
                            menuItemsWithPriority.Add(new MenuItemWithPriority(menuItemInfo, priority));
                        }
                        menuItemsDictionary.Add(menus[i].name, menuItemsWithPriority);
                    }
                    else
                    {
                        menuItemsDictionary.Add(menus[i].name, new List <MenuItemWithPriority>());
                    }
                }
            }

            Type[] menuDefinitions = assemblies.SelectMany(asm => asm.GetTypesWithAttribute(typeof(MenuDefinitionAttribute))).OrderBy(kvp => ((MenuDefinitionAttribute)kvp.Value).Order).Select(kvp => kvp.Key).ToArray();
            foreach (Type menuDef in menuDefinitions)
            {
                MethodInfo[] methods = menuDef.GetMethods(BindingFlags.Static | BindingFlags.Public);
                for (int i = 0; i < methods.Length; ++i)
                {
                    MethodInfo           mi  = methods[i];
                    MenuCommandAttribute cmd = (MenuCommandAttribute)mi.GetCustomAttributes(typeof(MenuCommandAttribute), true).FirstOrDefault();
                    if (cmd == null || string.IsNullOrEmpty(cmd.Path))
                    {
                        continue;
                    }

                    if (cmd.RequiresInstance)
                    {
                        if (FindObjectOfType(menuDef) == null)
                        {
                            continue;
                        }
                    }

                    string[] pathParts = cmd.Path.Split('/');
                    if (pathParts.Length < 1)
                    {
                        continue;
                    }

                    string menuName = pathParts[0];

                    if (!menuDictionary.ContainsKey(menuName))
                    {
                        MainMenuButton btn = _CreateMenu(menuName);

                        menuDictionary.Add(menuName, btn.Menu);
                        menuItemsDictionary.Add(menuName, new List <MenuItemWithPriority>());
                    }

                    if (pathParts.Length == 1)
                    {
                        if (cmd.Hide)
                        {
                            menuItemsDictionary[menuName].Clear();
                        }
                    }

                    if (pathParts.Length < 2)
                    {
                        continue;
                    }

                    string path = string.Join("/", pathParts.Skip(1));
                    List <MenuItemWithPriority> menuItems = menuItemsDictionary[menuName];
                    MenuItemWithPriority        menuItem  = menuItems.Where(item => item.Info.Path == path).FirstOrDefault();
                    if (menuItem == null)
                    {
                        menuItem = new MenuItemWithPriority();
                        menuItems.Add(menuItem);
                    }

                    menuItem.Info.Path = string.Join("/", pathParts.Skip(1));
                    menuItem.Info.Icon = !string.IsNullOrEmpty(cmd.IconPath) ? Resources.Load <Sprite>(cmd.IconPath) : null;
                    menuItem.Info.Text = pathParts.Last();

                    if (cmd.Validate)
                    {
                        Func <bool> validate = (Func <bool>)Delegate.CreateDelegate(typeof(Func <bool>), mi, false);
                        if (validate == null)
                        {
                            Debug.LogWarning("method signature is invalid. bool Func() is expected. " + string.Join("/", pathParts));
                        }
                        else
                        {
                            menuItem.Info.Validate = new MenuItemValidationEvent();
                            menuItem.Info.Validate.AddListener(new UnityAction <MenuItemValidationArgs>(args => args.IsValid = validate()));
                        }
                    }
                    else
                    {
                        Action action = (Action)Delegate.CreateDelegate(typeof(Action), mi, false);
                        if (action == null)
                        {
                            Debug.LogWarning("method signature is invalid. void Action() is expected. " + string.Join("/", pathParts));
                        }
                        else
                        {
                            menuItem.Info.Action = new MenuItemEvent();
                            menuItem.Info.Action.AddListener(new UnityAction <string>(args => action()));
                        }
                    }

                    if (cmd.Hide)
                    {
                        menuItems.Remove(menuItem);
                    }

                    menuItem.Priority = cmd.Priority;
                }

                m_menuPrefab.gameObject.SetActive(wasMenuPrefabActive);
                m_menuButtonPrefab.gameObject.SetActive(wasButtonPrefabActive);
            }

            foreach (KeyValuePair <string, List <MenuItemWithPriority> > kvp in menuItemsDictionary)
            {
                menuDictionary[kvp.Key].SetMenuItems(kvp.Value.OrderBy(m => m.Priority).Select(m => m.Info).ToArray(), false);
            }
        }
コード例 #2
0
ファイル: MenuCreator.cs プロジェクト: huhuman/NadiSensoUI
        private void Awake()
        {
            var asName = new AssemblyName();

            asName.Name = "Assembly-CSharp";
            Assembly csAssembly = Assembly.Load(asName);

            if (csAssembly == null)
            {
                Debug.LogWarning("Unable to load Assembly-CSharp");
                return;
            }

            if (m_menuPanel == null)
            {
                m_menuPanel = gameObject;
            }

            if (m_topMenu == null)
            {
                m_topMenu = gameObject;
            }

            if (m_menuButtonPrefab == null)
            {
                Debug.LogError("Set Menu Button Prefab");
                return;
            }

            if (m_menuPrefab == null)
            {
                Debug.LogError("Set Menu Prefab");
                return;
            }

            bool wasButtonPrefabActive = m_menuButtonPrefab.gameObject.activeSelf;
            bool wasMenuPrefabActive   = m_menuPrefab.gameObject.activeSelf;

            Dictionary <string, Menu> menuDictionary = new Dictionary <string, Menu>();
            Dictionary <string, List <MenuItemInfo> > menuItemsDictionary = new Dictionary <string, List <MenuItemInfo> >();

            Menu[] menus = m_menuPanel.GetComponentsInChildren <Menu>(true);
            for (int i = 0; i < menus.Length; ++i)
            {
                if (!menuDictionary.ContainsKey(menus[i].name))
                {
                    menuDictionary.Add(menus[i].name, menus[i]);

                    if (menus[i].Items != null)
                    {
                        menuItemsDictionary.Add(menus[i].name, menus[i].Items.ToList());
                    }
                    else
                    {
                        menuItemsDictionary.Add(menus[i].name, new List <MenuItemInfo>());
                    }
                }
            }


            Type[] menuDefinitions = csAssembly.GetTypesWithAttribute(typeof(MenuDefinitionAttribute)).ToArray();
            foreach (Type menuDef in menuDefinitions)
            {
                MethodInfo[] methods = menuDef.GetMethods(BindingFlags.Static | BindingFlags.Public);
                for (int i = 0; i < methods.Length; ++i)
                {
                    MethodInfo           mi  = methods[i];
                    MenuCommandAttribute cmd = (MenuCommandAttribute)mi.GetCustomAttributes(typeof(MenuCommandAttribute), true).FirstOrDefault();
                    if (string.IsNullOrEmpty(cmd.Path))
                    {
                        continue;
                    }

                    string[] pathParts = cmd.Path.Split('/');
                    if (pathParts.Length < 2)
                    {
                        continue;
                    }

                    string menuName = pathParts[0];

                    Menu menu;
                    if (!menuDictionary.ContainsKey(menuName))
                    {
                        m_menuButtonPrefab.gameObject.SetActive(false);
                        m_menuPrefab.gameObject.SetActive(false);

                        menu       = Instantiate(m_menuPrefab, m_menuPanel.transform, false);
                        menu.Items = null;

                        MainMenuButton btn = Instantiate(m_menuButtonPrefab, m_topMenu.transform, false);
                        btn.name = menuName;
                        btn.Menu = menu;

                        Text txt = btn.GetComponentInChildren <Text>(true);
                        if (txt != null)
                        {
                            txt.text = menuName;
                        }

                        btn.gameObject.SetActive(true);

                        menuDictionary.Add(menuName, menu);
                        menuItemsDictionary.Add(menuName, new List <MenuItemInfo>());
                    }
                    else
                    {
                        menu = menuDictionary[menuName];
                    }

                    string path = string.Join("/", pathParts.Skip(1));
                    List <MenuItemInfo> menuItems = menuItemsDictionary[menuName];
                    MenuItemInfo        menuItem  = menuItems.Where(item => item.Path == path).FirstOrDefault();
                    if (menuItem == null)
                    {
                        menuItem = new MenuItemInfo();
                        menuItems.Add(menuItem);
                    }

                    menuItem.Path = string.Join("/", pathParts.Skip(1));
                    menuItem.Icon = !string.IsNullOrEmpty(cmd.IconPath) ? Resources.Load <Sprite>(cmd.IconPath) : null;
                    menuItem.Text = pathParts.Last();

                    if (cmd.Validate)
                    {
                        Func <bool> validate = (Func <bool>)Delegate.CreateDelegate(typeof(Func <bool>), mi, false);
                        if (validate == null)
                        {
                            Debug.LogWarning("method signature is invalid. bool Func() is expected. " + string.Join("/", pathParts));
                        }
                        else
                        {
                            menuItem.Validate = new MenuItemValidationEvent();
                            menuItem.Validate.AddListener(new UnityAction <MenuItemValidationArgs>(args => args.IsValid = validate()));
                        }
                    }
                    else
                    {
                        Action action = (Action)Delegate.CreateDelegate(typeof(Action), mi, false);
                        if (action == null)
                        {
                            Debug.LogWarning("method signature is invalid. void Action() is expected. " + string.Join("/", pathParts));
                        }
                        else
                        {
                            menuItem.Action = new MenuItemEvent();
                            menuItem.Action.AddListener(new UnityAction <string>(args => action()));
                        }
                    }

                    if (cmd.Hide)
                    {
                        menuItems.Remove(menuItem);
                    }
                }

                m_menuPrefab.gameObject.SetActive(wasMenuPrefabActive);
                m_menuButtonPrefab.gameObject.SetActive(wasButtonPrefabActive);
            }

            foreach (KeyValuePair <string, List <MenuItemInfo> > kvp in menuItemsDictionary)
            {
                menuDictionary[kvp.Key].SetMenuItems(kvp.Value.ToArray(), false);
            }
        }