protected virtual void OnSceneGUI() { float size = 0.1f; MotionMatcher motionMatcher = (MotionMatcher)target; currentMotionsData = motionMatcher.motionsData; if (currentMotionsData) { Transform child = motionMatcher.transform.Find(MotionMatchingBakeEditor.RootBoneName); Transform[] joints = child.GetComponentsInChildren <Transform>(); for (int i = 0; i < currentMotionsData.motionDataList.Length; i++) { MotionData motionData = currentMotionsData.motionDataList[i]; if (motionData.motionName == motionMatcher.bestMotionName || (string.IsNullOrEmpty(motionMatcher.bestMotionName) && motionData.motionName == defaultMotionName)) { for (int j = 0; j < motionData.motionFrameDataList.Length; j++) { MotionFrameData motionFrameData = motionData.motionFrameDataList[j]; for (int k = 0; k < motionFrameData.motionBoneDataList.Length; k++) { MotionBoneData motionBoneData = motionFrameData.motionBoneDataList[k]; Transform bone = joints[motionBoneData.boneIndex]; if (bone) { Vector3 bonePosition = motionBoneData.position; Handles.color = Color.green; Handles.SphereHandleCap(0, bonePosition, Quaternion.identity, size, EventType.Repaint); } } for (int l = 0; l < motionFrameData.motionTrajectoryDataList.Length; l++) { MotionTrajectoryData motionTrajectoryData = motionFrameData.motionTrajectoryDataList[l]; Handles.color = Color.yellow; Handles.SphereHandleCap(0, motionTrajectoryData.position, Quaternion.identity, size, EventType.Repaint); } } } } } }
private void CreateSnapshots() { UnityEditor.Animations.AnimatorController bakeController = null; string assetPath = GetPrefabPath(); if (string.IsNullOrEmpty(assetPath)) { EditorUtility.DisplayDialog("Mesh Animator", "Unable to locate the asset path for prefab: " + prefab.name, "OK"); return; } HashSet <string> allAssets = new HashSet <string>(); List <AnimationClip> clips = GetClips(); foreach (var clip in clips) { allAssets.Add(AssetDatabase.GetAssetPath(clip)); } string[] split = assetPath.Split("/".ToCharArray()); string assetFolder = string.Empty; for (int s = 0; s < split.Length - 1; s++) { assetFolder += split[s] + "/"; } var sampleGO = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity) as GameObject; sampleGO.name = prefab.name; animator = sampleGO.GetComponent <Animator>(); if (animator == null) { animator = sampleGO.GetComponentInChildren <Animator>(); } InitAnimationBones(sampleGO); if (requiresAnimator) { bakeController = CreateBakeController(); if (animator == null) { animator = sampleGO.AddComponent <Animator>(); animator.runtimeAnimatorController = bakeController; animator.avatar = GetAvatar(); } else { animator.runtimeAnimatorController = bakeController; animator.avatar = GetAvatar(); } animator.cullingMode = AnimatorCullingMode.AlwaysAnimate; animator.applyRootMotion = true; } MotionsData meshAnimationList = ScriptableObject.CreateInstance <MotionsData>(); meshAnimationList.motionDataList = new MotionData[clips.Count]; Transform rootMotionBaker = new GameObject().transform; for (int x = 0; x < clips.Count; x++) { AnimationClip animClip = clips[x]; if (bakeAnims.ContainsKey(animClip.name) && bakeAnims[animClip.name] == false) { continue; } if (frameSkips.ContainsKey(animClip.name) == false) { Debug.LogWarningFormat("No animation with name {0} in frame skips", animClip.name); continue; } string meshAnimationPath = string.Format("{0}{1}.asset", assetFolder, FormatClipName(animClip.name)); int bakeFrames = Mathf.CeilToInt(animClip.length * fps); meshAnimationList.motionDataList[x] = new MotionData(); MotionData motionData = meshAnimationList.motionDataList[x]; motionData.motionName = animClip.name; int totalFrame = 0; for (int i = 0; i < bakeFrames; i += frameSkips[animClip.name]) { totalFrame++; } motionData.motionFrameDataList = new MotionFrameData[totalFrame]; int frame = 0; for (int i = 0; i < bakeFrames; i += frameSkips[animClip.name]) { motionData.motionFrameDataList[frame] = new MotionFrameData(); motionData.motionFrameDataList[frame].motionBoneDataList = new MotionBoneData[bonesMap.Count]; motionData.motionFrameDataList[frame].motionTrajectoryDataList = new MotionTrajectoryData[predictionTrajectoryTimeList.Length]; for (int i1 = 0; i1 < bonesMap.Count; i1++) { motionData.motionFrameDataList[frame].motionBoneDataList[i1] = new MotionBoneData(); } for (int i2 = 0; i2 < predictionTrajectoryTimeList.Length; i2++) { motionData.motionFrameDataList[frame].motionTrajectoryDataList[i2] = new MotionTrajectoryData(); } frame++; } } int animCount = 0; for (int j = 0; j < clips.Count; j++) { //Vector3.zero, Quaternion.identity sampleGO.transform.position = Vector3.zero; sampleGO.transform.rotation = Quaternion.identity; AnimationClip animClip = clips[j]; MotionData motionData = meshAnimationList.motionDataList[j]; int bakeFrames = Mathf.CeilToInt(animClip.length * fps); int frame = 0; for (int i = 0; i < bakeFrames; i += frameSkips[animClip.name]) { float bakeDelta = Mathf.Clamp01(((float)i / bakeFrames)); EditorUtility.DisplayProgressBar("Baking Animation", string.Format("Processing: {0} Frame: {1}", animClip.name, i), bakeDelta); float animationTime = bakeDelta * animClip.length; MotionFrameData motionFrameData = motionData.motionFrameDataList[frame]; MotionFrameData lastMotionFrameData = frame > 0 ? motionData.motionFrameDataList[frame - 1] : null; CaptureBoneSnapShot(animClip, motionFrameData, lastMotionFrameData, sampleGO, bakeFrames, i); CaptureTrajectorySnapShot(animClip, motionFrameData, lastMotionFrameData, sampleGO, bakeFrames, i); frame++; } animCount++; } //string TargetPath = Application.dataPath + "/Resources/" + sampleGO.name + "_MotionField1.asset"; //AssetDatabase.DeleteAsset(TargetPath); //AssetDatabase.CreateAsset(meshAnimationList, TargetPath); AssetDatabase.CreateAsset(meshAnimationList, assetFolder + sampleGO.name + "_MotionField.asset"); GameObject.DestroyImmediate(sampleGO); EditorUtility.ClearProgressBar(); EditorUtility.DisplayDialog("MotionField", string.Format("Baked {0} motionField {1} successfully!", clips.Count, clips.Count > 1 ? "s" : string.Empty), "OK"); try { //Wait } catch (System.Exception e) { EditorUtility.ClearProgressBar(); EditorUtility.DisplayDialog("Bake Error", string.Format("There was a problem baking the animations.", e), "OK"); } finally { if (bakeController) { AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(bakeController)); } } }