/// <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> /// 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; } }