public AnimationWindowHierarchyPropertyGroupNode(System.Type animatableObjectType, int setId, string propertyName, string path, TreeViewItem parent) : base(AnimationWindowUtility.GetPropertyNodeID(setId, path, animatableObjectType, propertyName), parent != null ? parent.depth + 1 : -1, parent, animatableObjectType, AnimationWindowUtility.GetPropertyGroupName(propertyName), path, AnimationWindowUtility.GetNicePropertyGroupDisplayName(animatableObjectType, propertyName)) { }
private void HandleHotKeys() { if (GUI.enabled && !this.m_State.disabled) { bool flag = false; if (AnimEditor.kAnimationPrevKeyframe.activated) { this.MoveToPreviousKeyframe(); flag = true; } if (AnimEditor.kAnimationNextKeyframe.activated) { this.MoveToNextKeyframe(); flag = true; } if (AnimEditor.kAnimationNextFrame.activated) { this.m_State.frame++; flag = true; } if (AnimEditor.kAnimationPrevFrame.activated) { this.m_State.frame--; flag = true; } if (AnimEditor.kAnimationFirstKey.activated) { this.MoveToFirstKeyframe(); flag = true; } if (AnimEditor.kAnimationLastKey.activated) { this.MoveToLastKeyframe(); flag = true; } if (flag) { Event.current.Use(); this.Repaint(); } if (AnimEditor.kAnimationPlayToggle.activated) { this.m_State.playing = !this.m_State.playing; this.m_PreviousUpdateTime = Time.realtimeSinceStartup; Event.current.Use(); } if (AnimEditor.kAnimationPlayToggle.activated) { this.m_State.playing = !this.m_State.playing; this.m_PreviousUpdateTime = Time.realtimeSinceStartup; Event.current.Use(); } if (AnimEditor.kAnimationRecordKeyframe.activated) { this.SaveCurveEditorKeySelection(); AnimationKeyTime time = AnimationKeyTime.Time(this.m_State.currentTime, this.m_State.frameRate); AnimationWindowUtility.AddSelectedKeyframes(this.m_State, time); this.UpdateSelectedKeysToCurveEditor(); Event.current.Use(); } } }
private void SetupWizardOnGUI(Rect position) { Rect position1 = new Rect(position.x, position.y, position.width - 15f, position.height - 15f); GUI.BeginClip(position1); GUI.enabled = true; this.m_State.showCurveEditor = false; this.m_State.timeArea = (TimeArea)this.m_DopeSheet; this.m_State.timeArea.SetShownHRangeInsideMargins(0.0f, 1f); if ((bool)((UnityEngine.Object)Selection.activeGameObject) && !EditorUtility.IsPersistent((UnityEngine.Object)Selection.activeGameObject)) { string str = (bool)((UnityEngine.Object) this.m_State.activeRootGameObject) || (bool)((UnityEngine.Object) this.m_State.activeAnimationClip) ? AnimationWindowStyles.animationClip.text : AnimationWindowStyles.animatorAndAnimationClip.text; GUIContent content = GUIContent.Temp(string.Format(AnimationWindowStyles.formatIsMissing.text, (object)Selection.activeGameObject.name, (object)str)); Vector2 vector2 = GUI.skin.label.CalcSize(content); Rect position2 = new Rect((float)((double)position1.width * 0.5 - (double)vector2.x * 0.5), (float)((double)position1.height * 0.5 - (double)vector2.y * 0.5), vector2.x, vector2.y); GUI.Label(position2, content); if (GUI.Button(new Rect((float)((double)position1.width * 0.5 - 35.0), position2.yMax + 3f, 70f, 20f), AnimationWindowStyles.create) && AnimationWindowUtility.InitializeGameobjectForAnimation(Selection.activeGameObject)) { this.m_State.activeAnimationClip = AnimationUtility.GetAnimationClips(AnimationWindowUtility.GetClosestAnimationPlayerComponentInParents(Selection.activeGameObject.transform).gameObject)[0]; this.m_State.recording = true; this.m_State.currentTime = 0.0f; this.m_State.ResampleAnimation(); } } else { Color color = GUI.color; GUI.color = Color.gray; Vector2 vector2 = GUI.skin.label.CalcSize(AnimationWindowStyles.noAnimatableObjectSelectedText); GUI.Label(new Rect((float)((double)position1.width * 0.5 - (double)vector2.x * 0.5), (float)((double)position1.height * 0.5 - (double)vector2.y * 0.5), vector2.x, vector2.y), AnimationWindowStyles.noAnimatableObjectSelectedText); GUI.color = color; } GUI.EndClip(); GUI.enabled = false; }
static bool IsRotationCurve(string propertyName) { string groupName = AnimationWindowUtility.GetPropertyGroupName(propertyName); return(groupName == kLocalRotation || groupName == kLocalEulerHint); }
public override void GoToNextKeyframe() { var newTime = AnimationWindowUtility.GetNextKeyframeTime(GetCurves(), time.time, m_AnimWindowState.clipFrameRate); GoToTime(m_AnimWindowState.SnapToFrame(newTime, AnimationWindowState.SnapMode.SnapToClipFrame)); }
public override void GoToNextKeyframe() { float nextKeyframeTime = AnimationWindowUtility.GetNextKeyframeTime(this.GetCurves(), this.get_time().get_time(), this.m_AnimWindowState.get_clipFrameRate()); this.GoToTime(this.m_AnimWindowState.SnapToFrame(nextKeyframeTime, 2)); }
private void FillInMissingTransformCurves(List <AnimationWindowCurve> transformCurves, ref List <AnimationWindowCurve> curvesCache) { EditorCurveBinding lastBinding = transformCurves[0].binding; var propertyGroup = new EditorCurveBinding?[3]; string propertyGroupName; foreach (var transformCurve in transformCurves) { var transformBinding = transformCurve.binding; //if it's a new property group if (transformBinding.path != lastBinding.path || AnimationWindowUtility.GetPropertyGroupName(transformBinding.propertyName) != AnimationWindowUtility.GetPropertyGroupName(lastBinding.propertyName)) { propertyGroupName = AnimationWindowUtility.GetPropertyGroupName(lastBinding.propertyName); FillPropertyGroup(ref propertyGroup, lastBinding, propertyGroupName, ref curvesCache); lastBinding = transformBinding; propertyGroup = new EditorCurveBinding?[3]; } AssignBindingToRightSlot(transformBinding, ref propertyGroup); } FillPropertyGroup(ref propertyGroup, lastBinding, AnimationWindowUtility.GetPropertyGroupName(lastBinding.propertyName), ref curvesCache); }
public AddCurvesPopupPropertyNode(TreeViewItem parent, EditorCurveBinding[] curveBindings) : base(curveBindings[0].GetHashCode(), parent.depth + 1, parent, AnimationWindowUtility.NicifyPropertyGroupName(curveBindings[0].type, AnimationWindowUtility.GetPropertyGroupName(curveBindings[0].propertyName))) { this.curveBindings = curveBindings; }
private TreeViewItem AddGameObjectToHierarchy(GameObject gameObject, GameObject rootGameObject, AnimationClip animationClip, TreeViewItem parent) { string path = AnimationUtility.CalculateTransformPath(gameObject.transform, rootGameObject.transform); AddCurvesPopupGameObjectNode node = new AddCurvesPopupGameObjectNode(gameObject, parent, gameObject.name); List <TreeViewItem> childNodes = new List <TreeViewItem>(); if (m_RootItem == null) { m_RootItem = node; } // Iterate over all animatable objects EditorCurveBinding[] allCurveBindings = AnimationUtility.GetAnimatableBindings(gameObject, rootGameObject); List <EditorCurveBinding> singleObjectBindings = new List <EditorCurveBinding>(); for (int i = 0; i < allCurveBindings.Length; i++) { EditorCurveBinding curveBinding = allCurveBindings[i]; singleObjectBindings.Add(curveBinding); // Don't create group for GameObject.m_IsActive. It looks messy if (curveBinding.propertyName == "m_IsActive") { // Don't show for the root go if (curveBinding.path != "") { TreeViewItem newNode = CreateNode(singleObjectBindings.ToArray(), node); if (newNode != null) { childNodes.Add(newNode); } singleObjectBindings.Clear(); } else { singleObjectBindings.Clear(); } } else { // We expect allCurveBindings to come sorted by type bool isLastItemOverall = (i == allCurveBindings.Length - 1); bool isLastItemOnThisGroup = false; if (!isLastItemOverall) { isLastItemOnThisGroup = (allCurveBindings[i + 1].type != curveBinding.type); } // Let's not add those that already have a existing curve. if (AnimationWindowUtility.IsCurveCreated(animationClip, curveBinding)) { singleObjectBindings.Remove(curveBinding); } // Remove animator enabled property which shouldn't be animated. if (curveBinding.type == typeof(Animator) && curveBinding.propertyName == "m_Enabled") { singleObjectBindings.Remove(curveBinding); } if ((isLastItemOverall || isLastItemOnThisGroup) && singleObjectBindings.Count > 0) { childNodes.Add(AddAnimatableObjectToHierarchy(singleObjectBindings.ToArray(), node, path)); singleObjectBindings.Clear(); } } } var animator = rootGameObject.GetComponent <Animator>(); if (animator != null) { //If the Animator has a human avatar, we need to check if the avatar's hierarchy matches that of the current GameObject. If they do not match, disable the node. if (animator.avatarRoot != null && animator.isHuman) { if (animator.avatarRoot.Find(path) == null) { node.disabled = true; } } } if (showEntireHierarchy) { // Iterate over all child GOs for (int i = 0; i < gameObject.transform.childCount; i++) { Transform childTransform = gameObject.transform.GetChild(i); TreeViewItem childNode = AddGameObjectToHierarchy(childTransform.gameObject, rootGameObject, animationClip, node); if (childNode != null) { childNodes.Add(childNode); } } } TreeViewUtility.SetChildParentReferences(childNodes, node); return(node); }
static void AddRotationKey(AnimationClip clip, EditorCurveBinding sourceBind, SerializedProperty prop, double time) { if (prop.propertyType != SerializedPropertyType.Quaternion) { return; } var updateCurves = new List <AnimationCurve>(); var updateBindings = new List <EditorCurveBinding>(); var info = AnimationClipCurveCache.Instance.GetCurveInfo(clip); for (var i = 0; i < info.bindings.Length; i++) { if (sourceBind.type != info.bindings[i].type) { continue; } if (info.bindings[i].propertyName.Contains("localEuler")) { updateBindings.Add(info.bindings[i]); updateCurves.Add(info.curves[i]); } } // use this instead of serialized properties because the editor will attempt to maintain // correct localeulers var eulers = ((Transform)prop.serializedObject.targetObject).localEulerAngles; if (updateBindings.Count == 0) { var propName = AnimationWindowUtility.GetPropertyGroupName(sourceBind.propertyName); updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".x")); updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".y")); updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".z")); var curveX = new AnimationCurve(); var curveY = new AnimationCurve(); var curveZ = new AnimationCurve(); AddKeyFrameToCurve(curveX, (float)time, clip.frameRate, eulers.x, false); AddKeyFrameToCurve(curveY, (float)time, clip.frameRate, eulers.y, false); AddKeyFrameToCurve(curveZ, (float)time, clip.frameRate, eulers.z, false); updateCurves.Add(curveX); updateCurves.Add(curveY); updateCurves.Add(curveZ); } for (var i = 0; i < updateBindings.Count; i++) { var c = updateBindings[i].propertyName.Last(); var value = eulers.x; if (c == 'y') { value = eulers.y; } else if (c == 'z') { value = eulers.z; } AddKeyFrameToCurve(updateCurves[i], (float)time, clip.frameRate, value, false); } UpdateEditorCurves(clip, updateBindings, updateCurves); }
private TreeViewItem AddAnimatableObjectToHierarchy(EditorCurveBinding[] curveBindings, TreeViewItem parentNode, string path) { TreeViewItem node = new AddCurvesPopupObjectNode(parentNode, path, GetClassName(curveBindings[0])); node.icon = GetIcon(curveBindings[0]); List <TreeViewItem> childNodes = new List <TreeViewItem>(); List <EditorCurveBinding> singlePropertyBindings = new List <EditorCurveBinding>(); for (int i = 0; i < curveBindings.Length; i++) { EditorCurveBinding curveBinding = curveBindings[i]; singlePropertyBindings.Add(curveBinding); // We expect curveBindings to come sorted by propertyname if (i == curveBindings.Length - 1 || AnimationWindowUtility.GetPropertyGroupName(curveBindings[i + 1].propertyName) != AnimationWindowUtility.GetPropertyGroupName(curveBinding.propertyName)) { TreeViewItem newNode = CreateNode(singlePropertyBindings.ToArray(), node); if (newNode != null) { childNodes.Add(newNode); } singlePropertyBindings.Clear(); } } childNodes.Sort(); TreeViewUtility.SetChildParentReferences(childNodes, node); return(node); }
// Add a floating point curve key static void AddFloatKey(AnimationClip clip, EditorCurveBinding sourceBind, SerializedProperty prop, double time) { var updateCurves = new List <AnimationCurve>(); var updateBindings = new List <EditorCurveBinding>(); var updated = false; var info = AnimationClipCurveCache.Instance.GetCurveInfo(clip); for (var i = 0; i < info.bindings.Length; i++) { var binding = info.bindings[i]; if (binding.type != sourceBind.type) { continue; } SerializedProperty valProp = null; var curve = info.curves[i]; // perfect match on property path, editting a float if (prop.propertyPath.Equals(binding.propertyName)) { valProp = prop; } // this is a child object else if (binding.propertyName.Contains(prop.propertyPath)) { valProp = prop.serializedObject.FindProperty(binding.propertyName); } if (valProp != null) { var value = GetKeyValue(valProp); if (!float.IsNaN(value)) // Nan indicates an error retrieving the property value { updated = true; AddKeyFrameToCurve(curve, (float)time, clip.frameRate, value, valProp.propertyType == SerializedPropertyType.Boolean); updateCurves.Add(curve); updateBindings.Add(binding); } } } // Curves don't exist, add them if (!updated) { var propName = AnimationWindowUtility.GetPropertyGroupName(sourceBind.propertyName); if (!prop.hasChildren) { var value = GetKeyValue(prop); if (!float.IsNaN(value)) { updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, sourceBind.propertyName)); var curve = new AnimationCurve(); AddKeyFrameToCurve(curve, (float)time, clip.frameRate, value, prop.propertyType == SerializedPropertyType.Boolean); updateCurves.Add(curve); } } else { // special case because subproperties on color aren't 'visible' so you can't iterate over them if (prop.propertyType == SerializedPropertyType.Color) { updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".r")); updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".g")); updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".b")); updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, propName + ".a")); var c = prop.colorValue; for (var i = 0; i < 4; i++) { var curve = new AnimationCurve(); AddKeyFrameToCurve(curve, (float)time, clip.frameRate, c[i], prop.propertyType == SerializedPropertyType.Boolean); updateCurves.Add(curve); } } else { prop = prop.Copy(); foreach (SerializedProperty cp in prop) { updateBindings.Add(EditorCurveBinding.FloatCurve(sourceBind.path, sourceBind.type, cp.propertyPath)); var curve = new AnimationCurve(); AddKeyFrameToCurve(curve, (float)time, clip.frameRate, GetKeyValue(cp), cp.propertyType == SerializedPropertyType.Boolean); updateCurves.Add(curve); } } } } UpdateEditorCurves(clip, updateBindings, updateCurves); }
public override void OnInspectorGUI() { bool isEditingMultipleObjects = targets.Length > 1; bool cullingModeChanged = false; bool updateModeChanged = false; Animator firstAnimator = target as Animator; serializedObject.UpdateIfRequiredOrScript(); UpdateShowOptions(); EditorGUI.BeginChangeCheck(); var controller = EditorGUILayout.ObjectField("Controller", firstAnimator.runtimeAnimatorController, typeof(RuntimeAnimatorController), false) as RuntimeAnimatorController; if (EditorGUI.EndChangeCheck()) { foreach (Animator animator in targets) { Undo.RecordObject(animator, "Changed AnimatorController"); animator.runtimeAnimatorController = controller; } AnimationWindowUtility.ControllerChanged(); } EditorGUILayout.PropertyField(m_Avatar); if (firstAnimator.supportsOnAnimatorMove && !isEditingMultipleObjects) { EditorGUILayout.LabelField("Apply Root Motion", "Handled by Script"); } else { EditorGUILayout.PropertyField(m_ApplyRootMotion, styles.applyRootMotion); // This might change between layout & repaint so we have local cached value to only update on layout if (Event.current.type == EventType.Layout) { m_IsRootPositionOrRotationControlledByCurves = firstAnimator.isRootPositionOrRotationControlledByCurves; } if (!m_ApplyRootMotion.boolValue && m_IsRootPositionOrRotationControlledByCurves) { EditorGUILayout.HelpBox("Root position or rotation are controlled by curves", MessageType.Info, true); } } EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_UpdateMode, styles.updateMode); updateModeChanged = EditorGUI.EndChangeCheck(); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_CullingMode, styles.cullingMode); cullingModeChanged = EditorGUI.EndChangeCheck(); if (!isEditingMultipleObjects) { EditorGUILayout.HelpBox(firstAnimator.GetStats(), MessageType.Info, true); } if (EditorGUILayout.BeginFadeGroup(m_ShowWarningMessage.faded)) { EditorGUILayout.HelpBox(WarningMessage, MessageType.Warning, true); } EditorGUILayout.EndFadeGroup(); serializedObject.ApplyModifiedProperties(); foreach (Animator animator in targets) { if (cullingModeChanged) { animator.OnCullingModeChanged(); } if (updateModeChanged) { animator.OnUpdateModeChanged(); } } }
public AnimationWindowHierarchyPropertyNode(System.Type animatableObjectType, int setId, string propertyName, string path, TreeViewItem parent, EditorCurveBinding binding, bool isPptrNode) : base(AnimationWindowUtility.GetPropertyNodeID(setId, path, animatableObjectType, propertyName), parent != null ? parent.depth + 1 : -1, parent, animatableObjectType, propertyName, path, AnimationWindowUtility.GetNicePropertyDisplayName(animatableObjectType, propertyName)) { this.binding = binding; this.isPptrNode = isPptrNode; }
private void DeleteKeysAtCurrentTime(List <AnimationWindowCurve> curves) { AnimationWindowUtility.RemoveKeyframes(state, curves, state.time); }
private AnimationWindowHierarchyPropertyGroupNode AddPropertyGroupToHierarchy(AnimationWindowCurve[] curves, AnimationWindowHierarchyNode parentNode) { List <AnimationWindowHierarchyNode> childNodes = new List <AnimationWindowHierarchyNode>(); System.Type animatableObjectType = curves[0].type; AnimationWindowHierarchyPropertyGroupNode node = new AnimationWindowHierarchyPropertyGroupNode(animatableObjectType, 0, AnimationWindowUtility.GetPropertyGroupName(curves[0].propertyName), curves[0].path, parentNode); node.icon = GetIcon(curves[0].binding); node.indent = curves[0].depth; node.curves = curves; foreach (AnimationWindowCurve curve in curves) { AnimationWindowHierarchyPropertyNode childNode = AddPropertyToHierarchy(curve, node); // For child nodes we do not want to display the type in front (It is already shown by the group node) childNode.displayName = AnimationWindowUtility.GetPropertyDisplayName(childNode.propertyName); childNodes.Add(childNode); } TreeViewUtility.SetChildParentReferences(new List <TreeViewItem>(childNodes.ToArray()), node); return(node); }
private void RemoveCurvesFromNodes(List <AnimationWindowHierarchyNode> nodes) { string undoLabel = "Remove Curve"; state.SaveKeySelection(undoLabel); foreach (var node in nodes) { AnimationWindowHierarchyNode hierarchyNode = (AnimationWindowHierarchyNode)node; if (hierarchyNode.parent is AnimationWindowHierarchyPropertyGroupNode && hierarchyNode.binding != null && AnimationWindowUtility.ForceGrouping((EditorCurveBinding)hierarchyNode.binding)) { hierarchyNode = (AnimationWindowHierarchyNode)hierarchyNode.parent; } if (hierarchyNode.curves == null) { continue; } List <AnimationWindowCurve> curves = null; // Property or propertygroup if (hierarchyNode is AnimationWindowHierarchyPropertyGroupNode || hierarchyNode is AnimationWindowHierarchyPropertyNode) { curves = AnimationWindowUtility.FilterCurves(hierarchyNode.curves.ToArray(), hierarchyNode.path, hierarchyNode.animatableObjectType, hierarchyNode.propertyName); } else { curves = AnimationWindowUtility.FilterCurves(hierarchyNode.curves.ToArray(), hierarchyNode.path, hierarchyNode.animatableObjectType); } foreach (AnimationWindowCurve animationWindowCurve in curves) { state.RemoveCurve(animationWindowCurve, undoLabel); } } m_TreeView.ReloadData(); state.controlInterface.ResampleAnimation(); }
public List <AnimationWindowHierarchyNode> CreateTreeFromCurves() { List <AnimationWindowHierarchyNode> nodes = new List <AnimationWindowHierarchyNode>(); List <AnimationWindowCurve> singlePropertyCurves = new List <AnimationWindowCurve>(); AnimationWindowCurve[] curves = state.allCurves.ToArray(); AnimationWindowHierarchyNode parentNode = (AnimationWindowHierarchyNode)m_RootItem; for (int i = 0; i < curves.Length; i++) { AnimationWindowCurve curve = curves[i]; if (!state.ShouldShowCurve(curve)) { continue; } AnimationWindowCurve nextCurve = i < curves.Length - 1 ? curves[i + 1] : null; singlePropertyCurves.Add(curve); bool areSameGroup = nextCurve != null && AnimationWindowUtility.GetPropertyGroupName(nextCurve.propertyName) == AnimationWindowUtility.GetPropertyGroupName(curve.propertyName); bool areSamePathAndType = nextCurve != null && curve.path.Equals(nextCurve.path) && curve.type == nextCurve.type; // We expect curveBindings to come sorted by propertyname // So we compare curve vs nextCurve. If its different path or different group (think "scale.xyz" as group), then we know this is the last element of such group. if (i == curves.Length - 1 || !areSameGroup || !areSamePathAndType) { if (singlePropertyCurves.Count > 1) { nodes.Add(AddPropertyGroupToHierarchy(singlePropertyCurves.ToArray(), parentNode)); } else { nodes.Add(AddPropertyToHierarchy(singlePropertyCurves[0], parentNode)); } singlePropertyCurves.Clear(); } } return(nodes); }
private void HandleHotKeys() { if (!GUI.enabled || m_State.disabled) { return; } bool keyChanged = false; if (kAnimationPrevKeyframe.activated) { controlInterface.GoToPreviousKeyframe(); keyChanged = true; } if (kAnimationNextKeyframe.activated) { controlInterface.GoToNextKeyframe(); keyChanged = true; } if (kAnimationNextFrame.activated) { controlInterface.GoToNextFrame(); keyChanged = true; } if (kAnimationPrevFrame.activated) { controlInterface.GoToPreviousFrame(); keyChanged = true; } if (kAnimationFirstKey.activated) { controlInterface.GoToFirstKeyframe(); keyChanged = true; } if (kAnimationLastKey.activated) { controlInterface.GoToLastKeyframe(); keyChanged = true; } if (keyChanged) { Event.current.Use(); Repaint(); } if (kAnimationPlayToggle.activated) { if (controlInterface.playing) { controlInterface.StopPlayback(); } else { controlInterface.StartPlayback(); } Event.current.Use(); } if (kAnimationRecordKeyframeSelected.activated) { SaveCurveEditorKeySelection(); AnimationWindowUtility.AddSelectedKeyframes(m_State, controlInterface.time); UpdateSelectedKeysToCurveEditor(); Event.current.Use(); } if (kAnimationRecordKeyframeModified.activated) { SaveCurveEditorKeySelection(); controlInterface.ProcessCandidates(); UpdateSelectedKeysToCurveEditor(); Event.current.Use(); } }
private static bool CreateAnimation(GameObject gameObject, UnityEngine.Object[] frames, SpriteUtility.ShowFileDialogDelegate saveFileDialog) { SpriteUtility.ShowFileDialogDelegate arg_26_0; if ((arg_26_0 = saveFileDialog) == null) { if (SpriteUtility.< > f__mg$cache1 == null) { SpriteUtility.< > f__mg$cache1 = new SpriteUtility.ShowFileDialogDelegate(EditorUtility.SaveFilePanelInProject); } arg_26_0 = SpriteUtility.< > f__mg$cache1; } saveFileDialog = arg_26_0; Array.Sort <UnityEngine.Object>(frames, (UnityEngine.Object a, UnityEngine.Object b) => EditorUtility.NaturalCompare(a.name, b.name)); Animator animator = (!AnimationWindowUtility.EnsureActiveAnimationPlayer(gameObject)) ? null : AnimationWindowUtility.GetClosestAnimatorInParents(gameObject.transform); bool flag = animator != null; bool result; if (animator != null) { string message = string.Format("Create a new animation for the game object '{0}':", gameObject.name); string activeFolderPath = ProjectWindowUtil.GetActiveFolderPath(); string text = saveFileDialog("Create New Animation", "New Animation", "anim", message, activeFolderPath); if (string.IsNullOrEmpty(text)) { UnityEngine.Object.DestroyImmediate(animator); result = false; return(result); } AnimationClip animationClip = AnimationWindowUtility.CreateNewClipAtPath(text); if (animationClip != null) { SpriteUtility.AddSpriteAnimationToClip(animationClip, frames); flag = AnimationWindowUtility.AddClipToAnimatorComponent(animator, animationClip); } } if (!flag) { Debug.LogError("Failed to create animation for dragged object"); } result = flag; return(result); }
public void SaveCurve(AnimationWindowCurve curve) { Undo.RegisterCompleteObjectUndo(activeAnimationClip, L10n.Tr("Edit Curve")); AnimationWindowUtility.SaveCurve(activeAnimationClip, curve); }
static bool DoesPropertyPathMatch(string a, string b) { return(AnimationWindowUtility.GetPropertyGroupName(a).Equals(AnimationWindowUtility.GetPropertyGroupName(a))); }
public static bool DoesPropertyPathMatch(string a, string b) { return(AnimationWindowUtility.GetPropertyGroupName(a).Equals(AnimationWindowUtility.GetPropertyGroupName(b)) || IsRotationCurve(a) && IsRotationCurve(b)); }
private void DoIconAndName(Rect rect, AnimationWindowHierarchyNode node, bool selected, bool focused, float indent) { EditorGUIUtility.SetIconSize(new Vector2(13, 13)); // If not set we see icons scaling down if text is being cropped // TODO: All this is horrible. SHAME FIX! if (Event.current.type == EventType.Repaint) { if (selected) { selectionStyle.Draw(rect, false, false, true, focused); } // Leave some space for the value field that comes after. if (node is AnimationWindowHierarchyPropertyNode) { rect.width -= k_ValueFieldOffsetFromRightSide + 2; } bool isLeftOverCurve = AnimationWindowUtility.IsNodeLeftOverCurve(node); bool isAmbiguous = AnimationWindowUtility.IsNodeAmbiguous(node); bool isPhantom = AnimationWindowUtility.IsNodePhantom(node); string warningText = ""; string tooltipText = ""; if (isPhantom) { warningText = " (Default Value)"; tooltipText = "Transform position, rotation and scale can't be partially animated. This value will be animated to the default value"; } if (isLeftOverCurve) { warningText = " (Missing!)"; tooltipText = "The GameObject or Component is missing (" + node.path + ")"; } if (isAmbiguous) { warningText = " (Duplicate GameObject name!)"; tooltipText = "Target for curve is ambiguous since there are multiple GameObjects with same name (" + node.path + ")"; } Color oldColor = lineStyle.normal.textColor; Color textColor = oldColor; if (node.depth == 0) { string nodePrefix = ""; if (node.curves.Length > 0) { AnimationWindowSelectionItem selectionBinding = node.curves[0].selectionBinding; string gameObjectName = GetGameObjectName(selectionBinding != null ? selectionBinding.rootGameObject : null, node.path); nodePrefix = string.IsNullOrEmpty(gameObjectName) ? "" : gameObjectName + " : "; } Styles.content = new GUIContent(nodePrefix + node.displayName + warningText, GetIconForItem(node), tooltipText); textColor = EditorGUIUtility.isProSkin ? Color.gray * 1.35f : Color.black; } else { Styles.content = new GUIContent(node.displayName + warningText, GetIconForItem(node), tooltipText); textColor = EditorGUIUtility.isProSkin ? Color.gray : m_LightSkinPropertyTextColor; var phantomColor = selected ? m_PhantomCurveColor * k_SelectedPhantomCurveColorMultiplier : m_PhantomCurveColor; textColor = isPhantom ? phantomColor : textColor; } textColor = isLeftOverCurve || isAmbiguous ? k_LeftoverCurveColor : textColor; SetStyleTextColor(lineStyle, textColor); rect.xMin += (int)(indent + foldoutStyleWidth + lineStyle.margin.left); GUI.Label(rect, Styles.content, lineStyle); SetStyleTextColor(lineStyle, oldColor); } if (IsRenaming(node.id) && Event.current.type != EventType.Layout) { GetRenameOverlay().editFieldRect = new Rect(rect.x + k_IndentWidth, rect.y, rect.width - k_IndentWidth - 1, rect.height); } }
// identifier to generate an id thats the same for all curves in the same group public static string GetGroupID(this EditorCurveBinding binding) { return(binding.type + AnimationWindowUtility.GetPropertyGroupName(binding.propertyName)); }
private void DoValueField(Rect rect, AnimationWindowHierarchyNode node, int row) { bool curvesChanged = false; if (node is AnimationWindowHierarchyPropertyNode) { AnimationWindowCurve[] curves = node.curves; if (curves == null || curves.Length == 0) { return; } // We do valuefields for dopelines that only have single curve AnimationWindowCurve curve = curves[0]; object objectValue = CurveBindingUtility.GetCurrentValue(state, curve); if (objectValue is float) { float value = (float)objectValue; Rect valueFieldDragRect = new Rect(rect.xMax - k_ValueFieldOffsetFromRightSide - k_ValueFieldDragWidth, rect.y, k_ValueFieldDragWidth, rect.height); Rect valueFieldRect = new Rect(rect.xMax - k_ValueFieldOffsetFromRightSide, rect.y, k_ValueFieldWidth, rect.height); if (Event.current.type == EventType.MouseMove && valueFieldRect.Contains(Event.current.mousePosition)) { s_WasInsideValueRectFrame = Time.frameCount; } EditorGUI.BeginChangeCheck(); if (curve.valueType == typeof(bool)) { value = GUI.Toggle(valueFieldRect, m_HierarchyItemValueControlIDs[row], value != 0, GUIContent.none, EditorStyles.toggle) ? 1 : 0; } else { int id = m_HierarchyItemValueControlIDs[row]; bool enterInTextField = (EditorGUIUtility.keyboardControl == id && EditorGUIUtility.editingTextField && Event.current.type == EventType.KeyDown && (Event.current.character == '\n' || (int)Event.current.character == 3)); // Force back keyboard focus to float field editor when editing it. // TreeView forces keyboard focus on itself at mouse down and we lose focus here. if (EditorGUI.s_RecycledEditor.controlID == id && Event.current.type == EventType.MouseDown && valueFieldRect.Contains(Event.current.mousePosition)) { GUIUtility.keyboardControl = id; } value = EditorGUI.DoFloatField(EditorGUI.s_RecycledEditor, valueFieldRect, valueFieldDragRect, id, value, "g5", m_AnimationSelectionTextField, true); if (enterInTextField) { GUI.changed = true; Event.current.Use(); } } if (float.IsInfinity(value) || float.IsNaN(value)) { value = 0; } if (EditorGUI.EndChangeCheck()) { string undoLabel = "Edit Key"; AnimationKeyTime newAnimationKeyTime = AnimationKeyTime.Time(state.currentTime, curve.clip.frameRate); AnimationWindowKeyframe existingKeyframe = null; foreach (AnimationWindowKeyframe keyframe in curve.m_Keyframes) { if (Mathf.Approximately(keyframe.time, state.currentTime)) { existingKeyframe = keyframe; } } if (existingKeyframe == null) { AnimationWindowUtility.AddKeyframeToCurve(curve, value, curve.valueType, newAnimationKeyTime); } else { existingKeyframe.value = value; } state.SaveCurve(curve.clip, curve, undoLabel); curvesChanged = true; } } } if (curvesChanged) { state.ResampleAnimation(); } }
private void RenderClipOverlay(Rect rect) { Vector2 timeRange = this.m_State.timeRange; AnimationWindowUtility.DrawRangeOfClip(rect, this.m_State.TimeToPixel(timeRange.x) + rect.xMin, this.m_State.TimeToPixel(timeRange.y) + rect.xMin); }
private GenericMenu GenerateMenu(List <AnimationWindowHierarchyNode> interactedNodes, bool enabled) { List <AnimationWindowCurve> curves = GetCurvesAffectedByNodes(interactedNodes, false); // Linked curves are like regular affected curves but always include transform siblings List <AnimationWindowCurve> linkedCurves = GetCurvesAffectedByNodes(interactedNodes, true); bool forceGroupRemove = curves.Count == 1 ? AnimationWindowUtility.ForceGrouping(curves[0].binding) : false; GenericMenu menu = new GenericMenu(); // Remove curves GUIContent removePropertyContent = new GUIContent(curves.Count > 1 || forceGroupRemove ? "Remove Properties" : "Remove Property"); if (!enabled) { menu.AddDisabledItem(removePropertyContent); } else { menu.AddItem(removePropertyContent, false, RemoveCurvesFromSelectedNodes); } // Change rotation interpolation bool showInterpolation = true; EditorCurveBinding[] curveBindings = new EditorCurveBinding[linkedCurves.Count]; for (int i = 0; i < linkedCurves.Count; i++) { curveBindings[i] = linkedCurves[i].binding; } RotationCurveInterpolation.Mode rotationInterpolation = GetRotationInterpolationMode(curveBindings); if (rotationInterpolation == RotationCurveInterpolation.Mode.Undefined) { showInterpolation = false; } else { foreach (var node in interactedNodes) { if (!(node is AnimationWindowHierarchyPropertyGroupNode)) { showInterpolation = false; } } } if (showInterpolation) { string legacyWarning = state.activeAnimationClip.legacy ? " (Not fully supported in Legacy)" : ""; GenericMenu.MenuFunction2 nullMenuFunction2 = null; menu.AddItem(EditorGUIUtility.TrTextContent("Interpolation/Euler Angles" + legacyWarning), rotationInterpolation == RotationCurveInterpolation.Mode.RawEuler, enabled ? ChangeRotationInterpolation : nullMenuFunction2, RotationCurveInterpolation.Mode.RawEuler); menu.AddItem(EditorGUIUtility.TrTextContent("Interpolation/Euler Angles (Quaternion)"), rotationInterpolation == RotationCurveInterpolation.Mode.Baked, enabled ? ChangeRotationInterpolation : nullMenuFunction2, RotationCurveInterpolation.Mode.Baked); menu.AddItem(EditorGUIUtility.TrTextContent("Interpolation/Quaternion"), rotationInterpolation == RotationCurveInterpolation.Mode.NonBaked, enabled ? ChangeRotationInterpolation : nullMenuFunction2, RotationCurveInterpolation.Mode.NonBaked); } // Menu items that are only applicaple when in animation mode: if (state.previewing) { menu.AddSeparator(""); bool allHaveKeys = true; bool noneHaveKeys = true; foreach (AnimationWindowCurve curve in curves) { bool curveHasKey = curve.HasKeyframe(state.time); if (!curveHasKey) { allHaveKeys = false; } else { noneHaveKeys = false; } } string str; str = "Add Key"; if (allHaveKeys || !enabled) { menu.AddDisabledItem(new GUIContent(str)); } else { menu.AddItem(new GUIContent(str), false, AddKeysAtCurrentTime, curves); } str = "Delete Key"; if (noneHaveKeys || !enabled) { menu.AddDisabledItem(new GUIContent(str)); } else { menu.AddItem(new GUIContent(str), false, DeleteKeysAtCurrentTime, curves); } } return(menu); }
private void MoveToNextKeyframe() { this.m_State.currentTime = AnimationWindowUtility.GetNextKeyframeTime((!this.m_State.showCurveEditor ? this.m_State.allCurves : this.m_State.activeCurves).ToArray(), this.m_State.FrameToTime((float)this.m_State.frame), this.m_State.frameRate); this.m_State.frame = this.m_State.TimeToFrameFloor(this.m_State.currentTime); }
public override void OnInspectorGUI() { bool flag = base.targets.Length > 1; Animator animator = base.target as Animator; base.serializedObject.UpdateIfDirtyOrScript(); this.UpdateShowOptions(); EditorGUI.BeginChangeCheck(); RuntimeAnimatorController runtimeAnimatorController = EditorGUILayout.ObjectField("Controller", animator.runtimeAnimatorController, typeof(RuntimeAnimatorController), false, new GUILayoutOption[0]) as RuntimeAnimatorController; if (EditorGUI.EndChangeCheck()) { UnityEngine.Object[] targets = base.targets; for (int i = 0; i < targets.Length; i++) { Animator animator2 = (Animator)targets[i]; Undo.RecordObject(animator2, "Changed AnimatorController"); animator2.runtimeAnimatorController = runtimeAnimatorController; } AnimationWindowUtility.ControllerChanged(); } EditorGUILayout.PropertyField(this.m_Avatar, new GUILayoutOption[0]); if (animator.supportsOnAnimatorMove && !flag) { EditorGUILayout.LabelField("Apply Root Motion", "Handled by Script", new GUILayoutOption[0]); } else { EditorGUILayout.PropertyField(this.m_ApplyRootMotion, AnimatorInspector.styles.applyRootMotion, new GUILayoutOption[0]); if (Event.current.type == EventType.Layout) { this.m_IsRootPositionOrRotationControlledByCurves = animator.isRootPositionOrRotationControlledByCurves; } if (!this.m_ApplyRootMotion.boolValue && this.m_IsRootPositionOrRotationControlledByCurves) { EditorGUILayout.HelpBox("Root position or rotation are controlled by curves", MessageType.Info, true); } } EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(this.m_UpdateMode, AnimatorInspector.styles.updateMode, new GUILayoutOption[0]); bool flag2 = EditorGUI.EndChangeCheck(); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(this.m_CullingMode, AnimatorInspector.styles.cullingMode, new GUILayoutOption[0]); bool flag3 = EditorGUI.EndChangeCheck(); if (!flag) { EditorGUILayout.HelpBox(animator.GetStats(), MessageType.Info, true); } if (EditorGUILayout.BeginFadeGroup(this.m_ShowWarningMessage.faded)) { EditorGUILayout.HelpBox(this.WarningMessage, MessageType.Warning, true); } EditorGUILayout.EndFadeGroup(); base.serializedObject.ApplyModifiedProperties(); UnityEngine.Object[] targets2 = base.targets; for (int j = 0; j < targets2.Length; j++) { Animator animator3 = (Animator)targets2[j]; if (flag3) { animator3.OnCullingModeChanged(); } if (flag2) { animator3.OnUpdateModeChanged(); } } }