From 591d1b60147160e191579914f3faca5b322b2649 Mon Sep 17 00:00:00 2001 From: kusomaigo Date: Fri, 6 Jan 2023 23:23:13 -0800 Subject: [PATCH 1/3] fix "Collection was modified" InvalidOperationException and missing parameter behavior when isCombined is false --- .../Editor/BinaryParameterWindow.cs | 38 +++++++++++++++---- .../Editor/ParameterGenerator.cs | 35 +++++++++++++++++ 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/BinaryParameterWindow.cs b/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/BinaryParameterWindow.cs index 6b725c1..8fe6e7e 100644 --- a/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/BinaryParameterWindow.cs +++ b/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/BinaryParameterWindow.cs @@ -409,6 +409,13 @@ private void OnGUI() { if (_tab == 0 && !_smooth) { + // remove only the float parameter from the VRC avatar parameter list + ParameterTools.RemoveVRCParameter(_avDescriptor, new VRCExpressionParameters.Parameter + { + name = _baseParamName, + valueType = VRCExpressionParameters.ValueType.Float + }); + // create parameter in the animation controller ParameterTools.CheckAndCreateParameter(_baseParamName, _animatorController, 1); _binaryStateMachine.initClip = BinaryParameterFloatDriver.CreateFloatDriverAnimation(_baseParamName, 0f); @@ -416,6 +423,13 @@ private void OnGUI() } else if (_tab == 0) { + // remove only the float parameter from the VRC avatar parameter list + ParameterTools.RemoveVRCParameter(_avDescriptor, new VRCExpressionParameters.Parameter + { + name = _baseParamName, + valueType = VRCExpressionParameters.ValueType.Float + }); + // create parameter in the animation controller ParameterTools.CheckAndCreateParameter(_baseParamName, _animatorController, 1); _binaryStateMachine.CreateSmoothingLayer(_smoothness); @@ -423,14 +437,11 @@ private void OnGUI() _binaryStateMachine.initClip = BinaryParameterFloatDriver.CreateFloatDriverAnimation(_baseParamName + "Proxy", 0f); _binaryStateMachine.finalClip = BinaryParameterFloatDriver.CreateFloatDriverAnimation(_baseParamName + "Proxy", 1f); } - if (ParameterTools.AddVRCParameter(_avDescriptor, GenerateBinaryParams(_baseParamName, _binarySize, _isCombined))) - { - ParameterTools.RemoveVRCParameter(_avDescriptor, _baseParamName); - _binaryStateMachine.CreateBinaryLayer(); - } - else - EditorGUILayout.HelpBox("Parameters can not fit, or Expressions Parameters do not exist.", MessageType.Warning); + // generates direct binary layer if _tab==1 + _binaryStateMachine.CreateBinaryLayer(); } + else + EditorGUILayout.HelpBox("Parameters can not fit, or Expressions Parameters do not exist.", MessageType.Warning); } } else if (GUILayout.Button @@ -444,22 +455,32 @@ private void OnGUI() { if (ParameterTools.AddVRCParameter(_avDescriptor, GenerateBinaryParams(_baseParamName, _binarySize, _isCombined)) | !_createParametersInDescriptor) { + // float parameter and not smoothing if (_tab == 0 && !_smooth) { + // remove only the float parameter from the VRC avatar parameter list ParameterTools.RemoveVRCParameter(_avDescriptor, new VRCExpressionParameters.Parameter { name = _baseParamName, valueType = VRCExpressionParameters.ValueType.Float }); + // create parameter in the animation controller ParameterTools.CheckAndCreateParameter(_baseParamName, _animatorController, 1); _binaryStateMachine.initClip = BinaryParameterFloatDriver.CreateFloatDriverAnimation(_baseParamName, 0f); _binaryStateMachine.finalClip = BinaryParameterFloatDriver.CreateFloatDriverAnimation(_baseParamName, 1f); _binaryStateMachine.finalNegativeClip = BinaryParameterFloatDriver.CreateFloatDriverAnimation(_baseParamName, -1f); } + // float parameter and smoothing else if (_tab == 0) { - ParameterTools.RemoveVRCParameter(_avDescriptor, _baseParamName); + // remove only the float parameter from the VRC avatar parameter list + ParameterTools.RemoveVRCParameter(_avDescriptor, new VRCExpressionParameters.Parameter + { + name = _baseParamName, + valueType = VRCExpressionParameters.ValueType.Float + }); + // create parameter in the animation controller ParameterTools.CheckAndCreateParameter(_baseParamName, _animatorController, 1); _binaryStateMachine.CreateSmoothingLayer(_smoothness); @@ -467,6 +488,7 @@ private void OnGUI() _binaryStateMachine.finalClip = BinaryParameterFloatDriver.CreateFloatDriverAnimation(_baseParamName + "Proxy", 1f); _binaryStateMachine.finalNegativeClip = BinaryParameterFloatDriver.CreateFloatDriverAnimation(_baseParamName + "Proxy", -1f); } + // generates direct binary layer if _tab==1 _binaryStateMachine.CreateCombinedBinaryLayer(); } else diff --git a/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/ParameterGenerator.cs b/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/ParameterGenerator.cs index 59a8e81..a9a78b8 100644 --- a/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/ParameterGenerator.cs +++ b/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/ParameterGenerator.cs @@ -132,6 +132,41 @@ public static bool RemoveVRCParameter(VRCAvatarDescriptor avatarDescriptor, VRCE return true; } + public static bool RemoveVRCParameter(VRCAvatarDescriptor avatarDescriptor, string parameter) + { + // Make sure Parameters aren't null + if (avatarDescriptor.expressionParameters == null) + { + Debug.Log("ExpressionsParameters not found!"); + return false; + } + + // Instantiate and Save to Database + VRCExpressionParameters newParameters = avatarDescriptor.expressionParameters; + string assetPath = AssetDatabase.GetAssetPath(avatarDescriptor.expressionParameters); + if (assetPath != String.Empty) + { + AssetDatabase.RemoveObjectFromAsset(avatarDescriptor.expressionParameters); + AssetDatabase.CreateAsset(newParameters, assetPath); + avatarDescriptor.expressionParameters = newParameters; + } + + // Check and see if parameter exists + if (newParameters.FindParameter(parameter) != null) + { + // Remove the parameters with listed keyword + List betterParametersBecauseItsAListInstead = + newParameters.parameters.ToList(); + + // Remove without editing the collection being looped + betterParametersBecauseItsAListInstead = + betterParametersBecauseItsAListInstead.Where(p => !p.name.Contains(parameter)).ToList(); + + newParameters.parameters = betterParametersBecauseItsAListInstead.ToArray(); + } + return true; + } + public static AnimatorControllerParameter CheckAndCreateParameter(string paramName, AnimatorController animatorController, int type, double defaultVal = 0) { AnimatorControllerParameter param = new AnimatorControllerParameter(); From 68510bf5b1feac24c5b12030a2d6371197cf438b Mon Sep 17 00:00:00 2001 From: kusomaigo Date: Sat, 7 Jan 2023 01:18:55 -0800 Subject: [PATCH 2/3] Fix create parameter switch with minor cleanup of 'create' button execution logic and minor UI change --- .../Editor/BinaryParameterWindow.cs | 79 ++++++++++++++----- .../Editor/ParameterGenerator.cs | 22 ++++-- 2 files changed, 73 insertions(+), 28 deletions(-) diff --git a/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/BinaryParameterWindow.cs b/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/BinaryParameterWindow.cs index 8fe6e7e..97802fc 100644 --- a/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/BinaryParameterWindow.cs +++ b/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/BinaryParameterWindow.cs @@ -405,30 +405,44 @@ private void OnGUI() "set animations, transitions, and parameters that handle the specified Binary Parameter." ))) { - if (ParameterTools.AddVRCParameter(_avDescriptor, GenerateBinaryParams(_baseParamName, _binarySize, _isCombined)) | !_createParametersInDescriptor) + bool doAnimationControllerActions = true; + // creating parameters in VRC avatar parameters asset + if (_createParametersInDescriptor) { + // remove original (float) parameter from VRC avatar parameters asset + // won't remove if it isn't a float! + ParameterTools.RemoveVRCParameter(_avDescriptor, new VRCExpressionParameters.Parameter + { + name = _baseParamName, + valueType = VRCExpressionParameters.ValueType.Float + }, true); + + if (!ParameterTools.AddVRCParameter(_avDescriptor, GenerateBinaryParams(_baseParamName, _binarySize, _isCombined))) + { + doAnimationControllerActions = false; + // HelpBoxes don't actually show because they show in the time window of the buttonclick + //EditorGUILayout.HelpBox("Parameters can not fit, or Expressions Parameters do not exist.", MessageType.Warning); + EditorUtility.DisplayDialog("Warning", "Parameters can not fit, or Expressions Parameters do not exist.\n" + + "Aborting binary parameter creation.", "OK"); + } + } + + // animation controller actions + // don't add to animation controller if adding to VRC parameters asset failed + if (doAnimationControllerActions) + { + // no smoothing layer if (_tab == 0 && !_smooth) { - // remove only the float parameter from the VRC avatar parameter list - ParameterTools.RemoveVRCParameter(_avDescriptor, new VRCExpressionParameters.Parameter - { - name = _baseParamName, - valueType = VRCExpressionParameters.ValueType.Float - }); // create parameter in the animation controller ParameterTools.CheckAndCreateParameter(_baseParamName, _animatorController, 1); _binaryStateMachine.initClip = BinaryParameterFloatDriver.CreateFloatDriverAnimation(_baseParamName, 0f); _binaryStateMachine.finalClip = BinaryParameterFloatDriver.CreateFloatDriverAnimation(_baseParamName, 1f); } + // with smoothing layer else if (_tab == 0) { - // remove only the float parameter from the VRC avatar parameter list - ParameterTools.RemoveVRCParameter(_avDescriptor, new VRCExpressionParameters.Parameter - { - name = _baseParamName, - valueType = VRCExpressionParameters.ValueType.Float - }); // create parameter in the animation controller ParameterTools.CheckAndCreateParameter(_baseParamName, _animatorController, 1); @@ -440,8 +454,6 @@ private void OnGUI() // generates direct binary layer if _tab==1 _binaryStateMachine.CreateBinaryLayer(); } - else - EditorGUILayout.HelpBox("Parameters can not fit, or Expressions Parameters do not exist.", MessageType.Warning); } } else if (GUILayout.Button @@ -453,9 +465,33 @@ private void OnGUI() "set animations, transitions, and parameters that handle the specified Combined Binary Parameter." ))) { - if (ParameterTools.AddVRCParameter(_avDescriptor, GenerateBinaryParams(_baseParamName, _binarySize, _isCombined)) | !_createParametersInDescriptor) + bool doAnimationControllerActions = true; + // creating parameters in VRC avatar parameters asset + if (_createParametersInDescriptor) + { + // remove original (float) parameter from VRC avatar parameters asset + // won't remove if it isn't a float! + ParameterTools.RemoveVRCParameter(_avDescriptor, new VRCExpressionParameters.Parameter + { + name = _baseParamName, + valueType = VRCExpressionParameters.ValueType.Float + }, true); + + if (!ParameterTools.AddVRCParameter(_avDescriptor, GenerateBinaryParams(_baseParamName, _binarySize, _isCombined))) + { + doAnimationControllerActions = false; + // HelpBoxes don't actually show because they show in the time window of the buttonclick + //EditorGUILayout.HelpBox("Parameters can not fit, or Expressions Parameters do not exist.", MessageType.Warning); + EditorUtility.DisplayDialog("Warning", "Parameters can not fit, or Expressions Parameters do not exist.\n" + + "Aborting binary parameter creation.", "OK"); + } + } + + // animation controller actions + // don't add to animation controller if adding to VRC parameters asset failed + if (doAnimationControllerActions) { - // float parameter and not smoothing + // no smoothing layer if (_tab == 0 && !_smooth) { // remove only the float parameter from the VRC avatar parameter list @@ -471,7 +507,7 @@ private void OnGUI() _binaryStateMachine.finalClip = BinaryParameterFloatDriver.CreateFloatDriverAnimation(_baseParamName, 1f); _binaryStateMachine.finalNegativeClip = BinaryParameterFloatDriver.CreateFloatDriverAnimation(_baseParamName, -1f); } - // float parameter and smoothing + // with smoothing layer else if (_tab == 0) { // remove only the float parameter from the VRC avatar parameter list @@ -491,10 +527,11 @@ private void OnGUI() // generates direct binary layer if _tab==1 _binaryStateMachine.CreateCombinedBinaryLayer(); } - else - EditorGUILayout.HelpBox("Parameters can not fit, or Expressions Parameters do not exist.", MessageType.Warning); } - EditorGUILayout.HelpBox("Parameters (" + _avDescriptor.expressionParameters.CalcTotalCost() + "/" + VRCExpressionParameters.MAX_PARAMETER_COST + "):" + GenerateParamNames(_baseParamName, _binarySize, _isCombined), MessageType.None); + EditorGUILayout.Space(); + EditorGUILayout.HelpBox("Parameters (" + _avDescriptor.expressionParameters.CalcTotalCost() + "/" + VRCExpressionParameters.MAX_PARAMETER_COST + ")\n\n" + + "Binary Parameters to create:" + (_createParametersInDescriptor ? "(Will Add to VRC Expression Parameters)" : "") + + GenerateParamNames(_baseParamName, _binarySize, _isCombined), MessageType.None); } } diff --git a/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/ParameterGenerator.cs b/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/ParameterGenerator.cs index a9a78b8..7b8bd76 100644 --- a/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/ParameterGenerator.cs +++ b/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/ParameterGenerator.cs @@ -17,8 +17,6 @@ public static bool AddVRCParameter(VRCAvatarDescriptor avatarDescriptor, List betterParametersBecauseItsAListInstead = newParameters.parameters.ToList(); @@ -132,7 +139,8 @@ public static bool RemoveVRCParameter(VRCAvatarDescriptor avatarDescriptor, VRCE return true; } - public static bool RemoveVRCParameter(VRCAvatarDescriptor avatarDescriptor, string parameter) + // kept for future use + public static bool RemoveVRCParametersByStem(VRCAvatarDescriptor avatarDescriptor, string parameterStem) { // Make sure Parameters aren't null if (avatarDescriptor.expressionParameters == null) @@ -152,7 +160,7 @@ public static bool RemoveVRCParameter(VRCAvatarDescriptor avatarDescriptor, stri } // Check and see if parameter exists - if (newParameters.FindParameter(parameter) != null) + if (newParameters.FindParameter(parameterStem) != null) { // Remove the parameters with listed keyword List betterParametersBecauseItsAListInstead = @@ -160,7 +168,7 @@ public static bool RemoveVRCParameter(VRCAvatarDescriptor avatarDescriptor, stri // Remove without editing the collection being looped betterParametersBecauseItsAListInstead = - betterParametersBecauseItsAListInstead.Where(p => !p.name.Contains(parameter)).ToList(); + betterParametersBecauseItsAListInstead.Where(p => !p.name.Contains(parameterStem)).ToList(); newParameters.parameters = betterParametersBecauseItsAListInstead.ToArray(); } From 04685e4161e3c52a544950ea94366facfd45d2a8 Mon Sep 17 00:00:00 2001 From: kusomaigo Date: Sat, 7 Jan 2023 01:23:39 -0800 Subject: [PATCH 3/3] remove residue "RemoveVRCParmeter" commands from combined binary parameter layer GUI button if block --- .../Editor/BinaryParameterWindow.cs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/BinaryParameterWindow.cs b/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/BinaryParameterWindow.cs index 97802fc..2ecb05e 100644 --- a/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/BinaryParameterWindow.cs +++ b/Assets/VRCFaceTracking/Tools/Binary Parameter Tool/Editor/BinaryParameterWindow.cs @@ -494,12 +494,6 @@ private void OnGUI() // no smoothing layer if (_tab == 0 && !_smooth) { - // remove only the float parameter from the VRC avatar parameter list - ParameterTools.RemoveVRCParameter(_avDescriptor, new VRCExpressionParameters.Parameter - { - name = _baseParamName, - valueType = VRCExpressionParameters.ValueType.Float - }); // create parameter in the animation controller ParameterTools.CheckAndCreateParameter(_baseParamName, _animatorController, 1); @@ -510,12 +504,6 @@ private void OnGUI() // with smoothing layer else if (_tab == 0) { - // remove only the float parameter from the VRC avatar parameter list - ParameterTools.RemoveVRCParameter(_avDescriptor, new VRCExpressionParameters.Parameter - { - name = _baseParamName, - valueType = VRCExpressionParameters.ValueType.Float - }); // create parameter in the animation controller ParameterTools.CheckAndCreateParameter(_baseParamName, _animatorController, 1);