/// <summary> /// Animatorと記録したデータで書き込む /// </summary> /// <param name="root"></param> /// <param name="facial"></param> void ExportFacialAnimationClip(Animator root, CharacterFacialData facial) { var animclip = new AnimationClip(); var mesh = _smeshs; for (int faceTargetMeshIndex = 0; faceTargetMeshIndex < mesh.Length; faceTargetMeshIndex++) { var pathsb = new StringBuilder().Append(mesh[faceTargetMeshIndex].transform.name); var trans = mesh[faceTargetMeshIndex].transform; while (trans.parent != null && trans.parent != root.transform) { trans = trans.parent; pathsb.Insert(0, "/").Insert(0, trans.name); } //pathにはBlendshapeのベース名が入る //U_CHAR_1:SkinnedMeshRendererみたいなもの var path = pathsb.ToString(); //個別メッシュの個別Blendshapeごとに、AnimationCurveを生成している for (var blendShapeIndex = 0; blendShapeIndex < mesh[faceTargetMeshIndex].sharedMesh.blendShapeCount; blendShapeIndex++) { var curveBinding = new EditorCurveBinding(); curveBinding.type = typeof(SkinnedMeshRenderer); curveBinding.path = path; curveBinding.propertyName = "blendShape." + mesh[faceTargetMeshIndex].sharedMesh.GetBlendShapeName(blendShapeIndex); AnimationCurve curve = new AnimationCurve(); float pastBlendshapeWeight = -1; for (int k = 0; k < _facialData.Facials.Count; k++) { if (!(Mathf.Abs(pastBlendshapeWeight - _facialData.Facials[k].Smeshes[faceTargetMeshIndex].blendShapes[blendShapeIndex]) > 0.1f)) { continue; } curve.AddKey(new Keyframe(facial.Facials[k].Time, _facialData.Facials[k].Smeshes[faceTargetMeshIndex].blendShapes[blendShapeIndex], float.PositiveInfinity, 0f)); pastBlendshapeWeight = _facialData.Facials[k].Smeshes[faceTargetMeshIndex].blendShapes[blendShapeIndex]; } AnimationUtility.SetEditorCurve(animclip, curveBinding, curve); } } MotionDataRecorder.SafeCreateDirectory("Assets/Resources"); var outputPath = "Assets/Resources/FaceRecordMotion_" + _animRecorder.CharacterAnimator.name + "_" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") + "_Clip.anim"; Debug.Log("outputPath:" + outputPath); AssetDatabase.CreateAsset(animclip, AssetDatabase.GenerateUniqueAssetPath(outputPath)); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); }
// Use this for initialization private void OnEnable() { _animRecorder = GetComponent <MotionDataRecorder>(); _animRecorder.OnRecordStart += RecordStart; _animRecorder.OnRecordEnd += RecordEnd; if (_animRecorder.CharacterAnimator != null) { _smeshs = GetSkinnedMeshRenderers(_animRecorder.CharacterAnimator); } }
/// <summary> /// Animatorと記録したデータで書き込む /// </summary> /// <param name="root"></param> /// <param name="facial"></param> void ExportFacialAnimationClip(Animator root, CharacterFacialData facial) { var animclip = new AnimationClip(); var mesh = _smeshs; for (int i = 0; i < mesh.Length; i++) { var pathsb = new StringBuilder().Append(mesh[i].transform.name); var trans = mesh[i].transform; while (trans.parent != null && trans.parent != root.transform) { trans = trans.parent; pathsb.Insert(0, "/").Insert(0, trans.name); } var path = pathsb.ToString(); for (var j = 0; j < mesh[i].sharedMesh.blendShapeCount; j++) { var curveBinding = new EditorCurveBinding(); curveBinding.type = typeof(SkinnedMeshRenderer); curveBinding.path = path; curveBinding.propertyName = "blendShape." + mesh[i].sharedMesh.GetBlendShapeName(j); AnimationCurve curve = new AnimationCurve(); float pastBlendshapeWeight = -1; for (int k = 0; k < _facialData.Facials.Count; k++) { if (!(Mathf.Abs(pastBlendshapeWeight - _facialData.Facials[k].Smeshes[i].blendShapes[j]) > 0.1f)) { continue; } curve.AddKey(facial.Facials[k].Time, _facialData.Facials[k].Smeshes[i].blendShapes[j]); pastBlendshapeWeight = _facialData.Facials[k].Smeshes[i].blendShapes[j]; } AnimationUtility.SetEditorCurve(animclip, curveBinding, curve); } } MotionDataRecorder.SafeCreateDirectory("Assets/Resources"); var outputPath = "Assets/Resources/FaceRecordMotion_" + _animRecorder.CharacterAnimator.name + "_" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") + "_Clip.anim"; Debug.Log("outputPath:" + outputPath); AssetDatabase.CreateAsset(animclip, AssetDatabase.GenerateUniqueAssetPath(outputPath)); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); }
private void WriteAnimationFileToScriptableObject() { MotionDataRecorder.SafeCreateDirectory("Assets/Resources"); string path = AssetDatabase.GenerateUniqueAssetPath( "Assets/Resources/RecordMotion_ face" + _animRecorder.CharacterAnimator.name + DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") + ".asset"); if (_facialData == null) { Debug.LogError("記録されたFaceデータがnull"); } else { AssetDatabase.CreateAsset(_facialData, path); AssetDatabase.Refresh(); } _recordedTime = 0f; _frameCount = 0; }