// TODO Possible type caching? public static MenuItemNode GenerateMenuItemNodeTree(GenericMenu p_menu) { MenuItemNode rootNode = new MenuItemNode(); if (p_menu == null) { return(rootNode); } var menuItemsField = TryGetField("menuItems"); if (menuItemsField == null) { menuItemsField = TryGetField("m_MenuItems"); } var menuItems = menuItemsField.GetValue(p_menu) as IEnumerable; foreach (var menuItem in menuItems) { var menuItemType = menuItem.GetType(); GUIContent content = (GUIContent)menuItemType.GetField("content").GetValue(menuItem); bool separator = (bool)menuItemType.GetField("separator").GetValue(menuItem); string path = content.text; string[] splitPath = path.Split('/'); MenuItemNode currentNode = rootNode; for (int i = 0; i < splitPath.Length; i++) { currentNode = (i < splitPath.Length - 1) ? currentNode.GetOrCreateNode(splitPath[i]) : currentNode.CreateNode(splitPath[i]); } if (separator) { currentNode.separator = true; } else { currentNode.content = content; currentNode.func = (GenericMenu.MenuFunction)menuItemType.GetField("func").GetValue(menuItem); currentNode.func2 = (GenericMenu.MenuFunction2)menuItemType.GetField("func2").GetValue(menuItem); currentNode.userData = menuItemType.GetField("userData").GetValue(menuItem); currentNode.on = (bool)menuItemType.GetField("on").GetValue(menuItem); } } return(rootNode); FieldInfo TryGetField(string fieldName) { return(p_menu.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic)); } }