public void Rebind(RebindOption bindOpt) { if (Application.isPlaying) { Transform tr = bindOpt.FindTr(m_trPath); m_runtimeCp = null; if (tr != null) { Type type = RCall.GetTypeFromString(m_compType, true); m_runtimeCp = tr.GetComponent(type); if (m_runtimeCp == null) { Dbg.LogWarn("RebindCp.Rebind: failed to get cp \"{0}\" on \"{1}\"", m_compType, m_trPath); } } else { Dbg.LogWarn("RebindCp.Rebind: failed to find \"{0}\"", m_trPath); } } else { Transform tr = bindOpt.FindTr(m_trPath); //even editTimeTr not null, it could be stale if (tr != null) { Type type = RCall.GetTypeFromString(m_compType, true); m_editTimeCp = tr.GetComponent(type); } } }
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(); }
private void _GUI_EditSingleCurve() { EditorWindow uaw = (EditorWindow)EUtil.GetUnityAnimationWindow(); object uawstate = EUtil.GetUnityAnimationWindowState(uaw); m_CurClip = RCall.GetField("UnityEditorInternal.AnimationWindowState", "m_ActiveAnimationClip", uawstate) as AnimationClip; IList curves = (IList)RCall.GetProp("UnityEditorInternal.AnimationWindowState", "activeCurves", uawstate); if (curves.Count != 1) { EditorGUILayout.LabelField(string.Format("Please select ONE curve, you have currently selected {0} curves", curves.Count)); return; } object oneCurve = curves[0]; //AnimationWindowCurve EditorCurveBinding oneBinding = (EditorCurveBinding)RCall.GetProp("UnityEditorInternal.AnimationWindowCurve", "binding", oneCurve); EditorGUILayout.LabelField("Path:"); EUtil.PushContentColor(Color.yellow); EditorGUILayout.SelectableLabel(oneBinding.path); EUtil.PopContentColor(); EditorGUILayout.LabelField("Property:"); EUtil.PushContentColor(Color.green); EditorGUILayout.SelectableLabel(oneBinding.propertyName); EUtil.PopContentColor(); EditorGUILayout.LabelField("IsPPtrCurve: " + oneBinding.isPPtrCurve.ToString()); EditorGUILayout.Separator(); m_NewType = EditorGUILayout.TextField("Type:", m_NewType); if (m_NewType.Length == 0) { m_NewType = oneBinding.type.ToString(); } m_NewPath = EditorGUILayout.TextField("New Path:", m_NewPath); m_NewProperty = EditorGUILayout.TextField("New Property:", m_NewProperty); Type newTp = RCall.GetTypeFromString(m_NewType, true); EUtil.PushGUIEnable(m_NewProperty.Length > 0 && newTp != null); if (EUtil.Button("Apply Change", Color.green)) { Undo.RegisterCompleteObjectUndo(m_CurClip, "Apply Curve Change"); _ModifyCurveBinding(oneBinding, m_NewPath, m_NewProperty, newTp); } EUtil.PopGUIEnable(); }
private void _GUI_BatchAddPrefix() { EditorWindow uaw = (EditorWindow)EUtil.GetUnityAnimationWindow(); object uawstate = EUtil.GetUnityAnimationWindowState(uaw); m_CurClip = RCall.GetField("UnityEditorInternal.AnimationWindowState", "m_ActiveAnimationClip", uawstate) as AnimationClip; //1. collect the TrPaths from active curves List <BindingInfo> bindingInfos = new List <BindingInfo>(); IList curves = (IList)RCall.GetProp("UnityEditorInternal.AnimationWindowState", "activeCurves", uawstate); for (int idx = 0; idx < curves.Count; ++idx) { object oneCurve = curves[idx]; //AnimationWindowCurve EditorCurveBinding oneBinding = (EditorCurveBinding)RCall.GetProp("UnityEditorInternal.AnimationWindowCurve", "binding", oneCurve); bindingInfos.Add(new BindingInfo(oneBinding, oneCurve)); } //2. display EditorGUILayout.LabelField("Selected curves:"); m_scrollPos = EditorGUILayout.BeginScrollView(m_scrollPos, false, true, GUILayout.Height(200f)); { foreach (var oneInfo in bindingInfos) { EditorCurveBinding oneBinding = oneInfo.m_Binding; GUILayout.BeginHorizontal(); { EUtil.PushContentColor(Color.yellow); GUILayout.Label(oneBinding.path); EUtil.PopContentColor(); EUtil.PushContentColor(Color.green); GUILayout.Label(oneBinding.propertyName); EUtil.PopContentColor(); } GUILayout.EndHorizontal(); } } EditorGUILayout.EndScrollView(); //3. apply prefix m_Prefix = EditorGUILayout.TextField("Prefix:", m_Prefix); EUtil.PushGUIEnable(m_CurClip != null && bindingInfos.Count > 0); if (EUtil.Button("Apply Prefix", Color.green)) { _DoApplyPrefix(bindingInfos, m_Prefix); } EUtil.PopGUIEnable(); }
private void _TryCollectBones() { Transform root = _bones[(int)Bones.Root]; Dictionary <Transform, bool> validBones = new Dictionary <Transform, bool>(); Transform[] allTransforms = root.GetComponentsInChildren <Transform>(); foreach (var b in allTransforms) { validBones[b] = true; } Dictionary <int, Transform> outDict = new Dictionary <int, Transform>(); outDict = (Dictionary <int, Transform>)RCall.CallMtd1("UnityEditor.AvatarAutoMapper", "MapBones", new Type[] { typeof(Transform), typeof(Dictionary <Transform, bool>) }, null, root, validBones); _bones[(int)Bones.Pelvis] = outDict.TryGet((int)HumanBodyBones.Hips); _bones[(int)Bones.UpperArmR] = outDict.TryGet((int)HumanBodyBones.RightUpperArm); _bones[(int)Bones.UpperArmL] = outDict.TryGet((int)HumanBodyBones.LeftUpperArm); _bones[(int)Bones.LowerArmR] = outDict.TryGet((int)HumanBodyBones.RightLowerArm); _bones[(int)Bones.LowerArmL] = outDict.TryGet((int)HumanBodyBones.LeftLowerArm); _bones[(int)Bones.HandR] = outDict.TryGet((int)HumanBodyBones.RightHand); _bones[(int)Bones.HandL] = outDict.TryGet((int)HumanBodyBones.LeftHand); _bones[(int)Bones.UpperLegR] = outDict.TryGet((int)HumanBodyBones.RightUpperLeg); _bones[(int)Bones.UpperLegL] = outDict.TryGet((int)HumanBodyBones.LeftUpperLeg); _bones[(int)Bones.LowerLegR] = outDict.TryGet((int)HumanBodyBones.RightLowerLeg); _bones[(int)Bones.LowerLegL] = outDict.TryGet((int)HumanBodyBones.LeftLowerLeg); _bones[(int)Bones.FootR] = outDict.TryGet((int)HumanBodyBones.RightFoot); _bones[(int)Bones.FootL] = outDict.TryGet((int)HumanBodyBones.LeftFoot); //foreach( var pr in outDict ) //{ // Dbg.Log(((HumanBodyBones)pr.Key) + ":" + pr.Value); //} }
private void _GUI_ChangePath() { EditorWindow uaw = (EditorWindow)EUtil.GetUnityAnimationWindow(); object uawstate = EUtil.GetUnityAnimationWindowState(uaw); m_CurClip = RCall.GetField("UnityEditorInternal.AnimationWindowState", "m_ActiveAnimationClip", uawstate) as AnimationClip; //1. collect the TrPaths from active curves List <EditorCurveBinding> bindingInfos = new List <EditorCurveBinding>(); IList curves = (IList)RCall.GetProp("UnityEditorInternal.AnimationWindowState", "activeCurves", uawstate); if (curves.Count <= 0) { EditorGUILayout.LabelField("Please Select a Curve first..."); return; } EditorCurveBinding theBinding = (EditorCurveBinding)RCall.GetProp("UnityEditorInternal.AnimationWindowCurve", "binding", curves[0]); string toChangePath = theBinding.path; IList allCurves = (IList)RCall.GetProp("UnityEditorInternal.AnimationWindowState", "allCurves", uawstate); foreach (var oneUAWCurve in allCurves) { EditorCurveBinding oneBinding = (EditorCurveBinding)RCall.GetProp("UnityEditorInternal.AnimationWindowCurve", "binding", oneUAWCurve); if (oneBinding.path == toChangePath) { bindingInfos.Add(oneBinding); } } //2. display EditorGUILayout.LabelField("Affected curves:"); m_scrollPos = EditorGUILayout.BeginScrollView(m_scrollPos, false, true, GUILayout.Height(200f)); { foreach (var oneInfo in bindingInfos) { EditorCurveBinding oneBinding = oneInfo; GUILayout.BeginHorizontal(); { EUtil.PushContentColor(Color.yellow); GUILayout.Label(oneBinding.path); EUtil.PopContentColor(); EUtil.PushContentColor(Color.green); GUILayout.Label(oneBinding.propertyName); EUtil.PopContentColor(); } GUILayout.EndHorizontal(); } } EditorGUILayout.EndScrollView(); //3. apply prefix EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("R", GUILayout.Width(20))) { GUIUtility.keyboardControl = 0; m_NewPath = toChangePath; } m_NewPath = EditorGUILayout.TextField("New Path:", m_NewPath); EditorGUILayout.EndHorizontal(); EUtil.PushGUIEnable(m_CurClip != null && bindingInfos.Count > 0); if (EUtil.Button("Change Path!", Color.green)) { _DoChangePath(bindingInfos, m_NewPath); } EUtil.PopGUIEnable(); }
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); }