コード例 #1
0
        private void OnEditorSelectionChanged()
        {
            SidekickSettings settings = BridgingContext.Instance.container.Settings;

            if (settings.InspectionConnection == InspectionConnection.LocalEditor)
            {
                SetSelectedPath(GetFullPath(Selection.activeObject));
            }
        }
コード例 #2
0
        private void OnEditorSelectionChanged()
        {
            SidekickSettings settings = BridgingContext.Instance.container.Settings;

            if (settings.InspectionConnection == InspectionConnection.LocalEditor)
            {
                if (Selection.activeGameObject != null)
                {
                    SelectedPath = Selection.activeGameObject.scene.name + "/" + GetPath(Selection.activeGameObject.transform);
                }
                else
                {
                    SelectedPath = "";
                }
            }
        }
コード例 #3
0
        public int SendToPlayers(BaseRequest request)
        {
            SidekickSettings settings = BridgingContext.Instance.container.Settings;

            lastRequestID++;
            if (settings.InspectionConnection == InspectionConnection.LocalEditor)
            {
                if (ResponseReceived != null)
                {
                    ResponseReceived(request.GenerateResponse());
                }
            }
            else
            {
                byte[] bytes;
                using (MemoryStream ms = new MemoryStream())
                {
                    using (BinaryWriter bw = new BinaryWriter(ms))
                    {
                        bw.Write(lastRequestID);

                        bw.Write(request.GetType().Name);
                        request.Write(bw);
                    }
                    bytes = ms.ToArray();
                }
#if SIDEKICK_DEBUG
                if (settings.LocalDevMode)
                {
                    byte[]           testResponse = SidekickRequestProcessor.Process(bytes);
                    MessageEventArgs messageEvent = new MessageEventArgs();
                    messageEvent.data = testResponse;
                    BaseResponse response = SidekickResponseProcessor.Process(testResponse);
                    if (ResponseReceived != null)
                    {
                        ResponseReceived(response);
                    }
                }
                else
#endif
                {
                    EditorConnection.instance.Send(RuntimeSidekickBridge.SEND_EDITOR_TO_PLAYER, bytes);
                }
            }
            return(lastRequestID);
        }
コード例 #4
0
        public void SetConnectionMode(InspectionConnection newConnectionMode)
        {
            SidekickSettings settings = commonContext.Settings;

            settings.InspectionConnection = newConnectionMode;

            // Reset
            gameObjectResponse = null;
            commonContext.SelectionManager.SelectedPath = null;

            if (newConnectionMode == InspectionConnection.RemotePlayer)
            {
                EnableRemoteMode();
                FindOrCreateRemoteHierarchyWindow();
            }
            else
            {
                DisableRemoteMode();
            }
        }
コード例 #5
0
        void OnGUI()
        {
            GUIStyle centerMessageStyle = new GUIStyle(GUI.skin.label);

            centerMessageStyle.alignment = TextAnchor.MiddleCenter;
            centerMessageStyle.wordWrap  = true;

            if (parentWindow == null)
            {
                AcquireParentWindowIfPossible();
            }

            if (parentWindow == null || parentWindow.CommonContext.Enabled == false)
            {
                GUILayout.FlexibleSpace();
                GUILayout.Label("Sidekick Inspector window must be open to use remote hierarchy", centerMessageStyle);
                if (GUILayout.Button("Open Sidekick Inspector"))
                {
                    SidekickInspectorWindow.OpenWindow();
                    AcquireParentWindowIfPossible();
                }
                GUILayout.FlexibleSpace();


                return;
            }

            if (parentWindow.CommonContext.Settings.InspectionConnection == InspectionConnection.RemotePlayer)
            {
                GUILayout.Space(9);

                SidekickSettings settings = parentWindow.CommonContext.Settings;

                if (settings.InspectionConnection == InspectionConnection.RemotePlayer)
                {
                    int playerCount = EditorConnection.instance.ConnectedPlayers.Count;


                    StringBuilder builder = new StringBuilder();
                    builder.AppendLine(string.Format("{0} players connected.", playerCount));

                    bool validConnection = (playerCount > 0);

#if SIDEKICK_DEBUG
                    // If we're in Local Dev Mode also consider that a valid connection
                    validConnection |= settings.LocalDevMode;
#endif


                    if (validConnection == false)
                    {
#if UNITY_2017_1_OR_NEWER
                        EditorGUILayout.HelpBox("No player connected, selected a Connected Player in the Console window or attach the Profiler to a remote player", MessageType.Warning);
#else
                        EditorGUILayout.HelpBox("No player connected, attach the Profiler to a remote player", MessageType.Warning);
#endif
                    }
                    else
                    {
                        int count = 0;
                        foreach (ConnectedPlayer p in EditorConnection.instance.ConnectedPlayers)
                        {
#if UNITY_2017_3_OR_NEWER
                            // ConnectedPlayer interface changed in 2017.3
                            builder.AppendLine(string.Format("[{0}] - {1} {2}", count++, p.name, p.playerId));
#else
                            builder.AppendLine(string.Format("[{0}] - {1}", count++, p.PlayerId));
#endif
                        }

                        EditorGUILayout.HelpBox(builder.ToString(), MessageType.Info);
                    }
                    settings.AutoRefreshRemote = EditorGUILayout.Toggle("Auto Refresh Remote", settings.AutoRefreshRemote);

#if SIDEKICK_DEBUG
                    settings.LocalDevMode = EditorGUILayout.Toggle("Local Dev Mode", settings.LocalDevMode);
#endif
                    if (validConnection)
                    {
                        if (GUILayout.Button("Refresh Hierarchy"))
                        {
                            parentWindow.CommonContext.APIManager.SendToPlayers(new GetHierarchyRequest());
                        }

                        DoToolbar();
                        DoTreeView();
                    }
                }
            }
            else
            {
                treeView.SetDisplays(new List <TreeViewItem>());
                GUILayout.FlexibleSpace();
                GUILayout.Label("Remote hierarchy is only visible in remote mode", centerMessageStyle);
                if (GUILayout.Button("Set Remote Mode"))
                {
                    parentWindow.SetConnectionMode(InspectionConnection.RemotePlayer);
                }
                GUILayout.FlexibleSpace();
            }
        }
コード例 #6
0
        void OnGUI()
        {
            // Frame rate tracking
            if (Event.current.type == EventType.Repaint)
            {
                AnimationHelper.UpdateTime();
            }

            GUILayout.Space(9);

            SidekickSettings settings = Settings;


            EditorGUI.BeginChangeCheck();
            InspectionConnection newConnectionMode = (InspectionConnection)GUILayout.Toolbar((int)settings.InspectionConnection, new string[] { "Local", "Remote" }, new GUIStyle("LargeButton"));

            if (EditorGUI.EndChangeCheck())
            {
                SetConnectionMode(newConnectionMode);
            }

            settings.SearchTerm = searchField2.OnGUI(settings.SearchTerm);
            GUILayout.Space(3);
            EditorGUI.BeginChangeCheck();

            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("Display");
            settings.GetGameObjectFlags = SidekickEditorGUI.EnumFlagsToggle(settings.GetGameObjectFlags, InfoFlags.Fields, "Fields");
            settings.GetGameObjectFlags = SidekickEditorGUI.EnumFlagsToggle(settings.GetGameObjectFlags, InfoFlags.Properties, "Properties");
            settings.GetGameObjectFlags = SidekickEditorGUI.EnumFlagsToggle(settings.GetGameObjectFlags, InfoFlags.Methods, "Methods");
            EditorGUILayout.EndHorizontal();

            if (EditorGUI.EndChangeCheck())
            {
                if (!string.IsNullOrEmpty(SelectionManager.SelectedPath)) // Valid path?
                {
                    APIManager.SendToPlayers(new GetGameObjectRequest(SelectionManager.SelectedPath, Settings.GetGameObjectFlags, Settings.IncludeInherited));
                }
            }

            scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);

            if (gameObjectResponse != null)
            {
                string activeSearchTerm = settings.SearchTerm;

                foreach (ComponentDescription component in gameObjectResponse.Components)
                {
                    SidekickEditorGUI.DrawSplitter();
                    GUIStyle style = new GUIStyle(EditorStyles.foldout);
                    style.fontStyle = FontStyle.Bold;

                    Texture    icon    = IconLookup.GetIcon(component.TypeFullName);
                    GUIContent content = new GUIContent(component.TypeShortName, icon, "Object Map ID: " + component.Guid.ToString());

                    float labelWidth = EditorGUIUtility.labelWidth; // Cache label width
                    // Temporarily set the label width to full width so the icon is not squashed with long strings
                    EditorGUIUtility.labelWidth = position.width / 2f;

                    bool wasComponentExpanded = !settings.CollapsedTypeNames.Contains(component.TypeFullName);
                    bool isComponentExpanded  = wasComponentExpanded;


                    bool?activeOrEnabled = null;
                    if (component.TypeShortName == "GameObject" && (settings.GetGameObjectFlags & InfoFlags.Properties) != 0)
                    {
                        activeOrEnabled = (bool)component.Scopes[0].GetPropertyValue("activeSelf");
                    }
                    else
                    {
                        ComponentScope behaviourScope = component.BehaviourScope;
                        if (behaviourScope != null && (settings.GetGameObjectFlags & InfoFlags.Properties) != 0)
                        {
                            activeOrEnabled = (bool)behaviourScope.GetPropertyValue("enabled");
                        }
                    }

                    bool?oldActiveOrEnabled = activeOrEnabled;

                    if (SidekickEditorGUI.DrawHeaderWithFoldout(content, isComponentExpanded, ref activeOrEnabled))
                    {
                        isComponentExpanded = !isComponentExpanded;
                    }

                    if (activeOrEnabled.HasValue && activeOrEnabled != oldActiveOrEnabled)
                    {
                        if (component.TypeShortName == "GameObject")
                        {
                            // Update local cache (requires method call)
                            var property = component.Scopes[0].GetProperty("activeSelf");
                            property.Value = activeOrEnabled.Value;

                            // Update via method call
                            APIManager.SendToPlayers(new InvokeMethodRequest(component.Guid, "SetActive", new WrappedVariable[] { new WrappedVariable("", activeOrEnabled.Value, typeof(bool), false) }));
                        }
                        else if (component.BehaviourScope != null)
                        {
                            // Update local cache, then ship via SetVariable
                            var property = component.BehaviourScope.GetProperty("enabled");
                            property.Value = activeOrEnabled.Value;

                            APIManager.SendToPlayers(new SetVariableRequest(component.Guid, property));
                        }
                    }
                    EditorGUIUtility.labelWidth = labelWidth; // Restore label width
                    if (isComponentExpanded != wasComponentExpanded)
                    {
                        if (isComponentExpanded == false)
                        {
                            // Not expanded, so collapse it
                            settings.CollapsedTypeNames.Add(component.TypeFullName);
                        }
                        else
                        {
                            // Expanded, remove it from collapse list
                            settings.CollapsedTypeNames.Remove(component.TypeFullName);
                        }
                    }

                    if (isComponentExpanded)
                    {
                        foreach (ComponentScope scope in component.Scopes)
                        {
                            if (scope.TypeFullName != component.TypeFullName)
                            {
                                SidekickEditorGUI.DrawHeader2(new GUIContent(": " + scope.TypeShortName));
                            }

                            ObjectPickerContext objectPickerContext = new ObjectPickerContext(component.Guid);
                            foreach (var field in scope.Fields)
                            {
                                if (!string.IsNullOrEmpty(activeSearchTerm) && !field.VariableName.Contains(activeSearchTerm, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    // Active search term not matched, skip it
                                    continue;
                                }

                                if (settings.IgnoreObsolete && (field.Attributes & VariableAttributes.Obsolete) == VariableAttributes.Obsolete)
                                {
                                    // Skip obsolete entries if that setting is enabled
                                    continue;
                                }
                                EditorGUI.BeginChangeCheck();
                                object newValue = VariableDrawer.Draw(objectPickerContext, field, OnOpenObjectPicker);
                                if (EditorGUI.EndChangeCheck() && (field.Attributes & VariableAttributes.ReadOnly) == VariableAttributes.None && field.DataType != DataType.Unknown)
                                {
                                    if (newValue != field.Value || field.Attributes.HasFlagByte(VariableAttributes.IsList) || field.Attributes.HasFlagByte(VariableAttributes.IsArray))
                                    {
                                        field.Value = newValue;
                                        APIManager.SendToPlayers(new SetVariableRequest(component.Guid, field));
                                    }

                                    //Debug.Log("Value changed in " + field.VariableName);
                                }
                            }
                            foreach (var property in scope.Properties)
                            {
                                if (!string.IsNullOrEmpty(activeSearchTerm) && !property.VariableName.Contains(activeSearchTerm, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    // Active search term not matched, skip it
                                    continue;
                                }

                                if (settings.IgnoreObsolete && (property.Attributes & VariableAttributes.Obsolete) == VariableAttributes.Obsolete)
                                {
                                    // Skip obsolete entries if that setting is enabled
                                    continue;
                                }

                                EditorGUI.BeginChangeCheck();
                                object newValue = VariableDrawer.Draw(objectPickerContext, property, OnOpenObjectPicker);
                                if (EditorGUI.EndChangeCheck() && (property.Attributes & VariableAttributes.ReadOnly) == VariableAttributes.None && property.DataType != DataType.Unknown)
                                {
                                    if (newValue != property.Value || property.Attributes.HasFlagByte(VariableAttributes.IsList) || property.Attributes.HasFlagByte(VariableAttributes.IsArray))
                                    {
                                        property.Value = newValue;
                                        APIManager.SendToPlayers(new SetVariableRequest(component.Guid, property));
                                    }
                                    //Debug.Log("Value changed in " + property.VariableName);
                                }
                            }

                            GUIStyle   expandButtonStyle = new GUIStyle(GUI.skin.button);
                            RectOffset padding           = expandButtonStyle.padding;
                            padding.left              = 0;
                            padding.right             = 1;
                            expandButtonStyle.padding = padding;

                            GUIStyle labelStyle = new GUIStyle(GUI.skin.label);
                            labelStyle.alignment = TextAnchor.MiddleRight;
                            GUIStyle normalButtonStyle = new GUIStyle(GUI.skin.button);
                            normalButtonStyle.padding   = normalButtonStyle.padding.SetLeft(100);
                            normalButtonStyle.alignment = TextAnchor.MiddleLeft;

                            foreach (var method in scope.Methods)
                            {
                                if (!string.IsNullOrEmpty(activeSearchTerm) && !method.MethodName.Contains(activeSearchTerm, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    // Active search term not matched, skip it
                                    continue;
                                }

                                if (settings.IgnoreObsolete && (method.MethodAttributes & MethodAttributes.Obsolete) == MethodAttributes.Obsolete)
                                {
                                    // Skip obsolete entries if that setting is enabled
                                    continue;
                                }

                                if (method.SafeToFire == false)
                                {
                                    EditorGUI.BeginDisabledGroup(true);
                                }

                                GUILayout.BeginHorizontal();
                                if (method.ReturnType == DataType.Void)
                                {
                                    labelStyle.normal.textColor = Color.grey;
                                }
                                else if ((method.ReturnTypeAttributes & VariableAttributes.IsValueType) == VariableAttributes.IsValueType)
                                {
                                    labelStyle.normal.textColor = new Color(0, 0, 1);
                                }
                                else
                                {
                                    labelStyle.normal.textColor = new Color32(255, 130, 0, 255);
                                }

                                string displayText = method.MethodName + " (" + method.ParameterCount + ")";

                                if ((method.MethodAttributes & MethodAttributes.Static) == MethodAttributes.Static)
                                {
                                    displayText += " [Static]";
                                }

                                if (method.SafeToFire == false)
                                {
                                    displayText += " [Unsupported]";
                                }

                                bool wasMethodExpanded = (method.Equals(expandedMethod));

                                if (GUILayout.Button(displayText, normalButtonStyle))
                                {
                                    if (wasMethodExpanded)
                                    {
                                        APIManager.SendToPlayers(new InvokeMethodRequest(component.Guid, method.MethodName, arguments.ToArray()));
                                    }
                                    else
                                    {
                                        // Not expanded, just use the default values
                                        List <WrappedVariable> defaultArguments = new List <WrappedVariable>();

                                        for (int i = 0; i < method.ParameterCount; i++)
                                        {
                                            WrappedParameter parameter = method.Parameters[i];
                                            defaultArguments.Add(new WrappedVariable(parameter));
                                        }

                                        APIManager.SendToPlayers(new InvokeMethodRequest(component.Guid, method.MethodName, defaultArguments.ToArray()));
                                    }
                                }

                                Rect lastRect = GUILayoutUtility.GetLastRect();
                                lastRect.xMax = normalButtonStyle.padding.left;
                                GUI.Label(lastRect, TypeUtility.NameForType(method.ReturnType), labelStyle);

                                if (method.ParameterCount > 0)
                                {
                                    bool isMethodExpanded = GUILayout.Toggle(wasMethodExpanded, "▼", expandButtonStyle, GUILayout.Width(20));
                                    GUILayout.EndHorizontal();

                                    if (isMethodExpanded != wasMethodExpanded) // has changed
                                    {
                                        if (isMethodExpanded)
                                        {
                                            // Reset the keyboard control as we don't want old text carrying over
                                            GUIUtility.keyboardControl = 0;

                                            expandedMethod = method;
                                            arguments      = new List <WrappedVariable>(method.ParameterCount);
                                            for (int i = 0; i < method.ParameterCount; i++)
                                            {
                                                WrappedParameter parameter = method.Parameters[i];
                                                arguments.Add(new WrappedVariable(parameter));
                                            }
                                        }
                                        else
                                        {
                                            expandedMethod = null;
                                            arguments      = null;
                                        }
                                    }
                                    else if (isMethodExpanded)
                                    {
                                        EditorGUI.indentLevel++;
                                        for (int i = 0; i < arguments.Count; i++)
                                        {
                                            var argument = arguments[i];
                                            argument.Value = VariableDrawer.Draw(new ObjectPickerContext(i), argument, OnOpenObjectPicker);
                                            //argument.Value = VariableDrawer.DrawIndividualVariable(null, argument, argument.VariableName, DataTypeHelper.GetSystemTypeFromWrappedDataType(argument.DataType), argument.Value, OnOpenObjectPicker);
                                        }

                                        //Rect buttonRect = GUILayoutUtility.GetRect(new GUIContent(), GUI.skin.button);
                                        //buttonRect = EditorGUI.IndentedRect(buttonRect);


                                        EditorGUI.indentLevel--;

                                        GUILayout.Space(10);
                                    }
                                }
                                else
                                {
                                    GUILayout.EndHorizontal();
                                }

                                if (method.SafeToFire == false)
                                {
                                    EditorGUI.EndDisabledGroup();
                                }
                            }
                        }
                    }
                }
                SidekickEditorGUI.DrawSplitter();
            }
            EditorGUILayout.EndScrollView();

            DrawOutputBox();
        }
コード例 #7
0
        void OnGUI()
        {
            // Frame rate tracking
            if (Event.current.type == EventType.Repaint)
            {
                AnimationHelper.UpdateTime();
            }

            GUILayout.Space(9);

            SidekickSettings settings = commonContext.Settings;


            EditorGUI.BeginChangeCheck();
            InspectionConnection newConnectionMode = (InspectionConnection)GUILayout.Toolbar((int)settings.InspectionConnection, new string[] { "Local", "Remote" }, new GUIStyle("LargeButton"));

            if (EditorGUI.EndChangeCheck())
            {
                SetConnectionMode(newConnectionMode);
            }

            settings.SearchTerm = searchField2.OnGUI(settings.SearchTerm);
            GUILayout.Space(3);
            EditorGUI.BeginChangeCheck();
#if UNITY_2017_3_OR_NEWER
            // EnumMaskField became EnumFlagsField in 2017.3
            settings.GetGameObjectFlags = (InfoFlags)EditorGUILayout.EnumFlagsField("Display", settings.GetGameObjectFlags);
#else
            settings.GetGameObjectFlags = (InfoFlags)EditorGUILayout.EnumMaskField("Display", settings.GetGameObjectFlags);
#endif
            if (EditorGUI.EndChangeCheck())
            {
                if (!string.IsNullOrEmpty(commonContext.SelectionManager.SelectedPath)) // Valid path?
                {
                    commonContext.APIManager.SendToPlayers(new GetGameObjectRequest(commonContext.SelectionManager.SelectedPath, commonContext.Settings.GetGameObjectFlags, commonContext.Settings.IncludeInherited));
                }
            }

            scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);

            if (gameObjectResponse != null)
            {
                string activeSearchTerm = settings.SearchTerm;

                foreach (ComponentDescription component in gameObjectResponse.Components)
                {
                    SidekickEditorGUI.DrawSplitter();
                    GUIStyle style = new GUIStyle(EditorStyles.foldout);
                    style.fontStyle = FontStyle.Bold;

                    Texture    icon       = IconLookup.GetIcon(component.TypeFullName);
                    GUIContent content    = new GUIContent(component.TypeShortName, icon, "Object Map ID: " + component.Guid.ToString());
                    float      labelWidth = EditorGUIUtility.labelWidth; // Cache label width
                    // Temporarily set the label width to full width so the icon is not squashed with long strings
                    EditorGUIUtility.labelWidth = position.width / 2f;

                    bool wasComponentExpanded = !settings.CollapsedTypeNames.Contains(component.TypeFullName);
                    bool isComponentExpanded  = wasComponentExpanded;
                    if (SidekickEditorGUI.DrawHeaderWithFoldout(content, isComponentExpanded))
                    {
                        isComponentExpanded = !isComponentExpanded;
                    }
                    EditorGUIUtility.labelWidth = labelWidth; // Restore label width
                    if (isComponentExpanded != wasComponentExpanded)
                    {
                        if (isComponentExpanded == false)
                        {
                            // Not expanded, so collapse it
                            settings.CollapsedTypeNames.Add(component.TypeFullName);
                        }
                        else
                        {
                            // Expanded, remove it from collapse list
                            settings.CollapsedTypeNames.Remove(component.TypeFullName);
                        }
                    }

                    if (isComponentExpanded)
                    {
                        foreach (var field in component.Fields)
                        {
                            if (!string.IsNullOrEmpty(activeSearchTerm) && !field.VariableName.Contains(activeSearchTerm, StringComparison.InvariantCultureIgnoreCase))
                            {
                                // Active search term not matched, skip it
                                continue;
                            }

                            if (settings.IgnoreObsolete && (field.Attributes & VariableAttributes.Obsolete) == VariableAttributes.Obsolete)
                            {
                                // Skip obsolete entries if that setting is enabled
                                continue;
                            }
                            EditorGUI.BeginChangeCheck();
                            object newValue = VariableDrawer.Draw(component, field, OnOpenObjectPicker);
                            if (EditorGUI.EndChangeCheck() && (field.Attributes & VariableAttributes.ReadOnly) == VariableAttributes.None && field.DataType != DataType.Unknown)
                            {
                                if (newValue != field.Value)
                                {
                                    field.Value = newValue;
                                    commonContext.APIManager.SendToPlayers(new SetVariableRequest(component.Guid, field));
                                }

                                //Debug.Log("Value changed in " + field.VariableName);
                            }
                        }
                        foreach (var property in component.Properties)
                        {
                            if (!string.IsNullOrEmpty(activeSearchTerm) && !property.VariableName.Contains(activeSearchTerm, StringComparison.InvariantCultureIgnoreCase))
                            {
                                // Active search term not matched, skip it
                                continue;
                            }

                            if (settings.IgnoreObsolete && (property.Attributes & VariableAttributes.Obsolete) == VariableAttributes.Obsolete)
                            {
                                // Skip obsolete entries if that setting is enabled
                                continue;
                            }

                            EditorGUI.BeginChangeCheck();
                            object newValue = VariableDrawer.Draw(component, property, OnOpenObjectPicker);
                            if (EditorGUI.EndChangeCheck() && (property.Attributes & VariableAttributes.ReadOnly) == VariableAttributes.None && property.DataType != DataType.Unknown)
                            {
                                if (newValue != property.Value)
                                {
                                    property.Value = newValue;
                                    commonContext.APIManager.SendToPlayers(new SetVariableRequest(component.Guid, property));
                                }
                                //Debug.Log("Value changed in " + property.VariableName);
                            }
                        }

                        GUIStyle   expandButtonStyle = new GUIStyle(GUI.skin.button);
                        RectOffset padding           = expandButtonStyle.padding;
                        padding.left              = 0;
                        padding.right             = 1;
                        expandButtonStyle.padding = padding;

                        GUIStyle labelStyle = new GUIStyle(GUI.skin.label);
                        labelStyle.alignment = TextAnchor.MiddleRight;
                        GUIStyle normalButtonStyle = new GUIStyle(GUI.skin.button);
                        normalButtonStyle.padding   = normalButtonStyle.padding.SetLeft(100);
                        normalButtonStyle.alignment = TextAnchor.MiddleLeft;

                        foreach (var method in component.Methods)
                        {
                            if (!string.IsNullOrEmpty(activeSearchTerm) && !method.MethodName.Contains(activeSearchTerm, StringComparison.InvariantCultureIgnoreCase))
                            {
                                // Active search term not matched, skip it
                                continue;
                            }

                            if (settings.IgnoreObsolete && (method.MethodAttributes & MethodAttributes.Obsolete) == MethodAttributes.Obsolete)
                            {
                                // Skip obsolete entries if that setting is enabled
                                continue;
                            }

                            GUILayout.BeginHorizontal();
                            if (method.ReturnType == DataType.Void)
                            {
                                labelStyle.normal.textColor = Color.grey;
                            }
                            else if ((method.ReturnTypeAttributes & VariableAttributes.IsValueType) == VariableAttributes.IsValueType)
                            {
                                labelStyle.normal.textColor = new Color(0, 0, 1);
                            }
                            else
                            {
                                labelStyle.normal.textColor = new Color32(255, 130, 0, 255);
                            }

                            string displayText = method.MethodName + " (" + method.ParameterCount + ")";

                            if ((method.MethodAttributes & MethodAttributes.Static) == MethodAttributes.Static)
                            {
                                displayText += " [Static]";
                            }

                            if (GUILayout.Button(displayText, normalButtonStyle))
                            {
                                List <WrappedVariable> defaultArguments = new List <WrappedVariable>();

                                for (int i = 0; i < method.ParameterCount; i++)
                                {
                                    //Type type = DataTypeHelper.GetSystemTypeFromWrappedDataType(method.Parameters[i].DataType);

                                    WrappedParameter parameter = method.Parameters[i];
                                    defaultArguments.Add(new WrappedVariable(parameter));
                                }

                                commonContext.APIManager.SendToPlayers(new InvokeMethodRequest(component.Guid, method.MethodName, defaultArguments.ToArray()));
                            }

                            Rect lastRect = GUILayoutUtility.GetLastRect();
                            lastRect.xMax = normalButtonStyle.padding.left;
                            GUI.Label(lastRect, TypeUtility.NameForType(method.ReturnType), labelStyle);

                            if (method.ParameterCount > 0)
                            {
                                bool wasMethodExpanded = (method.Equals(expandedMethod));
                                bool isMethodExpanded  = GUILayout.Toggle(wasMethodExpanded, "▼", expandButtonStyle, GUILayout.Width(20));
                                GUILayout.EndHorizontal();

                                if (isMethodExpanded != wasMethodExpanded)                                 // has changed
                                {
                                    if (isMethodExpanded)
                                    {
                                        expandedMethod = method;
                                        arguments      = new List <WrappedVariable>(method.ParameterCount);
                                        for (int i = 0; i < method.ParameterCount; i++)
                                        {
                                            WrappedParameter parameter = method.Parameters[i];
                                            arguments.Add(new WrappedVariable(parameter));
                                        }
                                    }
                                    else
                                    {
                                        expandedMethod = null;
                                        arguments      = null;
                                    }
                                }
                                else if (isMethodExpanded)
                                {
                                    EditorGUI.indentLevel++;
                                    foreach (var argument in arguments)
                                    {
                                        argument.Value = VariableDrawer.Draw(null, argument, OnOpenObjectPicker);
                                        //argument.Value = VariableDrawer.DrawIndividualVariable(null, argument, argument.VariableName, DataTypeHelper.GetSystemTypeFromWrappedDataType(argument.DataType), argument.Value, OnOpenObjectPicker);
                                    }

                                    Rect buttonRect = GUILayoutUtility.GetRect(new GUIContent(), GUI.skin.button);
                                    buttonRect = EditorGUI.IndentedRect(buttonRect);

                                    if (GUI.Button(buttonRect, "Fire"))
                                    {
                                        commonContext.APIManager.SendToPlayers(new InvokeMethodRequest(component.Guid, method.MethodName, arguments.ToArray()));
                                    }
                                    EditorGUI.indentLevel--;

                                    GUILayout.Space(10);
                                }
                            }
                            else
                            {
                                GUILayout.EndHorizontal();
                            }
                        }
                    }
                }
                SidekickEditorGUI.DrawSplitter();
            }
            EditorGUILayout.EndScrollView();

            DrawOutputBox();
        }