/// <summary>
 /// Caches the owner GameObject. Call this if you want to reference automatically the owner
 /// for example for an event target.
 /// note: It's really odd, cause I can't get serializedObject.targetObject to work...
 /// </summary>
 public void CacheOwnerGameObject(SerializedObject serializedObject)
 {
     if (_ownerGameObject == null)
     {
         _ownerGameObject = PlayMakerInspectorUtils.GetGameObject(serializedObject);
     }
 }
        public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
        {
            _target = PlayMakerInspectorUtils.GetBaseProperty <PlayMakerFsmVariable>(property);

            // TODO: allow option to force a particular type of variable
            ScanAttributesIfNeeded(property);

            rowCount = _noVariablesSelectable?2:3;             // ideal scenario


            // we let the user choose amongst globavariables if not target attribute and when target is defined.
            // else we error out
            if (_variabletargetTarget != null && !_variabletargetTarget.isTargetAvailable)
            {
                rowCount = 1;
            }

            return(base.GetPropertyHeight(property, label) * (rowCount));
        }
        void ScanAttributesIfNeeded(SerializedProperty property)
        {
            if (!attributeScanned)
            {
                attributeScanned = true;


                // check for FsmVariableTargetVariable Attribute
                object[] _variableTargets = this.fieldInfo.GetCustomAttributes(typeof(FsmVariableTargetVariable), true);

                if (_variableTargets.Length > 0)
                {
                    string variableName = (_variableTargets[0] as FsmVariableTargetVariable).variable;
                    variableTargetVariable = property.serializedObject.FindProperty(variableName);

                    _variabletargetTarget = PlayMakerInspectorUtils.GetBaseProperty <PlayMakerFsmVariableTarget>(variableTargetVariable);
                }

                if (variableTargetVariable != null)
                {
                    variableTarget    = variableTargetVariable.FindPropertyRelative("variableTarget");
                    gameObject        = variableTargetVariable.FindPropertyRelative("gameObject");
                    fsmComponent      = variableTargetVariable.FindPropertyRelative("fsmComponent");
                    isTargetAvailable = variableTargetVariable.FindPropertyRelative("isTargetAvailable");
                }

                // check for FsmVariableType Attribute
                //	object[] _variableTypes = this.fieldInfo.GetCustomAttributes(typeof(),true);

                /*
                 * if (_variableTypes.Length>0)
                 * {
                 *      VariableType variableType = (_variableTypes[0] as FsmVariableType).variableType;
                 * }
                 */
            }
        }
        public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
        {
            rowCount = 0;

            if (!attributeScanned)
            {
                attributeScanned = true;

                // check for EventTargetVariable Attribute
                object[] _evenTargets = this.fieldInfo.GetCustomAttributes(typeof(EventTargetVariable), true);

                if (_evenTargets.Length > 0)
                {
                    string variableName = (_evenTargets[0] as EventTargetVariable).variable;
                    eventTargetVariable = property.serializedObject.FindProperty(variableName);
                }
            }

            if (eventTargetVariable != null)
            {
                try{
                    eventTarget     = eventTargetVariable.FindPropertyRelative("eventTarget");
                    includeChildren = eventTargetVariable.FindPropertyRelative("includeChildren");
                    gameObject      = eventTargetVariable.FindPropertyRelative("gameObject");
                    fsmComponent    = eventTargetVariable.FindPropertyRelative("fsmComponent");
                }catch (Exception e)
                {
                }
            }


            CacheOwnerGameObject(property.serializedObject);

            eventName = property.FindPropertyRelative("eventName");
            string _eventName = eventName.stringValue;


            if (eventTargetVariable != null)
            {
                try{
                    eventTarget = eventTargetVariable.FindPropertyRelative("eventTarget");
                }catch (Exception e)
                {
                    var _sel = Selection.activeGameObject;

                    Selection.activeGameObject = null;
                    AssetDatabase.Refresh();
                    Selection.activeGameObject = _sel;

                    return(16f);
                }
            }

            string[] _eventList = new string[0];

            bool isEventImplemented = false;



            // Get the list of events
            if (eventTarget == null || eventTarget.enumValueIndex == 2)         // Undefined || broadcastAll
            {
                _eventList = PlayMakerInspectorUtils.GetGlobalEvents(true);
            }
            else if (eventTarget.enumValueIndex == 0 || eventTarget.enumValueIndex == 1)          // Owner || GameObject
            {
                _eventList = PlayMakerInspectorUtils.GetGlobalEvents(true);
                if (gameObject != null)
                {
                    isEventImplemented = PlayMakerInspectorUtils.DoesTargetImplementsEvent((GameObject)gameObject.objectReferenceValue, _eventName, true);
                }
            }
            else if (eventTarget.enumValueIndex == 3)              // FsmComponent
            {
                PlayMakerFSM _fsm = (PlayMakerFSM)fsmComponent.objectReferenceValue;
                _eventList = PlayMakerInspectorUtils.GetImplementedGlobalEvents(_fsm, true);

                isEventImplemented = PlayMakerInspectorUtils.DoesTargetImplementsEvent(_fsm, _eventName);
            }

            int selected = 0;

            if (!string.IsNullOrEmpty(_eventName))
            {
                selected = ArrayUtility.IndexOf <string>(_eventList, _eventName);
            }

            rowCount++;

            // feedback
            if (selected == -1)
            {
                rowCount++;
            }

            if (eventTarget != null)
            {
                if (selected != 0 && eventTarget.enumValueIndex != 2)            // not none and not broadcasting
                {
                    if (selected > 0 && !isEventImplemented)
                    {
                        rowCount++;
                    }
                }
            }



            return(base.GetPropertyHeight(property, label) * (rowCount));
        }
        public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
        {
            if (!attributeScanned)
            {
                attributeScanned = true;

                // check for EventTargetVariable Attribute
                object[] _evenTargets = this.fieldInfo.GetCustomAttributes(typeof(EventTargetVariable), true);

                if (_evenTargets.Length > 0)
                {
                    string variableName = (_evenTargets[0] as EventTargetVariable).variable;
                    eventTargetVariable = prop.serializedObject.FindProperty(variableName);
                }

                /// check for the ShowOptions attribute
                object[] _showOptions = this.fieldInfo.GetCustomAttributes(typeof(ShowOptions), true);

                if (_showOptions.Length > 0)
                {
                    showOptions = true;
                }
            }

            if (eventTargetVariable != null)
            {
                try{
                    eventTarget     = eventTargetVariable.FindPropertyRelative("eventTarget");
                    includeChildren = eventTargetVariable.FindPropertyRelative("includeChildren");
                    gameObject      = eventTargetVariable.FindPropertyRelative("gameObject");
                    fsmComponent    = eventTargetVariable.FindPropertyRelative("fsmComponent");
                }catch (Exception e)
                {
                    Selection.activeGameObject = null;
                    return;
                }
            }

            eventName = prop.FindPropertyRelative("eventName");
            string _eventName = eventName.stringValue;

            allowLocalEvents = prop.FindPropertyRelative("allowLocalEvents");
            bool _allowEvent = allowLocalEvents.boolValue;

            defaultEventName      = prop.FindPropertyRelative("defaultEventName");
            defaultEventNameValue = defaultEventName.stringValue;

            CacheOwnerGameObject(prop.serializedObject);

            int row = 0;

            string[] _eventList = new string[0];

            bool isEventImplemented = false;


            // Get the list of events
            if (eventTarget == null || eventTarget.enumValueIndex == 2)         // Undefined || broadcastAll
            {
                _eventList = PlayMakerInspectorUtils.GetGlobalEvents(true);
            }
            else if (eventTarget.enumValueIndex == 0 || eventTarget.enumValueIndex == 1)          // Owner || GameObject
            {
                _eventList         = PlayMakerInspectorUtils.GetGlobalEvents(true);
                isEventImplemented = PlayMakerInspectorUtils.DoesTargetImplementsEvent((GameObject)gameObject.objectReferenceValue, _eventName, true);
            }
            else if (eventTarget.enumValueIndex == 3)              // FsmComponent
            {
                PlayMakerFSM _fsm = (PlayMakerFSM)fsmComponent.objectReferenceValue;
                _eventList = PlayMakerInspectorUtils.GetImplementedGlobalEvents(_fsm, true);

                isEventImplemented = PlayMakerInspectorUtils.DoesTargetImplementsEvent(_fsm, _eventName);
            }

            // find the index of the serialized event name in the list of events
            int selected = 0;

            if (!string.IsNullOrEmpty(_eventName))
            {
                selected = ArrayUtility.IndexOf <string>(_eventList, _eventName);
            }

            Rect _rect = GetRectforRow(pos, ++row - 1);

            if (showOptions)
            {
                _rect.width -= 18;
            }

            string _popupLabel = label.text;

            if (selected != 0 && eventTarget != null && eventTarget.enumValueIndex != 2)      // not none and not broadcasting
            {
                if ((selected > 0 && !isEventImplemented) || selected == -1)
                {
                    //_popup = GUI.skin.GetStyle("ErrorLabel");
                    GUIStyle labelStyle = GUI.skin.GetStyle("controlLabel");
                    labelStyle.richText = true;

                    _popupLabel = "<color=red>" + _popupLabel + "</color>";
                }
            }

            // Event Popup
            Rect _contentRect = EditorGUI.PrefixLabel(_rect, label);

            //_contentRect.width -= 0;
            if (GUI.Button(
                    _contentRect,
                    string.IsNullOrEmpty(_eventName)?"none":_eventName,
                    EditorStyles.popup))
            {
                GenericMenu menu = GenerateEventMenu(_eventList, _eventName);
                menu.DropDown(_rect);
            }

            /*
             * _rect.x =_rect.xMax-10;
             * _rect.width = 10;
             *
             * if (GUI.Button(_rect,"?","label"))
             * {
             *      //buttonRect.x += FsmEditor.Window.position.x + FsmEditor.Window.position.width - FsmEditor.InspectorPanelWidth;
             *      //buttonRect.y += FsmEditor.Window.position.y + StateInspector.ActionsPanelRect.y + 3 - FsmEditor.StateInspector.scrollPosition.y;
             *      //var newVariableWindow = PlayMakerEditor.  NewEventWindow.CreateDropdown("New Global Event", _contentRect, eventName);
             *      //newVariableWindow.EditCommited += DoNewGlobalEvent;
             * }
             */
            _rect.x     = _rect.xMax + 2;
            _rect.width = 18;

            if (showOptions)
            {
                if (GUI.Button(_rect, FsmEditorContent.SettingsButton, "label"))
                {
                    GenericMenu menu = new GenericMenu();

                    if (eventTarget != null && eventTarget.enumValueIndex != 2)                    // not a broadcast call
                    {
                        menu.AddItem(new GUIContent("Show All global Events"), false, ShowAllEvents);
                        menu.AddItem(new GUIContent("Show local Event"), false, ShowImplementedEvents);

                        menu.AddSeparator("");
                    }

                    menu.AddItem(new GUIContent("Reset"), false, ResetToDefault);

                    menu.ShowAsContext();
                }
            }

            // feedback
            if (selected == -1)
            {
                EditorGUI.LabelField(
                    GetRectforRow(pos, ++row - 1),
                    "<color=red>missing event</color>",
                    "<color=red>" + _eventName + "</color>"
                    );
            }


            if (selected != 0 && eventTarget != null && eventTarget.enumValueIndex != 2)      // not none and not broadcasting
            {
                if (selected > 0 && !isEventImplemented)
                {
                    EditorGUI.LabelField(
                        GetRectforRow(pos, ++row - 1),
                        " ",
                        "<color=red>Not implemented on target</color>"
                        );
                }
            }

            // attempt to refresh UI and avoid glitch
            if (row != rowCount)
            {
                prop.serializedObject.ApplyModifiedProperties();
                prop.serializedObject.Update();
            }
            rowCount = row;
        }
        public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
        {
            int row = 0;

            // set style to use rich text.
            if (controlLabelStyle == null)
            {
                controlLabelStyle          = GUI.skin.GetStyle("ControlLabel");
                controlLabelStyle.richText = true;
            }


            ScanAttributesIfNeeded(prop);

            // we let the user choose amongst globavariables if not target attribute and when target is defined.
            if (variableTargetVariable != null && isTargetAvailable != null && !isTargetAvailable.boolValue)
            {
                EditorGUI.LabelField(
                    GetRectforRow(pos, ++row - 1),
                    " ",
                    "<color=red>Target is undefined</color>"
                    );

                return;
            }


            variableSelectionChoice = prop.FindPropertyRelative("variableSelectionChoice");
            int _variableSelectionChoiceIndex = variableSelectionChoice.enumValueIndex;

            selectedType = prop.FindPropertyRelative("selectedType");
            VariableType _selectedType = PlayMakerInspectorUtils.GetVariableTypeFromEnumIndex(selectedType.enumValueIndex);

            //	PlayMakerInspectorUtils.GetVariableTypeFromEnumIndex(variableSelectionChoice.enumValueIndex);


            //VariableType _variableType = (VariableType)Enum.GetValues(typeof(VariableType)).GetValue(variableType.enumValueIndex);
            //Debug.Log(variableSelectionChoice.enumValueIndex+" "+_variableSelectionChoice);

            variableName = prop.FindPropertyRelative("variableName");
            string _variableName = variableName.stringValue;

            defaultVariableName      = prop.FindPropertyRelative("defaultVariableName");
            defaultVariableNameValue = defaultVariableName.stringValue;

            CacheOwnerGameObject(prop.serializedObject);


            bool _isTargetAvailable = _variabletargetTarget.isTargetAvailable;

            //Debug.Log("GetVariablesStringList _isTargetAvailable?"+_isTargetAvailable);

            if (_isTargetAvailable)
            {
                // variable type selection
                Rect _typeRect = GetRectforRow(pos, ++row - 1);

                EditorGUI.PropertyField(
                    _typeRect,
                    variableSelectionChoice, new GUIContent("Variable Type"), true);

                VariableSelectionChoice _variableSelectionChoice = VariableSelectionChoice.Any;

                if (variableSelectionChoice.enumValueIndex != _variableSelectionChoiceIndex)
                {
                    _variableSelectionChoice =
                        (VariableSelectionChoice)Enum
                        .GetValues(typeof(VariableSelectionChoice))
                        .GetValue(variableSelectionChoice.enumValueIndex);


                    _variableSelectionChoiceIndex = variableSelectionChoice.enumValueIndex;
                    //Debug.Log ("Hello _variableSelectionChoice"+_variableSelectionChoice+" _variableSelectionChoiceIndex"+_variableSelectionChoiceIndex+" _selectedType"+_selectedType+" variableType"+PlayMakerFsmVariable.GetTypeFromChoice(_variableSelectionChoice));
                    if (_variableSelectionChoiceIndex > 0 && _selectedType != PlayMakerFsmVariable.GetTypeFromChoice(_variableSelectionChoice))
                    {
                        //	Debug.Log("reset variable name");
                        _variableName            = "";
                        variableName.stringValue = _variableName;
                    }
                }
                else
                {
                    _variableSelectionChoice =
                        (VariableSelectionChoice)Enum
                        .GetValues(typeof(VariableSelectionChoice))
                        .GetValue(variableSelectionChoice.enumValueIndex);
                }


                string[] _variableList = new string[0];

                bool isVariableImplemented = false;                 // not in use, TODO: clean up


                // Get the list of events
                _variableList = PlayMakerInspectorUtils.GetVariablesStringList
                                (
                    _variabletargetTarget.FsmVariables,
                    true,
                    PlayMakerFsmVariable.GetTypeFromChoice(_variableSelectionChoice)
                                );


                _noVariablesSelectable = _variableList.Length <= 1;

                // find the index of the serialized event name in the list of events
                int selected = 0;
                if (!string.IsNullOrEmpty(_variableName))
                {
                    //Debug.Log("?!");
                    selected = ArrayUtility.IndexOf <string>(_variableList, _variableName);
                }

                // set to none if not found
                if (selected == -1)
                {
                    _variableName            = "";
                    variableName.stringValue = _variableName;
                    selected = 0;
                }



                if (!_noVariablesSelectable)
                {
                    Rect _rect = GetRectforRow(pos, ++row - 1);

                    string _popupLabel = label.text;

                    if (selected != 0 && variableTarget != null && variableTarget.enumValueIndex != 2)              // not none and not globalVariables
                    {
                        if ((selected > 0 && !isVariableImplemented) || selected == -1)
                        {
                            _popupLabel = "<color=red>" + _popupLabel + "</color>";
                        }
                    }


                    // Variable Popup
                    Rect _contentRect = EditorGUI.PrefixLabel(_rect, label);
                    //_contentRect.width -= 0;
                    if (GUI.Button(
                            _contentRect,
                            string.IsNullOrEmpty(_variableName)?"none":_variableName,
                            EditorStyles.popup))
                    {
                        GenericMenu menu = GenerateVariableMenu(_variableList, _variableName);
                        menu.DropDown(_rect);
                    }
                }

                if (_target.GetVariable(_variabletargetTarget))
                {
                    EditorGUI.LabelField(
                        GetRectforRow(pos, ++row - 1),
                        " ",
                        _target.namedVariable.ToString()
                        );
                }
                else
                {
                    string _feedbackMessage = _noVariablesSelectable?"No " + _variableSelectionChoice + "(s) variable in target":"Please Select a variable";
                    string _feedbackLabel   = _noVariablesSelectable?"":" ";
                    EditorGUI.LabelField(
                        GetRectforRow(pos, ++row - 1),
                        _feedbackLabel,
                        "<color=red>" + _feedbackMessage + "</color>"
                        );
                }
            }
            else
            {
                EditorGUI.LabelField(
                    GetRectforRow(pos, ++row - 1),
                    " ",
                    "<color=red>Select a valid target</color>"
                    );
            }
            // attempt to refresh UI and avoid glitch
            if (row != rowCount)
            {
                prop.serializedObject.ApplyModifiedProperties();
                prop.serializedObject.Update();
            }

            rowCount = row;
        }
Example #7
0
        public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
        {
            _target = PlayMakerInspectorUtils.GetBaseProperty <PlayMakerFsmVariableTarget>(prop);

            bool isDirty = false;

            fsmVariableTarget = prop.FindPropertyRelative("variableTarget");
            int _variableTargetIndex = fsmVariableTarget.enumValueIndex;

            gameObject   = prop.FindPropertyRelative("gameObject");
            fsmName      = prop.FindPropertyRelative("fsmName");
            fsmComponent = prop.FindPropertyRelative("_fsmComponent");

            CacheOwnerGameObject(prop.serializedObject);

            int row = 0;

            // draw the enum popup Field
            int oldEnumIndex = fsmVariableTarget.enumValueIndex;

            // force the GameObject value to be the owner when switching to it
            // this is just to fall back nicely on a preset that is the expected one, as opposed to target nothing
            if (oldEnumIndex == 0 && gameObject.objectReferenceValue != ownerGameObject)
            {
                gameObject.objectReferenceValue = ownerGameObject;
                fsmName.stringValue             = "";
                isDirty = true;
            }

            EditorGUI.PropertyField(
                GetRectforRow(pos, ++row - 1),
                fsmVariableTarget, label, true);

            if (_variableTargetIndex != fsmVariableTarget.enumValueIndex)
            {
                prop.serializedObject.ApplyModifiedProperties();
                prop.serializedObject.Update();
                _target.Initialize(true);

                //Debug.Log("Initialized isTargetAvailable?"+_target.isTargetAvailable);
                return;
            }

            // force the GameObject value to be the owner when switching to it
            // this is just to fall back nicely on a preset that is the expected one, as opposed to target nothing
            if (oldEnumIndex == 0 && gameObject.objectReferenceValue != ownerGameObject)
            {
                gameObject.objectReferenceValue = ownerGameObject;
                fsmName.stringValue             = "";
                isDirty = true;
            }

            // Additional fields
            if (fsmVariableTarget.enumValueIndex == 0 || fsmVariableTarget.enumValueIndex == 1)         // targeting Owner or GameObject:
            {
                if (string.IsNullOrEmpty(fsmName.stringValue) || !updateFsmList())
                {
                    GameObject _go = (GameObject)gameObject.objectReferenceValue;
                    if (_go != null)
                    {
                        PlayMakerFSM _fsm = _go.GetComponent <PlayMakerFSM>();
                        if (_fsm != null)
                        {
                            fsmName.stringValue = _fsm.FsmName;
                            isDirty             = true;
                        }
                    }
                }

                EditorGUI.indentLevel++;

                if (fsmVariableTarget.enumValueIndex == 1)
                {
                    int _goId = gameObject.objectReferenceInstanceIDValue;
                    EditorGUI.PropertyField(
                        GetRectforRow(pos, ++row - 1),
                        gameObject, new GUIContent("Game Object"), true);

                    if (_goId != gameObject.objectReferenceInstanceIDValue)
                    {
                        isDirty = true;
                    }
                }

                Rect _rect = GetRectforRow(pos, ++row - 1);


                string _name      = fsmName.stringValue;
                Rect   _fieldRect = new Rect(_rect);
                _fieldRect.width -= 18;
                EditorGUI.PropertyField(
                    _fieldRect,
                    fsmName, new GUIContent("Fsm Name"), true);

                if (_name != fsmName.stringValue)
                {
                    isDirty = true;
                }

                _rect.xMin = _rect.xMax - 16;

                // Fsm Name Popup
                if (GUI.Button(
                        _rect,
                        "",
                        EditorStyles.popup)
                    )
                {
                    updateFsmList();

                    GenericMenu menu = GenerateFsmMenu(fsmList, fsmName.stringValue);
                    menu.DropDown(_fieldRect);

                    // move the focus out to reflect the change of the menu selection
                    GUI.SetNextControlName("noFocus");
                    GUI.FocusControl("noFocus");
                }


                EditorGUI.indentLevel--;
            }
            else if (fsmVariableTarget.enumValueIndex == 3)              // targeting  FsmComponent;

            {
                EditorGUI.indentLevel++;

                int _objId = fsmComponent.objectReferenceInstanceIDValue;
                EditorGUI.PropertyField(
                    GetRectforRow(pos, ++row - 1),
                    fsmComponent, new GUIContent("Fsm Component"), true);

                if (_objId != fsmComponent.objectReferenceInstanceIDValue)
                {
                    Debug.Log("yo " + _objId + " " + fsmComponent.objectReferenceInstanceIDValue);
                    isDirty = true;
                }

                EditorGUI.indentLevel--;
            }

            // attempt to refresh UI and avoid glitch
            if (row != rowCount || isDirty)
            {
                prop.serializedObject.ApplyModifiedProperties();
                prop.serializedObject.Update();

                _target.Initialize(true);
            }



            // update the rowCount to compute the right interface height
            rowCount = row;
        }