/************************************************************************************************************************/ /// <summary>Creates and saves a new <see cref="AnimationClip"/> that plays the `sprites`.</summary> private static void CreateAnimation(string path, params Sprite[] sprites) { var frameRate = AnimancerSettings.NewAnimationFrameRate.floatValue; var clip = new AnimationClip { frameRate = frameRate, }; var spriteKeyFrames = new ObjectReferenceKeyframe[sprites.Length]; for (int i = 0; i < spriteKeyFrames.Length; i++) { spriteKeyFrames[i] = new ObjectReferenceKeyframe { time = i / (float)frameRate, value = sprites[i] }; } var spriteBinding = EditorCurveBinding.PPtrCurve("", typeof(SpriteRenderer), "m_Sprite"); AnimationUtility.SetObjectReferenceCurve(clip, spriteBinding, spriteKeyFrames); AssetDatabase.CreateAsset(clip, path); }
static AnimationClip CreateSpriteAnimation(params Sprite[] sprites) { var animationClip = new AnimationClip { frameRate = 12 }; var animationClipSettings = new AnimationClipSettings { loopTime = true }; AnimationUtility.SetAnimationClipSettings(animationClip, animationClipSettings); var objectReferenceKeyframes = new ObjectReferenceKeyframe[sprites.Length]; for (var i = 0; i < objectReferenceKeyframes.Length; i++) { objectReferenceKeyframes[i] = new ObjectReferenceKeyframe { value = sprites[i], time = i / animationClip.frameRate }; } var editorCurveBinding = EditorCurveBinding.PPtrCurve("", typeof(SpriteRenderer), "m_Sprite"); AnimationUtility.SetObjectReferenceCurve(animationClip, editorCurveBinding, objectReferenceKeyframes); return(animationClip); }
public static AnimationClip Create(SpriteAnimationClipDefinition spriteAnimationDefinition) { AnimationClip animClip = new AnimationClip { name = spriteAnimationDefinition.Name, frameRate = spriteAnimationDefinition.FrameRate, wrapMode = spriteAnimationDefinition.WrapMode }; if (spriteAnimationDefinition.IsLoop) { AnimationClipSettings settings = AnimationUtility.GetAnimationClipSettings(animClip); settings.loopTime = true; AnimationUtility.SetAnimationClipSettings(animClip, settings); } EditorCurveBinding editorCurveBinding = EditorCurveBinding.PPtrCurve(string.Empty, typeof(SpriteRenderer), "m_Sprite"); ObjectReferenceKeyframe[] keyframes = spriteAnimationDefinition.SpriteKeyframes .Select(spriteKeyframe => spriteKeyframe.ToObjectReferenceKeyframe()) .ToArray(); AnimationUtility.SetObjectReferenceCurve(animClip, editorCurveBinding, keyframes); return(animClip); }
private void _ModifyCurveBinding(EditorCurveBinding oneBinding, string newPath, string newProp, Type newType) { //object animWndCurve = oneInfo.m_AnimationWindowCurve; if (oneBinding.isPPtrCurve) { EditorCurveBinding newBinding = EditorCurveBinding.PPtrCurve(newPath, newType, newProp); //var array = (ObjectReferenceKeyframe[])RCall.CallMtd("UnityEditorInternal.AnimationWindowCurve", "ToObjectCurve", animWndCurve); ObjectReferenceKeyframe[] array = AnimationUtility.GetObjectReferenceCurve(m_CurClip, oneBinding); AnimationUtility.SetObjectReferenceCurve(m_CurClip, newBinding, array); //add new AnimationUtility.SetObjectReferenceCurve(m_CurClip, oneBinding, null); //remove old } else { EditorCurveBinding newBinding = EditorCurveBinding.FloatCurve(newPath, newType, newProp); //AnimationCurve curve = (AnimationCurve)RCall.CallMtd("UnityEditorInternal.AnimationWindowCurve", "ToAnimationCurve", animWndCurve); AnimationCurve curve = AnimationUtility.GetEditorCurve(m_CurClip, oneBinding); Dbg.Assert(curve != null, "AnimCurvePropEditor._ModifyCurveBinding: failed to get editorCurve"); AnimationUtility.SetEditorCurve(m_CurClip, newBinding, curve); //add new AnimationUtility.SetEditorCurve(m_CurClip, oneBinding, null); //remove old } }
private Sprite[] GetSprites(AnimationClip animationClip) { var sprites = new Sprite[0]; if (animationClip != null) { var editorCurveBinding = EditorCurveBinding.PPtrCurve("", typeof(SpriteRenderer), "m_Sprite"); var objectReferenceKeyframes = AnimationUtility.GetObjectReferenceCurve(animationClip, editorCurveBinding); var _sprites = objectReferenceKeyframes .Select(objectReferenceKeyframe => objectReferenceKeyframe.value) .OfType <Sprite>(); foreach (var sprite in _sprites) { AssetPreview.GetAssetPreview(sprite); } sprites = _sprites.ToArray(); } return(sprites); }
private void _GUI_AddNewCurve() { EditorWindow uaw = (EditorWindow)EUtil.GetUnityAnimationWindow(); object uawstate = EUtil.GetUnityAnimationWindowState(uaw); m_CurClip = RCall.GetField("UnityEditorInternal.AnimationWindowState", "m_ActiveAnimationClip", uawstate) as AnimationClip; if (m_CurClip == null) { EditorGUILayout.LabelField("Need an animation clip first..."); return; } m_NewPath = EditorGUILayout.TextField("Path:", m_NewPath); m_NewProperty = EditorGUILayout.TextField("Property:", m_NewProperty); m_TypeFullName = EditorGUILayout.TextField("TypeFullName:", m_TypeFullName); m_bIsPPtrCurve = EditorGUILayout.Toggle("IsPPtrCurve:", m_bIsPPtrCurve); EditorGUILayout.Separator(); bool bOK = true; EUtil.PushGUIColor(Color.red); if (string.IsNullOrEmpty(m_NewProperty)) { bOK = false; EditorGUILayout.LabelField("Property is not specified"); } if (string.IsNullOrEmpty(m_TypeFullName) || RCall.GetTypeFromString(m_TypeFullName, true) == null) { bOK = false; EditorGUILayout.LabelField(string.Format("No type is found for name: {0}", m_TypeFullName)); } EUtil.PopGUIColor(); EUtil.PushGUIEnable(bOK); { if (EUtil.Button("Add New Curve", Color.green)) { Type tp = RCall.GetTypeFromString(m_TypeFullName); if (m_bIsPPtrCurve) { EditorCurveBinding newBinding = EditorCurveBinding.PPtrCurve(m_NewPath, tp, m_NewProperty); AnimationUtility.SetObjectReferenceCurve(m_CurClip, newBinding, new ObjectReferenceKeyframe[0]); } else { EditorCurveBinding newBinding = EditorCurveBinding.FloatCurve(m_NewPath, tp, m_NewProperty); AnimationUtility.SetEditorCurve(m_CurClip, newBinding, new AnimationCurve()); } } } EUtil.PopGUIEnable(); }
/// <summary> /// Forces an animation clip to have a defined length of at least <paramref name="length"/> /// </summary> /// <param name="clip">The animation clip</param> /// <param name="length">Minimum length to make the animation clip</param> public static void AdjustAnimationClipLength( AnimationClip clip, float length) { var dummy_key = new ObjectReferenceKeyframe() { time = length }; var dummy_array = new[] { dummy_key }; var binding = EditorCurveBinding.PPtrCurve("Length Adjuster", typeof(UnityObject), ""); AnimationUtility.SetObjectReferenceCurve(clip, binding, dummy_array); }
public static void SetObjectReferenceKeyframe(AnimationClip animationClip, Component target, string attribute, Object reference, List <Object> dirtyAssets) { var path = AnimUtility.GetAnimationPath(target.transform); var type = target.GetType(); var binding = EditorCurveBinding.PPtrCurve(path, type, $"{attribute}"); var keyframe = new ObjectReferenceKeyframe { time = 0, value = reference, }; AnimationUtility.SetObjectReferenceCurve(animationClip, binding, new[] { keyframe }); dirtyAssets.Add(target); dirtyAssets.Add(animationClip); }
private void CreateAnimation(SpriteSerie serie, Texture2D tex, Transform anim, Transform rend, string targetFolder) { if (targetFolder.StartsWith(Application.dataPath)) { targetFolder = "Assets" + targetFolder.Substring(Application.dataPath.Length); } Sprite[] sprites = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(tex)).OfType <Sprite>().ToArray(); Dictionary <string, Sprite> lookupTable = new Dictionary <string, Sprite>(); foreach (Sprite s in sprites) { lookupTable[s.name] = s; } TextureImporter importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(tex)) as TextureImporter; SpriteMetaData[] spritesheed = importer.spritesheet; string transformPath = AnimationUtility.CalculateTransformPath(rend, anim); int framecount = serie.end - serie.start + 1; AnimationClip clip = new AnimationClip(); clip.name = $"{tex.name}_{serie.name}"; clip.frameRate = framecount; clip.wrapMode = WrapMode.Loop; // now some voodoo stuff to set sprite ref on those keyframes EditorCurveBinding binding = EditorCurveBinding.PPtrCurve(transformPath, typeof(SpriteRenderer), "m_Sprite"); ObjectReferenceKeyframe[] objectRefCurve = new ObjectReferenceKeyframe[framecount]; for (int i = 0; i < objectRefCurve.Length; i++) { objectRefCurve[i] = new ObjectReferenceKeyframe() { time = i / (float)framecount, value = lookupTable[spritesheed[serie.start + i].name] } } ; AnimationUtility.SetObjectReferenceCurve(clip, binding, objectRefCurve); AssetDatabase.CreateAsset(clip, $"{targetFolder}\\{clip.name}.anim"); } }
public static Sprite[] GetClipSprites(AnimationClip animationClip) { var sprites = new Sprite[0]; if (animationClip != null) { var editorCurveBinding = EditorCurveBinding.PPtrCurve("", typeof(SpriteRenderer), "m_Sprite"); var objectReferenceKeyframes = AnimationUtility.GetObjectReferenceCurve(animationClip, editorCurveBinding); if (objectReferenceKeyframes != null) { sprites = objectReferenceKeyframes .Select(objectReferenceKeyframe => objectReferenceKeyframe.value) .OfType <Sprite>().ToArray(); } } return(sprites); }
// animation editing public static void ScaleAnimationClip(AnimationClip clip, FrameRange range) { if (clip == null) { return; } float oldLength = clip.length; float newLength = range.Length / clip.frameRate; AnimationClipCurveData[] curves = AnimationUtility.GetAllCurves(clip, true); // when scaling, we need to adjust the tangents otherwise the curves will get completely distorted float tangentMultiplier = oldLength / newLength; for (int i = 0; i != curves.Length; ++i) { AnimationCurve curve = curves[i].curve; if (newLength < oldLength) { for (int j = 0; j < curve.keys.Length; ++j) { Keyframe newKeyframe = new Keyframe((curve.keys[j].time / oldLength) * newLength, curve.keys[j].value, curve.keys[j].inTangent * tangentMultiplier, curve.keys[j].outTangent * tangentMultiplier); newKeyframe.tangentMode = curve.keys[j].tangentMode; curve.MoveKey(j, newKeyframe); } } else { for (int j = curve.keys.Length - 1; j >= 0; --j) { Keyframe newKeyframe = new Keyframe((curve.keys[j].time / oldLength) * newLength, curve.keys[j].value, curve.keys[j].inTangent * tangentMultiplier, curve.keys[j].outTangent * tangentMultiplier); newKeyframe.tangentMode = curve.keys[j].tangentMode; curve.MoveKey(j, newKeyframe); } } AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.PPtrCurve(curves[i].path, curves[i].type, curves[i].propertyName), curve); } clip.EnsureQuaternionContinuity(); EditorApplication.RepaintAnimationWindow(); EditorUtility.SetDirty(clip); }
public static void CreateAnimation() { var texture = Selection.objects[0] as Texture2D; if (texture == null) { return; } var texturePath = AssetDatabase.GetAssetPath(texture); Sprite[] allSprites = AssetDatabase.LoadAllAssetsAtPath(texturePath).OfType <Sprite>().ToArray(); if (allSprites.Length == 0) { Debug.LogError("no anim sprite"); return; } Sprite[] animSprites = new Sprite[allSprites.Length]; for (int i = 0; i < allSprites.Length; i++) { animSprites[i] = allSprites[i]; } AnimationClip animClip = new AnimationClip(); animClip.frameRate = DefaultFrameRate; var spriteBinding = EditorCurveBinding.PPtrCurve(string.Empty, typeof(SpriteRenderer), "m_Sprite"); ObjectReferenceKeyframe[] spriteKeyFrames = new ObjectReferenceKeyframe[animSprites.Length]; for (int i = 0; i < spriteKeyFrames.Length; i++) { spriteKeyFrames[i] = new ObjectReferenceKeyframe(); spriteKeyFrames[i].time = (float)i / DefaultFrameRate; spriteKeyFrames[i].value = animSprites[i]; } AnimationUtility.SetObjectReferenceCurve(animClip, spriteBinding, spriteKeyFrames); var path = (texturePath.Remove(texturePath.Length - 3)) + "anim"; AssetDatabase.CreateAsset(animClip, AssetDatabase.GenerateUniqueAssetPath(path)); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); }
public override void OnSwitchOff() { var clip = AssetDatabase.LoadAssetAtPath <AnimationClip>(path); bool setDirty = false; foreach (var binding in AnimationUtility.GetObjectReferenceCurveBindings(clip)) { if (binding.type == typeof(ImageSpriteAnimationHook) && binding.propertyName == "sprite") { var replacement = EditorCurveBinding.PPtrCurve(binding.path, typeof(Image), "m_Sprite"); var keyframes = AnimationUtility.GetObjectReferenceCurve(clip, binding); AnimationUtility.SetObjectReferenceCurve(clip, replacement, keyframes); AnimationUtility.SetObjectReferenceCurve(clip, binding, null); setDirty = true; } } if (setDirty) { EditorUtility.SetDirty(clip); } }
public static AnimationClip CreateAnimationClip(FPlayAnimationEvent animEvent) { string filePath = EditorUtility.SaveFilePanelInProject("Create Animation...", animEvent.Owner.name, "anim", "Choose path..."); if (string.IsNullOrEmpty(filePath)) { return(null); } AnimationClip clip = UnityEditor.Animations.AnimatorController.AllocateAnimatorClip(System.IO.Path.GetFileNameWithoutExtension(filePath)); clip.frameRate = animEvent.Sequence.FrameRate; Transform ownerTransform = animEvent.Owner; Vector3 pos = ownerTransform.localPosition; Quaternion rot = ownerTransform.localRotation; Keyframe[] xPosKeys = new Keyframe[] { new Keyframe(0, pos.x), new Keyframe(animEvent.LengthTime, pos.x) }; Keyframe[] yPosKeys = new Keyframe[] { new Keyframe(0, pos.y), new Keyframe(animEvent.LengthTime, pos.y) }; Keyframe[] zPosKeys = new Keyframe[] { new Keyframe(0, pos.z), new Keyframe(animEvent.LengthTime, pos.z) }; Keyframe[] xRotKeys = new Keyframe[] { new Keyframe(0, rot.x), new Keyframe(animEvent.LengthTime, rot.x) }; Keyframe[] yRotKeys = new Keyframe[] { new Keyframe(0, rot.y), new Keyframe(animEvent.LengthTime, rot.y) }; Keyframe[] zRotKeys = new Keyframe[] { new Keyframe(0, rot.z), new Keyframe(animEvent.LengthTime, rot.z) }; Keyframe[] wRotKeys = new Keyframe[] { new Keyframe(0, rot.w), new Keyframe(animEvent.LengthTime, rot.w) }; // set the tangent mode int tangentMode = 10; // 10 is unity auto tangent mode for (int i = 0; i != xPosKeys.Length; ++i) { xPosKeys[i].tangentMode = tangentMode; yPosKeys[i].tangentMode = tangentMode; zPosKeys[i].tangentMode = tangentMode; xRotKeys[i].tangentMode = tangentMode; yRotKeys[i].tangentMode = tangentMode; zRotKeys[i].tangentMode = tangentMode; wRotKeys[i].tangentMode = tangentMode; } AnimationCurve xPos = new AnimationCurve(xPosKeys); AnimationCurve yPos = new AnimationCurve(yPosKeys); AnimationCurve zPos = new AnimationCurve(zPosKeys); AnimationCurve xRot = new AnimationCurve(xRotKeys); AnimationCurve yRot = new AnimationCurve(yRotKeys); AnimationCurve zRot = new AnimationCurve(zRotKeys); AnimationCurve wRot = new AnimationCurve(wRotKeys); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.PPtrCurve(string.Empty, typeof(Transform), "m_LocalPosition.x"), xPos); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.PPtrCurve(string.Empty, typeof(Transform), "m_LocalPosition.y"), yPos); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.PPtrCurve(string.Empty, typeof(Transform), "m_LocalPosition.z"), zPos); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.PPtrCurve(string.Empty, typeof(Transform), "m_LocalRotation.x"), xRot); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.PPtrCurve(string.Empty, typeof(Transform), "m_LocalRotation.y"), yRot); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.PPtrCurve(string.Empty, typeof(Transform), "m_LocalRotation.z"), zRot); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.PPtrCurve(string.Empty, typeof(Transform), "m_LocalRotation.w"), wRot); clip.EnsureQuaternionContinuity(); AssetDatabase.CreateAsset(clip, filePath); FAnimationEventInspector.SetAnimationClip(animEvent, clip); return(clip); }
void OnGUI() { if (GUILayout.Button("Get Sprite Editor Data")) { GetTextureToSpriteData(); } GUILayout.Label("Name"); sTxt = GUILayout.TextField(sTxt); GUILayout.Label("Sprite Folder"); Folder = EditorGUILayout.ObjectField(Folder, typeof(Object)); bLoop = GUILayout.Toggle(bLoop, "Loop"); string sPath = ""; bUseTagName = GUILayout.Toggle(bUseTagName, "Use Tag Name"); nFrameRate = int.Parse(GUILayout.TextField(nFrameRate.ToString())); for (int i = 0; i < FolderList.Count; i++) { GUILayout.BeginHorizontal(); GUILayout.Label(AssetDatabase.GetAssetPath(FolderList[i].PackingObject) + " / " + FolderList[i].PackingTag + " / " + FolderList[i].Loop); if (GUILayout.Button("X", GUILayout.Width(20))) { FolderList.RemoveAt(i); } bool bEachLoop = FolderList[i].Loop; bEachLoop = GUILayout.Toggle(bEachLoop, "Loop"); if (bEachLoop != FolderList[i].Loop) { FolderList[i].Loop = bEachLoop; } GUILayout.EndHorizontal(); } if (GUILayout.Button("Add") || EnterDown) { EnterDown = false; if (sTxt != string.Empty) { CreateSpriteAnimationStruct ttss = new CreateSpriteAnimationStruct(); if (bUseTagName) { sPath = AssetDatabase.GetAssetPath(Folder); string[] files = Directory.GetFiles(sPath, "*.png"); TextureImporter importer = TextureImporter.GetAtPath(files[0]) as TextureImporter; sTxt = importer.spritePackingTag; } ttss.PackingTag = sTxt; ttss.PackingObject = Folder; ttss.Loop = bLoop; FolderList.Add(ttss); } } if (GUILayout.Button("Create")) { if (Folder == null || sTxt == "") { return; } for (int j = 0; j < FolderList.Count; j++) { sPath = AssetDatabase.GetAssetPath(FolderList[j].PackingObject); string[] files = Directory.GetFiles(sPath, "*.png"); List <Sprite> listSprite = new List <Sprite>(); for (int i = 0; i < files.Length; i++) { //string sName = files[i].Split('\'') listSprite.Add(AssetDatabase.LoadAssetAtPath <Sprite>(files[i])); } Animation anim = new Animation(); AnimationClip clip = new AnimationClip(); AnimationClipSettings sts = AnimationUtility.GetAnimationClipSettings(clip); clip.frameRate = nFrameRate; if (FolderList[j].Loop) { clip.wrapMode = WrapMode.Loop; sts.loopTime = true; AnimationUtility.SetAnimationClipSettings(clip, sts); } sTxt = FolderList[j].PackingTag; //System.IO. EditorCurveBinding spriteBinding = EditorCurveBinding.PPtrCurve("", typeof(UnityEngine.UI.Image), "m_Sprite"); //spriteBinding.type = typeof(SpriteRenderer); //spriteBinding.path = ""; //spriteBinding.propertyName = "m_Sprite"; ObjectReferenceKeyframe[] spriteKeyFrames = new ObjectReferenceKeyframe[listSprite.Count]; Debug.Log(sPath + "/" + " :: " + files.Length + " listSprite.Length] :: " + listSprite.Count); for (int i = 0; i < (listSprite.Count); i++) { spriteKeyFrames[i] = new ObjectReferenceKeyframe(); spriteKeyFrames[i].time = i / clip.frameRate; spriteKeyFrames[i].value = listSprite[i]; } AnimationUtility.SetObjectReferenceCurve(clip, spriteBinding, spriteKeyFrames); //clip.setc //폴더명 CreatedAnimation AssetDatabase.CreateAsset(clip, "assets/CreatedAnimation/" + sTxt + ".anim"); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); EditorUtility.DisplayProgressBar("Progress Bar", "Now : " + (j + 1).ToString() + " Changing.....", (float)j / (float)FolderList.Count); } EditorUtility.ClearProgressBar(); } }
public static EditorCurveBinding GetDefaultSpriteCurveBinding() { return(EditorCurveBinding.PPtrCurve("", typeof(SpriteRenderer), "m_Sprite")); }
private void _CreateMirrorClip(string newPath) { ConvertMap convMap = new ConvertMap(); foreach (var entry in m_MatchMap) { string fromPath = entry.Key; string toPath = entry.Value.path; bool bFound = entry.Value.found; convMap[fromPath] = toPath; if (bFound) { convMap[toPath] = fromPath; } } AnimationClip newClip = new AnimationClip(); float totalTime = m_Clip.length; float deltaTime = 1 / m_Clip.frameRate; var allBindings = AnimationUtility.GetCurveBindings(m_Clip); //collect bindings based on same path Dictionary <string, CurveBindingGroup> bindingMap = new Dictionary <string, CurveBindingGroup>(); foreach (var oneBinding in allBindings) { string bindingPath = oneBinding.path; string bindingProp = oneBinding.propertyName; CurveBindingGroup grp = null; if (!bindingMap.TryGetValue(bindingPath, out grp)) { grp = new CurveBindingGroup(); grp.path = bindingPath; bindingMap.Add(bindingPath, grp); } if (bindingProp.StartsWith("m_LocalPosition")) { grp.HasPosCurves = true; } else if (bindingProp.StartsWith("m_LocalRotation")) { grp.HasRotCurves = true; } else { grp.OtherCurves.Add(oneBinding); } } // fix foreach (var oneEntry in bindingMap) { string oldBindingPath = oneEntry.Key; CurveBindingGroup grp = oneEntry.Value; // get newBindingPath string newBindingPath = oldBindingPath; if (convMap.ContainsKey(oldBindingPath)) { newBindingPath = convMap[oldBindingPath]; } Axis selfAxisValue = _GetAxisValue(oldBindingPath, convMap); Axis parentAxisValue = _GetAxisValueForParent(oldBindingPath, convMap); // fix rotation curve and bindingProp if (grp.HasRotCurves) { AnimationCurve xCurve = AnimationUtility.GetEditorCurve(m_Clip, EditorCurveBinding.FloatCurve(oldBindingPath, typeof(Transform), "m_LocalRotation.x")); AnimationCurve yCurve = AnimationUtility.GetEditorCurve(m_Clip, EditorCurveBinding.FloatCurve(oldBindingPath, typeof(Transform), "m_LocalRotation.y")); AnimationCurve zCurve = AnimationUtility.GetEditorCurve(m_Clip, EditorCurveBinding.FloatCurve(oldBindingPath, typeof(Transform), "m_LocalRotation.z")); AnimationCurve wCurve = AnimationUtility.GetEditorCurve(m_Clip, EditorCurveBinding.FloatCurve(oldBindingPath, typeof(Transform), "m_LocalRotation.w")); AnimationCurve newXCurve = null; AnimationCurve newYCurve = null; AnimationCurve newZCurve = null; AnimationCurve newWCurve = null; if (parentAxisValue != selfAxisValue) { newXCurve = new AnimationCurve(); newYCurve = new AnimationCurve(); newZCurve = new AnimationCurve(); newWCurve = new AnimationCurve(); Vector3 planeNormal = Vector3.zero; switch (parentAxisValue) { case Axis.XY: planeNormal = Vector3.forward; break; case Axis.XZ: planeNormal = Vector3.up; break; case Axis.YZ: planeNormal = Vector3.right; break; default: Dbg.LogErr("AnimMirrorEditorWindow._CreateMirrorClip: unexpected parentAxisValue: {0}", parentAxisValue); break; } for (float t = 0; t <= totalTime;) { Quaternion oldQ = _BakeQ(xCurve, yCurve, zCurve, wCurve, t); Quaternion newQ = _ReflectQ(oldQ, selfAxisValue, planeNormal); newXCurve.AddKey(t, newQ.x); newYCurve.AddKey(t, newQ.y); newZCurve.AddKey(t, newQ.z); newWCurve.AddKey(t, newQ.w); if (Mathf.Approximately(t, totalTime)) { break; } t = Mathf.Min(totalTime, t + deltaTime); } } else { newXCurve = xCurve; newYCurve = yCurve; newZCurve = zCurve; newWCurve = wCurve; switch (parentAxisValue) { case Axis.XY: { newXCurve = _NegateCurve(xCurve); newYCurve = _NegateCurve(yCurve); } break; case Axis.XZ: { newXCurve = _NegateCurve(xCurve); newZCurve = _NegateCurve(zCurve); } break; case Axis.YZ: { newYCurve = _NegateCurve(yCurve); newZCurve = _NegateCurve(zCurve); } break; default: Dbg.LogErr("AnimMirrorEditorWindow._CreateMirrorClip: unexpected parentAxisValue: {0}", parentAxisValue); break; } } AnimationUtility.SetEditorCurve(newClip, EditorCurveBinding.FloatCurve(newBindingPath, typeof(Transform), "m_LocalRotation.x"), newXCurve); AnimationUtility.SetEditorCurve(newClip, EditorCurveBinding.FloatCurve(newBindingPath, typeof(Transform), "m_LocalRotation.y"), newYCurve); AnimationUtility.SetEditorCurve(newClip, EditorCurveBinding.FloatCurve(newBindingPath, typeof(Transform), "m_LocalRotation.z"), newZCurve); AnimationUtility.SetEditorCurve(newClip, EditorCurveBinding.FloatCurve(newBindingPath, typeof(Transform), "m_LocalRotation.w"), newWCurve); } // fix position curve if (grp.HasPosCurves) { AnimationCurve xCurve = AnimationUtility.GetEditorCurve(m_Clip, EditorCurveBinding.FloatCurve(oldBindingPath, typeof(Transform), "m_LocalPosition.x")); AnimationCurve yCurve = AnimationUtility.GetEditorCurve(m_Clip, EditorCurveBinding.FloatCurve(oldBindingPath, typeof(Transform), "m_LocalPosition.y")); AnimationCurve zCurve = AnimationUtility.GetEditorCurve(m_Clip, EditorCurveBinding.FloatCurve(oldBindingPath, typeof(Transform), "m_LocalPosition.z")); AnimationCurve newXCurve = xCurve; AnimationCurve newYCurve = yCurve; AnimationCurve newZCurve = zCurve; Axis posAxisValue = _GetAxisValueForParent(oldBindingPath, convMap); switch (posAxisValue) { case Axis.XZ: { newYCurve = _NegateCurve(newYCurve); } break; case Axis.XY: { newZCurve = _NegateCurve(newZCurve); } break; case Axis.YZ: { newXCurve = _NegateCurve(newXCurve); } break; default: Dbg.LogErr("AnimMirrorEditorWindow._CreateMirrorClip: unexpected mirror axis value (2nd): {0}", posAxisValue); break; } AnimationUtility.SetEditorCurve(newClip, EditorCurveBinding.FloatCurve(newBindingPath, typeof(Transform), "m_LocalPosition.x"), newXCurve); AnimationUtility.SetEditorCurve(newClip, EditorCurveBinding.FloatCurve(newBindingPath, typeof(Transform), "m_LocalPosition.y"), newYCurve); AnimationUtility.SetEditorCurve(newClip, EditorCurveBinding.FloatCurve(newBindingPath, typeof(Transform), "m_LocalPosition.z"), newZCurve); } // other curves foreach (var oneBinding in grp.OtherCurves) { Type tp = oneBinding.type; string propName = oneBinding.propertyName; if (oneBinding.isPPtrCurve) { EditorCurveBinding newBinding = EditorCurveBinding.PPtrCurve(newBindingPath, tp, propName); ObjectReferenceKeyframe[] array = AnimationUtility.GetObjectReferenceCurve(m_Clip, oneBinding); AnimationUtility.SetObjectReferenceCurve(newClip, newBinding, array); //add new } else { EditorCurveBinding newBinding = EditorCurveBinding.FloatCurve(newBindingPath, tp, propName); AnimationCurve curve = AnimationUtility.GetEditorCurve(m_Clip, oneBinding); AnimationUtility.SetEditorCurve(newClip, newBinding, curve); //add new } } } //end of foreach // finishing part #if !U5 var oldAnimType = (ModelImporterAnimationType)RCall.CallMtd("UnityEditor.AnimationUtility", "GetAnimationType", null, m_Clip); AnimationUtility.SetAnimationType(newClip, oldAnimType); #endif AnimationClipSettings oldSettings = AnimationUtility.GetAnimationClipSettings(m_Clip); RCall.CallMtd("UnityEditor.AnimationUtility", "SetAnimationClipSettings", null, newClip, oldSettings); newClip.EnsureQuaternionContinuity(); // save to disk AnimationClip existingClip = AssetDatabase.LoadAssetAtPath(newPath, typeof(AnimationClip)) as AnimationClip; if (existingClip != null) { EditorUtility.CopySerialized(newClip, existingClip); } else { AssetDatabase.CreateAsset(newClip, newPath); } AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Dbg.Log("Created mirror-ed animation clip at: {0}", newPath); }