Beispiel #1
0
        /// <summary>
        /// Draws all of the states.
        /// </summary>
        public void OnStateListDraw(Rect rect, int index, bool isActive, bool isFocused)
        {
            if (rect.width < 0)
            {
                return;
            }

            var profileIndex = EditorPrefs.GetInt(SelectedProfileKey, 0);
            var profile      = m_StateConfiguration.Profiles[profileIndex];

            if (index >= profile.StateElements.Length)
            {
                return;
            }

            var stateElement = profile.StateElements[index];

            // Setup the field sizings.
            var fieldWidth     = rect.width / 3;
            var blockedByWidth = Mathf.Max(c_MinBlockedByWidth, Mathf.Min(c_MaxBlockedByWidth, fieldWidth)) + EditorGUI.indentLevel * InspectorUtility.IndentWidth;

            fieldWidth = (rect.width - blockedByWidth) / 2 - (c_WidthBuffer * 3);
            var presetWidth = Mathf.Min(c_MaxPresetWidth, fieldWidth) + EditorGUI.indentLevel * 30;
            var nameWidth   = Mathf.Max(0, rect.width - presetWidth - blockedByWidth - (c_WidthBuffer * 4)) + EditorGUI.indentLevel * InspectorUtility.IndentWidth * 3;
            var startRectX  = rect.x;

            GUI.enabled = !stateElement.Default;
            var desiredName = EditorGUI.TextField(new Rect(startRectX, rect.y + 1, nameWidth, EditorGUIUtility.singleLineHeight), stateElement.Name);

            if (desiredName != stateElement.Name && IsUniqueStateName(profile.StateElements, stateElement, desiredName))
            {
                stateElement.Name = desiredName;
            }
            startRectX += nameWidth + c_WidthBuffer - EditorGUI.indentLevel * InspectorUtility.IndentWidth;

            var preset = EditorGUI.ObjectField(new Rect(startRectX, rect.y + 1, presetWidth,
                                                        EditorGUIUtility.singleLineHeight), string.Empty, stateElement.Preset, typeof(PersistablePreset), false) as PersistablePreset;

            if (preset != stateElement.Preset)
            {
                // If the preset is just set then ensure the state name doesn't conflict with any other state name.
                stateElement.Preset = preset;
                var name  = stateElement.Name;
                var count = 1;
                while (!IsUniqueStateName(profile.StateElements, stateElement, name))
                {
                    name = stateElement.Name + " " + count;
                    count++;
                }
                stateElement.Name = name;
                m_StateConfiguration.ResetInitialization();
            }

            startRectX += presetWidth + c_WidthBuffer - EditorGUI.indentLevel * InspectorUtility.IndentWidth;

            // Create a popup of the states that can block the current state. There are several conditions which would prevent a state from being able to block
            // another state so this popup has to first be filtered.
            var stateName = stateElement.Name;
            var blockList = stateElement.BlockList;
            var allStates = new List <string>();
            var selected  = 0;

            if (stateElement.Preset != null)
            {
                var objType = stateElement.Preset.Data.ObjectType;
                for (int i = 0; i < profile.StateElements.Length; ++i)
                {
                    var currentState = profile.StateElements[i];

                    // The current state cannot block another object type.
                    if (currentState.Preset == null || objType != currentState.Preset.Data.ObjectType)
                    {
                        continue;
                    }

                    string name;
                    // The current state cannot block itself.
                    if ((name = currentState.Name) == stateName)
                    {
                        continue;
                    }
                    // The selected state cannot block the current state if the current state blocks the selected state.
                    var currentStateBlockList = currentState.BlockList;
                    var canAdd = true;
                    if (currentStateBlockList != null)
                    {
                        for (int j = 0; j < currentStateBlockList.Length; ++j)
                        {
                            if (stateName == currentStateBlockList[j])
                            {
                                canAdd = false;
                                break;
                            }
                        }
                    }

                    // canAdd will be false if the current state is blocking the selected state.
                    if (!canAdd)
                    {
                        continue;
                    }

                    // The current state can block the selected state. Add the name to the popup and determine if the state is selected. A mask is used
                    // to allow multiple selected states.
                    allStates.Add(name);
                    if (blockList != null)
                    {
                        for (int j = 0; j < blockList.Length; ++j)
                        {
                            if (allStates[allStates.Count - 1] == blockList[j])
                            {
                                selected |= 1 << (allStates.Count - 1);
                                break;
                            }
                        }
                    }
                }
            }
            else
            {
                GUI.enabled = false;
            }
            // At least one value needs to exist.
            if (allStates.Count == 0)
            {
                allStates.Add("Nothing");
            }

            // Draw the actual popup.
            var blockMask = EditorGUI.MaskField(new Rect(startRectX, rect.y + 1, blockedByWidth, EditorGUIUtility.singleLineHeight), string.Empty, selected, allStates.ToArray());

            if (blockMask != selected)
            {
                var stateNames = new List <string>();
                for (int i = 0; i < allStates.Count; ++i)
                {
                    // If the state index is within the block mask then that state should be added to the list. A blockMask of -1 indicates Everything.
                    if (((1 << i) & blockMask) != 0 || blockMask == -1)
                    {
                        stateNames.Add(allStates[i]);
                    }
                }
                stateElement.BlockList = stateNames.ToArray();
            }
            GUI.enabled = true;
        }