public void TestFaceClip() { var model = GameObject.Find(Constants.ChatdollModelName)?.GetComponent <ModelController>(); if (model == null) { Debug.LogError("Chatdoll model not found"); return; } var skinnedMeshRenderer = model.SkinnedMeshRenderer; var weights = new Dictionary <string, float>(); weights.Add("mouth_a", 0.5f); weights.Add("mouth_smile", 0.3f); weights.Add("eye_smile_L", 1.0f); var face = new FaceClip("Smile", skinnedMeshRenderer, weights); Assert.AreEqual("Smile", face.Name); Assert.AreEqual(60, face.Values.Count); var configuredWeightCount = 0; foreach (var w in face.Values) { if (w.Name == "mouth_a") { Assert.AreEqual(53, w.Index); Assert.AreEqual(0.5f, w.Weight); configuredWeightCount++; } else if (w.Name == "mouth_smile") { Assert.AreEqual(40, w.Index); Assert.AreEqual(0.3f, w.Weight); configuredWeightCount++; } else if (w.Name == "eye_smile_L") { Assert.AreEqual(30, w.Index); Assert.AreEqual(1.0f, w.Weight); configuredWeightCount++; } else { Assert.AreEqual(0.0f, w.Weight); } } Assert.AreEqual(3, configuredWeightCount); }
public override void OnInspectorGUI() { base.OnInspectorGUI(); var modelController = target as ModelController; var skinnedMeshRenderer = modelController.SkinnedMeshRenderer; var ButtonLayout = new GUILayoutOption[] { GUILayout.Width(80) }; if (skinnedMeshRenderer != null) { if (modelController.FaceClipConfiguration == null) { // Clear local list faceClips = null; if (GUILayout.Button("Import JSON (migration)")) { LoadFacesFromJson(); } return; } previousConfigName = currentConfigName; currentConfigName = modelController.FaceClipConfiguration.name; // Reset flag to determine selection changed var selectionChanged = false; // Load data on started or configuration changed if (faceClips == null || currentConfigName != previousConfigName) { faceClips = modelController.FaceClipConfiguration.FaceClips; if (faceClips.Count > 0) { selectionChanged = true; selectedFaceIndex = 0; } else { selectedFaceIndex = -1; currentFaceName = string.Empty; } } EditorGUILayout.BeginHorizontal(); // Pulldown selection previousSelectedFaceIndex = selectedFaceIndex; selectedFaceIndex = EditorGUILayout.Popup(selectedFaceIndex, faceClips.Select(f => new GUIContent(f.Name)).ToArray()); if (faceClips.Count > 0 && previousSelectedFaceIndex != selectedFaceIndex) { selectionChanged = true; } // Remove face if (GUILayout.Button("Remove", ButtonLayout)) { if (faceClips.Count > 0) { // Remove from list var faceToRemove = faceClips.Where(f => f.Name == currentFaceName).First(); faceClips.Remove(faceToRemove); // Save to asset EditorUtility.SetDirty(modelController.FaceClipConfiguration); AssetDatabase.SaveAssets(); // Select item if (faceClips.Count == 0) { // Nothing to be selected when no item exists selectedFaceIndex = -1; currentFaceName = string.Empty; } else { if (selectedFaceIndex == 0) { selectedFaceIndex = 0; } else { selectedFaceIndex--; } selectionChanged = true; } } } EditorGUILayout.EndHorizontal(); // Add or update face EditorGUILayout.BeginHorizontal(); currentFaceName = GUILayout.TextField(currentFaceName); if (GUILayout.Button("Capture", ButtonLayout)) { if (!string.IsNullOrEmpty(currentFaceName.Trim())) { // Update or add to list var faceToUpdate = faceClips.Where(f => f.Name == currentFaceName).FirstOrDefault(); if (faceToUpdate == null) { faceClips.Add(new FaceClip(currentFaceName, skinnedMeshRenderer)); } else { faceToUpdate = new FaceClip(currentFaceName, skinnedMeshRenderer); } // Select item selectedFaceIndex = faceClips.Select(f => f.Name).ToList().IndexOf(currentFaceName); // Save to asset EditorUtility.SetDirty(modelController.FaceClipConfiguration); AssetDatabase.SaveAssets(); } } EditorGUILayout.EndHorizontal(); // Change current name and blend shapes when selection changed if (selectionChanged) { currentFaceName = faceClips[selectedFaceIndex].Name; foreach (var blendShapeValue in faceClips[selectedFaceIndex].Values) { skinnedMeshRenderer.SetBlendShapeWeight(blendShapeValue.Index, blendShapeValue.Weight); } } } }