/// <summary> /// Adds a new state element to the list. /// </summary> public void OnStateListAdd(ReorderableList list) { var profileIndex = EditorPrefs.GetInt(SelectedProfileKey, 0); var states = m_StateConfiguration.Profiles[profileIndex].StateElements; if (states == null) { states = new StateConfiguration.Profile.StateElement[1]; } else { Array.Resize(ref states, states.Length + 1); } list.list = m_StateConfiguration.Profiles[profileIndex].StateElements = states; m_StateReorderableList.displayAdd = true; m_StateReorderableList.displayRemove = true; m_StateConfiguration.ResetInitialization(); Shared.Editor.Utility.EditorUtility.RecordUndoDirtyObject(target, "Change Value"); EditorUtility.SetDirty(target); }
/// <summary> /// Draws the custom inspector. /// </summary> public override void OnInspectorGUI() { base.OnInspectorGUI(); GUILayout.Space(10); EditorGUILayout.BeginHorizontal(); m_CopyFromObject = EditorGUILayout.ObjectField("Copy From", m_CopyFromObject, typeof(GameObject), true) as GameObject; GUI.enabled = m_CopyFromObject != null; m_CopyType = (CopyType)EditorGUILayout.EnumPopup(m_CopyType, GUILayout.MaxWidth(70)); if (GUILayout.Button("Copy", GUILayout.MaxWidth(70))) { CopyFromGameObject(m_CopyFromObject); m_StateReorderableList = null; EditorPrefs.SetInt(SelectedProfileKey, m_StateConfiguration.Profiles.Length - 1); } GUI.enabled = true; EditorGUILayout.EndHorizontal(); GUILayout.Space(15); EditorGUI.BeginChangeCheck(); GUILayout.BeginHorizontal(); // Convert the state index into a string. var stateNames = new List <string>(); if (m_StateConfiguration.Profiles == null || m_StateConfiguration.Profiles.Length == 0) { stateNames.Add("(None)"); } if (m_StateConfiguration.Profiles != null) { for (int i = 0; i < m_StateConfiguration.Profiles.Length; ++i) { stateNames.Add(m_StateConfiguration.Profiles[i].Name); } } var prevSelectedProfile = EditorPrefs.GetInt(SelectedProfileKey, 0); var selectedProfileIndex = EditorGUILayout.Popup("Selected Profile", prevSelectedProfile, stateNames.ToArray()); // If the profile index changed then the reorderable list should be set to null so the reorderable list can refresh. if (selectedProfileIndex != prevSelectedProfile) { EditorPrefs.SetInt(SelectedProfileKey, selectedProfileIndex); m_StateReorderableList = null; } if (GUILayout.Button(InspectorStyles.AddIcon, InspectorStyles.NoPaddingButtonStyle, GUILayout.Width(18))) { // Add a new profile. var profiles = m_StateConfiguration.Profiles; Array.Resize(ref profiles, profiles != null ? profiles.Length + 1 : 1); var profile = new StateConfiguration.Profile(); var count = profiles.Length; var profileName = string.Empty; do { profileName = "Profile " + count; count++; } while (!IsUniqueProfileName(profileName)); profile.Name = profileName; profiles[profiles.Length - 1] = profile; m_StateConfiguration.Profiles = profiles; selectedProfileIndex = m_StateConfiguration.Profiles.Length - 1; EditorPrefs.SetInt(SelectedProfileKey, selectedProfileIndex); // Set the reorderableList to null and return so the correct array will be used on the next update. m_StateReorderableList = null; } GUI.enabled = m_StateConfiguration.Profiles != null && m_StateConfiguration.Profiles.Length > 0; if (GUILayout.Button(InspectorStyles.RemoveIcon, InspectorStyles.NoPaddingButtonStyle, GUILayout.Width(18))) { // Removes the current profile. var profileList = new List <StateConfiguration.Profile>(m_StateConfiguration.Profiles); var removeProfile = m_StateConfiguration.Profiles[selectedProfileIndex]; for (int j = 0; j < removeProfile.StateElements.Length; ++j) { if (removeProfile.StateElements[j].Default) { DestroyImmediate(removeProfile.StateElements[j].Preset, true); } } profileList.RemoveAt(selectedProfileIndex); m_StateConfiguration.Profiles = profileList.ToArray(); selectedProfileIndex = Mathf.Max(0, selectedProfileIndex - 1); EditorPrefs.SetInt(SelectedProfileKey, selectedProfileIndex); // Set the reorderableList to null and return so the correct array will be used on the next update. m_StateReorderableList = null; AssetDatabase.SaveAssets(); } if (GUILayout.Button(InspectorStyles.DuplicateIcon, InspectorStyles.NoPaddingButtonStyle, GUILayout.Width(20))) { // Duplicates the current profile. var profiles = m_StateConfiguration.Profiles; Array.Resize(ref profiles, profiles != null ? profiles.Length + 1 : 1); var duplicateProfile = profiles[selectedProfileIndex]; var count = 1; var profileName = string.Empty; do { profileName = duplicateProfile.Name + " " + count; count++; } while (!IsUniqueProfileName(profileName)); var profile = new StateConfiguration.Profile(); profile.Name = profileName; profile.Type = duplicateProfile.Type; profile.StateElements = new StateConfiguration.Profile.StateElement[duplicateProfile.StateElements.Length]; for (int i = 0; i < profile.StateElements.Length; ++i) { var preset = ScriptableObject.Instantiate(duplicateProfile.StateElements[i].Preset); preset.name = duplicateProfile.StateElements[i].Preset.name; AssetDatabase.AddObjectToAsset(preset, m_StateConfiguration); profile.StateElements[i] = new StateConfiguration.Profile.StateElement(duplicateProfile.StateElements[i].Name, preset, duplicateProfile.StateElements[i].BlockList, duplicateProfile.StateElements[i].Default); } profiles[profiles.Length - 1] = profile; m_StateConfiguration.Profiles = profiles; selectedProfileIndex = m_StateConfiguration.Profiles.Length - 1; EditorPrefs.SetInt(SelectedProfileKey, selectedProfileIndex); // Set the reorderableList to null and return so the correct array will be used on the next update. m_StateReorderableList = null; AssetDatabase.SaveAssets(); } var selectedProfile = (m_StateConfiguration.Profiles != null && selectedProfileIndex < m_StateConfiguration.Profiles.Length) ? m_StateConfiguration.Profiles[selectedProfileIndex] : null; GUI.enabled = selectedProfile != null; GUILayout.EndHorizontal(); var name = EditorGUILayout.TextField("Name", selectedProfile != null ? selectedProfile.Name : string.Empty); if (selectedProfile != null) { if (IsUniqueProfileName(name)) { selectedProfile.Name = name; } } var profileType = (StateConfiguration.Profile.ProfileType)EditorGUILayout.EnumPopup("Profile Type", selectedProfile != null ? selectedProfile.Type : StateConfiguration.Profile.ProfileType.Character); if (selectedProfile != null) { selectedProfile.Type = profileType; } if (m_StateReorderableList == null) { StateConfiguration.Profile.StateElement[] states = selectedProfile != null ? selectedProfile.StateElements : null; if (states == null) { states = new StateConfiguration.Profile.StateElement[0]; } m_StateReorderableList = new ReorderableList(states, typeof(StateConfiguration.Profile.StateElement), true, true, m_StateConfiguration.Profiles != null && m_StateConfiguration.Profiles.Length > 0, states.Length > 0); m_StateReorderableList.drawHeaderCallback = OnStateListHeaderDraw; m_StateReorderableList.drawElementCallback = OnStateListDraw; m_StateReorderableList.onAddCallback = OnStateListAdd; m_StateReorderableList.onRemoveCallback = OnStateListRemove; } m_StateReorderableList.DoLayoutList(); GUI.enabled = true; if (EditorGUI.EndChangeCheck()) { Shared.Editor.Utility.EditorUtility.RecordUndoDirtyObject(target, "Change Value"); serializedObject.ApplyModifiedProperties(); } }
/// <summary> /// Is the state name unique compared to the other states? /// </summary> private bool IsUniqueStateName(StateConfiguration.Profile.StateElement[] states, StateConfiguration.Profile.StateElement state, string name) { // A preset is required in order to match the object type. if (state.Preset == null) { return(true); } // A blank string is not unique. if (string.IsNullOrEmpty(name)) { return(false); } var objType = state.Preset.Data.ObjectType; // A name is not unique if it is equal to any other state name. for (int i = 0; i < states.Length; ++i) { // The object type must match in order to be compared. if (states[i].Preset == null || objType != states[i].Preset.Data.ObjectType) { continue; } if (states[i] == state) { continue; } if (states[i].Name == name) { return(false); } } return(true); }
/// <summary> /// Adds the list of states to the current profile. /// </summary> /// <param name="gameObject">The GameObject that the states were added from.</param> /// <param name="stateList">A list of states to add.</param> private void AddStatesToProfile(GameObject gameObject, List <Opsive.Shared.StateSystem.State> stateList) { if (stateList.Count == 0) { return; } var profile = new StateConfiguration.Profile(); // If the current name isn't unique then this profile needs to be updated. var addProfile = true; if (m_StateConfiguration.Profiles != null) { for (int i = 0; i < m_StateConfiguration.Profiles.Length; ++i) { if (m_StateConfiguration.Profiles[i].Name == gameObject.name) { profile = m_StateConfiguration.Profiles[i]; addProfile = false; // The default presets should be removed because they will be regenerated. for (int j = 0; j < profile.StateElements.Length; ++j) { if (profile.StateElements[j].Default) { DestroyImmediate(profile.StateElements[j].Preset, true); } } break; } } } profile.Name = gameObject.name; if (gameObject.GetComponent <UltimateCharacterController.Character.UltimateCharacterLocomotion>() != null) { profile.Type = StateConfiguration.Profile.ProfileType.Character; } else if (gameObject.GetComponent <UltimateCharacterController.Camera.CameraController>() != null) { profile.Type = StateConfiguration.Profile.ProfileType.Camera; } else if (gameObject.GetComponent <UltimateCharacterController.Items.Item>()) { profile.Type = StateConfiguration.Profile.ProfileType.Item; } else { Debug.LogWarning("Warning: The object " + gameObject.name + " is not a supported type."); return; } var stateElements = new StateConfiguration.Profile.StateElement[stateList.Count]; var configPath = AssetDatabase.GetAssetPath(m_StateConfiguration); for (int i = 0; i < stateList.Count; ++i) { // The default states will have the same path as the base ScriptableObject. var withinConfiguration = configPath == AssetDatabase.GetAssetPath(stateList[i].Preset); stateElements[i] = new StateConfiguration.Profile.StateElement(stateList[i].Name, stateList[i].Preset as PersistablePreset, stateList[i].BlockList, withinConfiguration); } profile.StateElements = stateElements; if (addProfile) { var profiles = m_StateConfiguration.Profiles; Array.Resize(ref profiles, profiles != null ? profiles.Length + 1 : 1); profiles[profiles.Length - 1] = profile; m_StateConfiguration.Profiles = profiles; } }