/// <summary> /// [HACK TRICK] /// get a TransformLst containing all active curves' transform in UAW /// </summary> private TrLst _GetActiveCurveTransforms() { //1. collect the TrPaths from active curves HashSet <string> strset = m_StrSet; strset.Clear(); IList curves = (IList)RCall.GetProp("UnityEditorInternal.AnimationWindowState", "activeCurves", m_AnimationWindowState); for (int idx = 0; idx < curves.Count; ++idx) { object oneCurve = curves[idx]; //AnimationWindowCurve string onePath = (string)RCall.GetProp("UnityEditorInternal.AnimationWindowCurve", "path", oneCurve); strset.Add(onePath); } //2. transform to Transform TrLst lst = new TrLst(); for (var ie = strset.GetEnumerator(); ie.MoveNext();) { string trPath = ie.Current; Transform tr = m_ClipRoot.Find(trPath); if (tr != null) { lst.Add(tr); } else { Dbg.LogWarn("CCEditor._GetActiveCurveTransforms: cannot get transform for: {0}", trPath); } } return(lst); }
private static bool _IsAnimationWindowOpenAndWithClip(out object uawstate, out AnimationClip clip) { uawstate = null; clip = null; EditorWindow uaw = (EditorWindow)EUtil.GetUnityAnimationWindow(); if (uaw == null) { return(false); } uawstate = EUtil.GetUnityAnimationWindowState(uaw); if (uawstate == null) { return(false); } //clip = RCall.GetField("UnityEditorInternal.AnimationWindowState", // "m_ActiveAnimationClip", uawstate) as AnimationClip; clip = RCall.GetProp("UnityEditorInternal.AnimationWindowState", "activeAnimationClip", uawstate) as AnimationClip; if (clip == null) { return(false); } return(true); }
/// <summary> /// [HACK TRICK] /// update every loop, /// current in-edit clip, clip's rootTr /// </summary> private void _UpdateInternalInfo() { AnimationClip curClip = null; Transform rootTr = null; m_AnimationWindowState = EUtil.GetUnityAnimationWindowState(m_UAW); if (m_AnimationWindowState != null) { curClip = RCall.GetField("UnityEditorInternal.AnimationWindowState", "m_ActiveAnimationClip", m_AnimationWindowState) as AnimationClip; #if U5 GameObject rootGO = RCall.GetProp("UnityEditorInternal.AnimationWindowState", "activeRootGameObject", m_AnimationWindowState) as GameObject; #else GameObject rootGO = RCall.GetField("UnityEditorInternal.AnimationWindowState", "m_RootGameObject", m_AnimationWindowState) as GameObject; #endif if (rootGO != null) { rootTr = rootGO.transform; } } else { curClip = null; rootTr = null; } if (curClip != m_CurClip) { _OnCurrentClipChange(m_CurClip, curClip); } if (rootTr != m_ClipRoot) { _OnRootTransformChange(m_ClipRoot, rootTr); } }
private void _NormalizeRotationsInClip(object uawstate, AnimationClip clip) { //float interval = 1 / clip.frameRate; IList allCurves = (IList)RCall.GetProp("UnityEditorInternal.AnimationWindowState", "allCurves", uawstate); foreach (var oneUAWCurve in allCurves) { EditorCurveBinding oneBinding = (EditorCurveBinding)RCall.GetProp("UnityEditorInternal.AnimationWindowCurve", "binding", oneUAWCurve); string prop = oneBinding.propertyName; string[] parts = prop.Split('.'); if (parts.Length != 2) { continue; } string main = parts[0]; //string acc = parts[1]; if (main == "localEulerAnglesRaw" || main == "localEulerAnglesBaked") { AnimationCurve curve = AnimationUtility.GetEditorCurve(clip, oneBinding); var keys = curve.keys; //////////////////// // 1. normalize the first key to [-PI, PI], get the delta, and apply delta on all other keys in this curve // 2. ensure the abs distance between each keyframe is less than 360 deg //////////////////// // 1 if (keys.Length == 0) { continue; } { float oldV = keys[0].value; float newV = Misc.NormalizeAnglePI(oldV); float delta = newV - oldV; // apply delta to all keyframes for (int i = 0; i < keys.Length; ++i) { var k = keys[i]; k.value += delta; k.inTangent = k.outTangent = 0; keys[i] = k; } } // 2 for (int i = 0; i < keys.Length - 1; ++i) { var k0 = keys[i]; var k1 = keys[i + 1]; float delta = (k1.value - k0.value) % 360f; k1.value = k0.value + delta; keys[i + 1] = k1; } curve.keys = keys; AnimationUtility.SetEditorCurve(clip, oneBinding, curve); } } }