private int GetParameterSize() { int size = 0; for (int i = 0; i < expressionParams.parameters.Length; i++) { size += VRCExpressionParameters.TypeCost(expressionParams.parameters[i].valueType); } return(size); }
/// <summary> /// Creates a copy of the avatar descriptor's parameter asset or creates one if it doesn't exist, adds a provided parameter, /// assigns the new parameter asset, and stores it in the specified directory. /// </summary> /// <param name="descriptor">The avatar descriptor to add the parameter to.</param> /// <param name="parameter">The parameter to add.</param> /// <param name="directory">The unique directory to store the new parameter asset, ex. "Assets/MyCoolScript/GeneratedAssets/725638/".</param> /// <param name="overwrite">Optionally, choose to not overwrite an asset of the same name in directory. See class for more info.</param> public static void AddParameter(VRCAvatarDescriptor descriptor, VRCExpressionParameters.Parameter parameter, string directory, bool overwrite = true) { if (descriptor == null) { Debug.LogError("Couldn't add the parameter, the avatar descriptor is null!"); return; } else if ((parameter == null) || (parameter.name == null)) { Debug.LogError("Couldn't add the parameter, it or its name is null!"); return; } else if ((directory == null) || (directory == "")) { Debug.Log("Directory was not specified, storing new parameters asset in " + defaultDirectory); directory = defaultDirectory; } descriptor.customExpressions = true; VRCExpressionParameters parameters = ScriptableObject.CreateInstance <VRCExpressionParameters>(); parameters.parameters = new VRCExpressionParameters.Parameter[0]; if (descriptor.expressionParameters == null) { AssetDatabase.CreateAsset(parameters, directory + "Parameters.asset"); } else { if ((descriptor.expressionParameters.CalcTotalCost() + VRCExpressionParameters.TypeCost(parameter.valueType)) > VRCExpressionParameters.MAX_PARAMETER_COST) { Debug.LogError("Couldn't add parameter '" + parameter.name + "', not enough memory free in the avatar's parameter asset!"); return; } string path = (directory + descriptor.expressionParameters.name + ".asset"); path = (overwrite) ? path : AssetDatabase.GenerateUniqueAssetPath(path); if (AssetDatabase.GetAssetPath(descriptor.expressionParameters) != path) // if we have not made a copy yet { // CopyAsset with two identical strings yields exception AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(descriptor.expressionParameters), path); } parameters = AssetDatabase.LoadAssetAtPath(path, typeof(VRCExpressionParameters)) as VRCExpressionParameters; } if (parameters.FindParameter(parameter.name) == null) { int count = parameters.parameters.Length; VRCExpressionParameters.Parameter[] parameterArray = new VRCExpressionParameters.Parameter[count + 1]; for (int i = 0; i < count; i++) { parameterArray[i] = parameters.GetParameter(i); } parameterArray[count] = parameter; parameters.parameters = parameterArray; } EditorUtility.SetDirty(parameters); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); descriptor.expressionParameters = parameters; }
private void ShowMenuFoldout(VRCExpressionsMenu menu, string title) { if (menu == null) { return; } bool b = expandedMenus.Contains(menu); // Remove before we go any further, prevents infinite recursion on cyclic menus. expandedMenus.Remove(menu); if (!EditorGUILayout.Foldout(b, title, true)) { return; } EditorGUILayout.BeginVertical(); GUILayout.BeginHorizontal(); GUILayout.Space(EditorGUI.indentLevel * 17); Debug.Log(expressionParams.parameters.Length + ":" + menu.controls.Count); int size = 0; for (int i = 0; i < expressionParams.parameters.Length; i++) { size += VRCExpressionParameters.TypeCost(expressionParams.parameters[i].valueType); } if (menu.controls.Count < expressionParams.parameters.Length) { if (GUILayout.Button("Add Marker Here", GUILayout.Width(130))) { InstallMarker(ref menu); } } else { if (size < VRCExpressionParameters.MAX_PARAMETER_COST) { if (GUILayout.Button("enlarge parameters", GUILayout.Width(130))) { if (size < VRCExpressionParameters.MAX_PARAMETER_COST) { VRCExpressionParameters.Parameter[] newParams = new VRCExpressionParameters.Parameter[expressionParams.parameters.Length + 1]; for (int i = 0; i < expressionParams.parameters.Length; i++) { newParams[i] = expressionParams.parameters[i]; } newParams[expressionParams.parameters.Length] = new VRCExpressionParameters.Parameter(); expressionParams.parameters = newParams; EditorUtility.SetDirty(expressionParams); } } } else { GUILayout.Label("No room.", GUILayout.Width(130)); } } GUILayout.EndHorizontal(); EditorGUI.indentLevel++; foreach (var child in menu.controls) { if (child.type == ControlType.SubMenu) { ShowMenuFoldout(child.subMenu, child.name); } } EditorGUI.indentLevel--; EditorGUILayout.EndVertical(); // Okay, it's safe to add the menu back. expandedMenus.Add(menu); }
void OnGUI() { EditorGUILayout.BeginHorizontal(); scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true)); if (Stage.Instruction == stage) { EditorGUILayout.HelpBox("Welcome to Avatar 8Track. This tool let's you automagically turn a folder of songs into a music player in your avatars radial menu.\n" + "Song Library Setup\n" + " - Create a folder somewhere under Assets\n" + " - Put all of your songs into that folder\n" + " The folder name does not matter.\n" + " All songs from the folder will be added\n" , MessageType.None, true); EditorGUILayout.HelpBox("Do not store anything but your songs in the Song Library, it may be deleted", MessageType.Warning, true); EditorGUILayout.HelpBox("One song library per avatar!", MessageType.Warning, true); EditorGUILayout.HelpBox("If you update the library with new songs just run the tool again", MessageType.Info, true); EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); // --- Avatar stuff --- EditorGUI.BeginChangeCheck(); avatarIndex = EditorGUILayout.Popup("Avatar", avatarIndex, avatarKeys, EditorStyles.popup); if (EditorGUI.EndChangeCheck()) { expressionParameters = avatars[avatarKeys[avatarIndex]].expressionParameters; expressionsMenu = avatars[avatarKeys[avatarIndex]].expressionsMenu; _8TrackEditor.SetFromAvatar(avatars[avatarKeys[avatarIndex]]); } //--- 8Track object EditorGUILayout.HelpBox("The 8Track object will hold all of your AudioClip Components." + "\nIt must be a first child of your avatar." + "\nThe name of the 8Track object will determine names for various assets." + "\nI highly recommend you use the default object.", MessageType.Info, true); EditorGUILayout.LabelField("The 8Track Object"); _8TrackEditor._8TrackObject = (GameObject)EditorGUILayout.ObjectField(_8TrackEditor._8TrackObject, typeof(GameObject), true); if (null == _8TrackEditor._8TrackObject) { _8trackValid = false; if (GUILayout.Button("Create _8Track Object", GUILayout.Height(30))) { _8TrackEditor._8TrackObject = new GameObject("8Track"); _8TrackEditor._8TrackObject.transform.parent = _8TrackEditor.Avatar.transform; Debug.Log($"Created new object for tracks [{_8TrackEditor._8TrackObject.name}]"); } else { _8TrackEditor.SetFromAvatar(avatars[avatarKeys[avatarIndex]]); } } else if (_8TrackEditor._8TrackObject.transform.parent != _8TrackEditor.Avatar.transform) { EditorGUILayout.HelpBox("The 8Track object must be a child of the avatar selected", MessageType.Error, true); _8trackValid = false; } else { _8trackValid = true; } //set var if (null != _8TrackEditor._8TrackObject) { _8TrackEditor.VolumeEPName = Avatar8Track.GetVarName(_8TrackEditor._8TrackObject, Avatar8Track.volumeEPNameSuffix); _8TrackEditor.TrackEPName = Avatar8Track.GetVarName(_8TrackEditor._8TrackObject, Avatar8Track.trackEPNameSuffix); } EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); //--- Parameters if (expressionValid) { EditorGUILayout.HelpBox("A Integer and Float parameter will be added", MessageType.Info, true); } else if (null != expressionParameters) { EditorGUILayout.HelpBox("The ExpressionParameters does not have space for a float and an int" + "\nYou can delete empty parameters to make room", MessageType.Error, true); if (GUILayout.Button("Delete Empty Parameters", GUILayout.Height(30))) { for (int i = 0; i < expressionParameters.parameters.Length; i++) { if (string.IsNullOrEmpty(expressionParameters.parameters[i].name)) { ArrayUtility.RemoveAt <VRCExpressionParameters.Parameter>(ref expressionParameters.parameters, i); i--; } } } } else { EditorGUILayout.HelpBox("An ExpressionParameters object is required", MessageType.Error, true); } EditorGUILayout.LabelField("VRC ExpressionParameters File"); expressionParameters = (VRCExpressionParameters)EditorGUILayout.ObjectField(expressionParameters, typeof(VRCExpressionParameters), true); if (null != expressionParameters && null != _8TrackEditor._8TrackObject) { int cost = VRCExpressionParameters.TypeCost(VRCExpressionParameters.ValueType.Int) + VRCExpressionParameters.TypeCost(VRCExpressionParameters.ValueType.Float); VRCExpressionParameters.Parameter[] parameters = expressionParameters.parameters; foreach (VRCExpressionParameters.Parameter parameter in parameters) { if (parameter.name == _8TrackEditor.VolumeEPName) { cost -= VRCExpressionParameters.TypeCost(VRCExpressionParameters.ValueType.Float); } else if (parameter.name == _8TrackEditor.TrackEPName) { cost -= VRCExpressionParameters.TypeCost(VRCExpressionParameters.ValueType.Int); } } expressionValid = expressionParameters.CalcTotalCost() + cost <= VRCExpressionParameters.MAX_PARAMETER_COST; } else { expressionValid = null != expressionParameters; } EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); //--- Menu if (menuValid) { EditorGUILayout.HelpBox("Which VRCExpressionsMenu do you want the SubMenu added to", MessageType.Info, true); } else if (null != expressionsMenu) { EditorGUILayout.HelpBox("The VRCExpressionsMenu is full", MessageType.Error, true); } if (null == expressionsMenu) { EditorGUILayout.HelpBox("ExpressionsMenu is not set", MessageType.Warning, true); } EditorGUILayout.LabelField("VRC Expressions Menu File"); expressionsMenu = (VRCExpressionsMenu)EditorGUILayout.ObjectField(expressionsMenu, typeof(VRCExpressionsMenu), true); if (null != expressionsMenu && null != _8TrackEditor._8TrackObject) { menuValid = expressionsMenu.controls.Count < VRCExpressionsMenu.MAX_CONTROLS; foreach (VRCExpressionsMenu.Control control in expressionsMenu.controls) { if (control.name == _8TrackEditor._8TrackObject.name) { menuValid = true; } } } else { menuValid = true; } if (null != expressionParameters && menuValid && expressionValid && _8trackValid) { Button(Stage._8Track, "Setup"); } } else if (Stage._8Track == stage) { _8TrackEditor.OnGUI(); Button(Stage.Instruction, "Back <-"); if (_8TrackEditor.IsValid()) { Button(Stage.Burn, "Continue ->"); } } if (Stage.Burn == stage) { EditorGUILayout.HelpBox("Read Carefully!!!!!!", MessageType.Error); EditorGUILayout.HelpBox("This will break the 8Track functionality for any other avatar this song library has been added to previously." + "\nDuplicate the song library if you want to add it to a separate avatar.", MessageType.Warning); EditorGUILayout.HelpBox("Avatar 8Tracks lets you update your song library by re-running it on the same avatar." + "\nfor convenience it auto-detects and deletes assets it has created previously and replaces them." + "\nDouble check the following items below were not manually edited by you." , MessageType.Warning); EditorGUILayout.LabelField("FX Controller Layers, Expression Parameters, and Expression Menu Controls with the following names", EditorStyles.wordWrappedLabel); EditorGUILayout.LabelField($" [{_8TrackEditor.TrackEPName}]", EditorStyles.boldLabel); EditorGUILayout.LabelField($" [{_8TrackEditor.VolumeEPName}]", EditorStyles.boldLabel); EditorGUILayout.LabelField($" [{_8TrackEditor._8TrackObject.name}]", EditorStyles.boldLabel); EditorGUILayout.HelpBox($"All AnimationClips, and ExpressionsMenus will be deleted in [{GetAssetDirectory(_8TrackEditor.AudioClip, true)}]", MessageType.Warning); Button(Stage._8Track, "Back <-"); if (GUILayout.Button("Accept And Burn Tracks", GUILayout.Height(30))) { try { string songLibrary = GetAssetDirectory(_8TrackEditor.AudioClip, false); CleanSongLibrary(songLibrary); List <AudioClip> libAssets = GetSongList(songLibrary); _8TrackEditor.BurnTracks(libAssets); VRC_Actions(songLibrary, libAssets, _8TrackEditor); AssetDatabase.SaveAssets(); EditorUtility.DisplayDialog("Avatar 8Tracks", "You're ready to rock", "great"); this.Close(); } catch (System.Exception e) { EditorUtility.DisplayDialog("so... this happened", e.Message, "sorry"); Debug.LogException(e); this.Close(); } } DrawEnd(); } else { DrawEnd(); } }