diff --git a/ChatdollKit/Editor/FaceClipEditor.cs b/ChatdollKit/Editor/FaceClipEditor.cs index 1e9589c..79e44b0 100644 --- a/ChatdollKit/Editor/FaceClipEditor.cs +++ b/ChatdollKit/Editor/FaceClipEditor.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -13,6 +13,8 @@ public class FaceClipEditor : Editor { // For face configuration + private string previousJsonPath; + private string currentJsonPath; private List faceClips; private int previousSelectedFaceIndex; private int selectedFaceIndex; @@ -33,7 +35,10 @@ public override void OnInspectorGUI() if (skinnedMeshRenderer != null) { - if (string.IsNullOrEmpty(modelController.FaceConfigurationFile) || !File.Exists(modelController.FaceConfigurationFile)) + previousJsonPath = currentJsonPath; + currentJsonPath = Path.Combine(Application.dataPath, modelController.FaceConfigurationFile); + + if (string.IsNullOrEmpty(modelController.FaceConfigurationFile) || !File.Exists(currentJsonPath)) { EditorGUILayout.HelpBox("Create new face configuration file to use face capture tool.", MessageType.Info, true); if (GUILayout.Button("Create")) @@ -44,6 +49,10 @@ public override void OnInspectorGUI() if (!string.IsNullOrEmpty(newFilePath)) { File.WriteAllText(newFilePath, JsonConvert.SerializeObject(new List())); + if (newFilePath.StartsWith(Application.dataPath)) + { + newFilePath = newFilePath.Substring(Application.dataPath.Length + 1); + } modelController.FaceConfigurationFile = newFilePath; } } @@ -55,18 +64,22 @@ public override void OnInspectorGUI() return; } - var path = modelController.FaceConfigurationFile; - // Reset flag to determine selection changed var selectionChanged = false; // Initial load - if (faceClips == null) + if (faceClips == null || currentJsonPath != previousJsonPath) { - faceClips = GetFacesFromFile(path); + faceClips = GetFacesFromFile(currentJsonPath); if (faceClips.Count > 0) { selectionChanged = true; + selectedFaceIndex = 0; + } + else + { + selectedFaceIndex = -1; + currentFaceName = string.Empty; } } @@ -83,7 +96,7 @@ public override void OnInspectorGUI() // Remove face if (GUILayout.Button("Remove", ButtonLayout)) { - if (faceClips.Count > 0 && RemoveFace(path, faceClips[selectedFaceIndex].Name)) + if (faceClips.Count > 0 && RemoveFace(currentJsonPath, faceClips[selectedFaceIndex].Name)) { if (faceClips.Count == 0) { @@ -109,20 +122,19 @@ public override void OnInspectorGUI() // Add or update face EditorGUILayout.BeginHorizontal(); - currentFaceName = GUILayout.TextField(currentFaceName); - - EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(currentFaceName) || string.IsNullOrEmpty(currentFaceName.Trim())); if (GUILayout.Button("Capture", ButtonLayout)) { - // Update and save FaceClip with current weights of SkinnedMeshRenderer - if (UpdateFace(path, new FaceClip(currentFaceName, skinnedMeshRenderer))) + if (!string.IsNullOrEmpty(currentFaceName.Trim())) { - // Change selected index to new item - selectedFaceIndex = faceClips.Select(f => f.Name).ToList().IndexOf(currentFaceName); + // Update and save FaceClip with current weights of SkinnedMeshRenderer + if (UpdateFace(currentJsonPath, new FaceClip(currentFaceName, skinnedMeshRenderer))) + { + // Change selected index to new item + selectedFaceIndex = faceClips.Select(f => f.Name).ToList().IndexOf(currentFaceName); + } } } - EditorGUI.EndDisabledGroup(); EditorGUILayout.EndHorizontal(); // Change current name and blend shapes when selection changed @@ -208,8 +220,11 @@ private List GetFacesFromFile(string path) try { - var facesJson = File.ReadAllText(path); - storedFaces = JsonConvert.DeserializeObject>(facesJson); + var faceJsonString = File.ReadAllText(path); + if (faceJsonString != null) + { + storedFaces = JsonConvert.DeserializeObject>(faceJsonString); + } } catch (Exception ex) { @@ -491,4 +506,4 @@ class VisemeTarget public SkinnedMeshRenderer SkinnedMeshRenderer { get; set; } public List ShapeKeyIndexes { get; set; } } -} \ No newline at end of file +} diff --git a/ChatdollKit/Scripts/Model/ModelController.cs b/ChatdollKit/Scripts/Model/ModelController.cs index 9e119d5..884b541 100644 --- a/ChatdollKit/Scripts/Model/ModelController.cs +++ b/ChatdollKit/Scripts/Model/ModelController.cs @@ -612,7 +612,13 @@ public void AddFace(string name, Dictionary weights, bool asDefau // Load faces from config file public void LoadFacesFromFile(string configFilePath = null) { - var path = configFilePath ?? FaceConfigurationFile; + var path = !string.IsNullOrEmpty(configFilePath) ? configFilePath : Application.dataPath + "/" + FaceConfigurationFile; + if (!File.Exists(path)) + { + Debug.LogWarning("Face configuration file does not exist: " + path); + return; + } + foreach (var faceClip in JsonConvert.DeserializeObject>(File.ReadAllText(path))) { var asDefault = faceClip.Name.ToLower() == "default" || faceClip.Name.ToLower() == "neutral";