static bool InternalAddParameter([NotNull] ICurvesOwner curvesOwner, string parameterName, ref EditorCurveBinding binding, out SerializedProperty property) { property = null; if (curvesOwner.IsParameterAnimated(parameterName)) { return(false); } var serializedObject = AnimatedParameterUtility.GetSerializedPlayableAsset(curvesOwner.asset); if (serializedObject == null) { return(false); } property = serializedObject.FindProperty(parameterName); if (property == null || !AnimatedParameterUtility.IsTypeAnimatable(property.propertyType)) { return(false); } if (curvesOwner.curves == null) { curvesOwner.CreateCurves(curvesOwner.GetUniqueRecordedClipName()); } binding = curvesOwner.GetCurveBinding(parameterName); return(true); }
// Checks if a key already exists for this property static bool HasBinding(UnityEngine.Object target, PropertyModification modification, AnimationClip clip, out EditorCurveBinding binding) { var component = target as Component; var playableAsset = target as IPlayableAsset; if (component != null) { var type = AnimationUtility.PropertyModificationToEditorCurveBinding(modification, component.gameObject, out binding); binding = RotationCurveInterpolation.RemapAnimationBindingForRotationCurves(binding, clip); return(type != null); } if (playableAsset != null) { binding = EditorCurveBinding.FloatCurve(string.Empty, target.GetType(), AnimatedParameterUtility.GetAnimatedParameterBindingName(target, modification.propertyPath)); } else { binding = new EditorCurveBinding(); return(false); } return(true); }
public void UpdateCurves(IEnumerable <CurveWrapper> updatedCurves) { if (m_ProxyIsRebuilding > 0) { return; } Undo.RegisterCompleteObjectUndo(m_OriginalOwner.asset, L10n.Tr("Edit Clip Curve")); if (m_OriginalOwner.curves != null) { Undo.RegisterCompleteObjectUndo(m_OriginalOwner.curves, L10n.Tr("Edit Clip Curve")); } var requireRebuild = false; foreach (var curve in updatedCurves) { requireRebuild |= curve.curve.length == 0; UpdateCurve(curve.binding, curve.curve); } if (requireRebuild) { m_OriginalOwner.SanitizeCurvesData(); } AnimatedParameterUtility.UpdateSerializedPlayableAsset(m_OriginalOwner.asset); }
// updates the just the proxied values. This can be called when the asset changes, so the proxy values are properly updated public void UpdateProxyCurves() { if (!m_IsAnimatable || m_ProxyCurves == null || m_ProxyCurves.empty) { return; } AnimatedParameterUtility.UpdateSerializedPlayableAsset(m_OriginalOwner.asset); var parameters = m_OriginalOwner.GetAllAnimatableParameters().ToArray(); using (new RebuildGuard(this)) { if (m_OriginalOwner.hasCurves) { var bindingInfo = AnimationClipCurveCache.Instance.GetCurveInfo(m_OriginalOwner.curves); foreach (var param in parameters) { var binding = AnimatedParameterUtility.GetCurveBinding(m_OriginalOwner.asset, param.propertyPath); if (!bindingInfo.bindings.Contains(binding, AnimationPreviewUtilities.EditorCurveBindingComparer.Instance)) { SetProxyCurve(param, AnimatedParameterUtility.GetCurveBinding(m_OriginalOwner.asset, param.propertyPath)); } } } else { foreach (var param in parameters) { SetProxyCurve(param, AnimatedParameterUtility.GetCurveBinding(m_OriginalOwner.asset, param.propertyPath)); } } } AnimationClipCurveCache.Instance.GetCurveInfo(m_ProxyCurves).dirty = true; }
void CreateProxyCurve(SerializedProperty prop, AnimationClip clip, UnityObject owner, string propertyName) { var binding = AnimatedParameterUtility.GetCurveBinding(owner, propertyName); var originalCurve = m_OriginalOwner.hasCurves ? AnimationUtility.GetEditorCurve(m_OriginalOwner.curves, binding) : null; if (originalCurve != null) { AnimationUtility.SetEditorCurve(clip, binding, originalCurve); } else { var curve = new AnimationCurve(); CurveEditUtility.AddKeyFrameToCurve( curve, 0.0f, clip.frameRate, CurveEditUtility.GetKeyValue(prop), prop.propertyType == SerializedPropertyType.Boolean); AnimationUtility.SetEditorCurve(clip, binding, curve); } m_PropertiesMap[binding] = prop; }
public void AddFromComponent(GameObject obj, Component component) { if (Application.isPlaying) { return; } if (obj == null || component == null) { return; } var serializedObject = new SerializedObject(component); SerializedProperty property = serializedObject.GetIterator(); while (property.NextVisible(true)) { if (property.hasVisibleChildren || !AnimatedParameterUtility.IsTypeAnimatable(property.propertyType)) { continue; } AddPropertyModification(component, property.propertyPath); } }
public bool IsAnimatable(PropertyModification[] modifications) { // search playable assets for (int i = 0; i < modifications.Length; i++) { var iAsset = modifications[i].target as IPlayableAsset; if (iAsset != null) { var curvesOwner = AnimatedParameterUtility.ToCurvesOwner(iAsset, state.editSequence.asset); if (curvesOwner != null && curvesOwner.HasAnyAnimatableParameters() && curvesOwner.IsParameterAnimatable(modifications[i].propertyPath)) { return(true); } } } // search recordable game objects foreach (var gameObject in TimelineRecording.GetRecordableGameObjects(state)) { for (int i = 0; i < modifications.Length; ++i) { var modification = modifications[i]; if (AnimationWindowUtility.PropertyIsAnimatable(modification.target, modification.propertyPath, gameObject)) { return(true); } } } return(false); }
public static bool AddAnimatedParameterValueAt(this ICurvesOwner curvesOwner, string parameterName, float value, float time) { if (!curvesOwner.IsParameterAnimatable(parameterName)) { return(false); } if (curvesOwner.curves == null) { curvesOwner.CreateCurves(curvesOwner.GetUniqueRecordedClipName()); } var binding = curvesOwner.GetCurveBinding(parameterName); var curve = AnimationUtility.GetEditorCurve(curvesOwner.curves, binding) ?? new AnimationCurve(); var serializedObject = AnimatedParameterUtility.GetSerializedPlayableAsset(curvesOwner.asset); var property = serializedObject.FindProperty(parameterName); bool isStepped = property.propertyType == SerializedPropertyType.Boolean || property.propertyType == SerializedPropertyType.Integer || property.propertyType == SerializedPropertyType.Enum; TimelineUndo.PushUndo(curvesOwner.curves, "Set Key"); CurveEditUtility.AddKeyFrameToCurve(curve, time, curvesOwner.curves.frameRate, value, isStepped); AnimationUtility.SetEditorCurve(curvesOwner.curves, binding, curve); return(true); }
void AddSerializedPlayableModifications(IPlayableAsset asset, AnimationClip clip) { var obj = asset as Object; if (obj == null) { return; } var driver = WindowState.previewDriver; if (driver == null || !AnimationMode.InAnimationMode(driver)) { return; } var serializedObj = new SerializedObject(obj); var bindings = AnimationClipCurveCache.Instance.GetCurveInfo(clip).bindings; var fields = AnimatedParameterUtility.GetScriptPlayableFields(asset); // go through each binding and offset using the field name // so the modification system can find the particle object using the asset as a root foreach (var b in bindings) { foreach (var f in fields) { var propertyPath = f.Name + "." + b.propertyName; if (serializedObj.FindProperty(propertyPath) != null) { DrivenPropertyManager.RegisterProperty(driver, obj, propertyPath); break; } } } }
// Helper that finds the animation clip we are recording and the relative time to that clip static bool GetClipAndRelativeTime(UnityEngine.Object target, WindowState state, out AnimationClip outClip, out double keyTime, out bool keyInRange) { const float floatToDoubleError = 0.00001f; outClip = null; keyTime = 0; keyInRange = false; double startTime = 0; double timeScale = 1; AnimationClip clip = null; IPlayableAsset playableAsset = target as IPlayableAsset; Component component = target as Component; // Handle recordable playable assets if (playableAsset != null) { var curvesOwner = AnimatedParameterUtility.ToCurvesOwner(playableAsset, state.editSequence.asset); if (curvesOwner != null) { if (curvesOwner.curves == null) { curvesOwner.CreateCurves(curvesOwner.GetUniqueRecordedClipName()); } clip = curvesOwner.curves; var timelineClip = curvesOwner as TimelineClip; if (timelineClip != null) { startTime = timelineClip.start; timeScale = timelineClip.timeScale; } } } // Handle recording components, including infinite clip else if (component != null) { var asset = GetTrackForGameObject(component.gameObject, state); if (asset != null) { clip = GetRecordingClip(asset, state, out startTime, out timeScale); } } if (clip == null) { return(false); } keyTime = (state.editSequence.time - startTime) * timeScale; outClip = clip; keyInRange = keyTime >= 0 && keyTime <= (clip.length * timeScale + floatToDoubleError); return(true); }
static bool ProcessPlayableAssetModification(UndoPropertyModification mod, WindowState state) { var target = GetTarget(mod) as IPlayableAsset; if (target == null) return false; var curvesOwner = AnimatedParameterUtility.ToCurvesOwner(target, state.editSequence.asset); if (curvesOwner == null || !curvesOwner.HasAnyAnimatableParameters()) return false; return ProcessPlayableAssetRecording(mod, state, curvesOwner); }
public static bool CanRecord(SerializedProperty property, WindowState state) { if (IsPlayableAssetProperty(property)) { return(AnimatedParameterUtility.IsTypeAnimatable(property.propertyType)); } if (GetRecordingTrack(property, state) == null) { return(false); } s_TempPropertyModifications.Clear(); GatherModifications(property, s_TempPropertyModifications); return(s_TempPropertyModifications.Any()); }
static bool ProcessPlayableAssetModification(UndoPropertyModification mod, WindowState state) { var target = GetTarget(mod) as IPlayableAsset; if (target == null) { return(false); } var curvesOwner = AnimatedParameterUtility.ToCurvesOwner(target, state.editSequence.asset); if (curvesOwner == null || !state.IsTrackRecordable(curvesOwner.targetTrack)) { return(false); } return(ProcessPlayableAssetRecording(mod, state, curvesOwner)); }
void CreateProxyCurve(SerializedProperty prop, AnimationClip clip, UnityObject owner, string propertyName) { var binding = AnimatedParameterUtility.GetCurveBinding(owner, propertyName); var originalCurve = m_OriginalOwner.hasCurves ? AnimationUtility.GetEditorCurve(m_OriginalOwner.curves, binding) : null; if (originalCurve != null) { AnimationUtility.SetEditorCurve(clip, binding, originalCurve); } else { SetProxyCurve(prop, binding); } m_PropertiesMap[binding] = prop; }
public void UpdateCurves(List <CurveWrapper> updatedCurves) { if (m_ProxyIsRebuilding > 0) { return; } Undo.RegisterCompleteObjectUndo(m_OriginalOwner.asset, "Edit Clip Curve"); if (m_OriginalOwner.curves != null) { Undo.RegisterCompleteObjectUndo(m_OriginalOwner.curves, "Edit Clip Curve"); } foreach (var curve in updatedCurves) { UpdateCurve(curve.binding, curve.curve); } AnimatedParameterUtility.UpdateSerializedPlayableAsset(m_OriginalOwner.asset); }
void RebuildProxyCurves() { if (!m_IsAnimatable) { return; } using (new RebuildGuard(this)) { if (m_ProxyCurves == null) { m_ProxyCurves = new AnimationClip { legacy = true, name = "Constant Curves", hideFlags = HideFlags.HideAndDontSave, frameRate = m_OriginalOwner.targetTrack.timelineAsset == null ? TimelineAsset.EditorSettings.kDefaultFps : m_OriginalOwner.targetTrack.timelineAsset.editorSettings.fps }; } else { m_ProxyCurves.ClearCurves(); } m_OriginalOwner.SanitizeCurvesData(); AnimatedParameterUtility.UpdateSerializedPlayableAsset(m_OriginalOwner.asset); var parameters = m_OriginalOwner.GetAllAnimatableParameters().ToArray(); foreach (var param in parameters) { CreateProxyCurve(param, m_ProxyCurves, m_OriginalOwner.asset, param.propertyPath); } AnimationClipCurveCache.Instance.GetCurveInfo(m_ProxyCurves).dirty = true; } }
void ApplyConstraints(EditorCurveBinding binding, AnimationCurve curve) { if (curve.length == 0) { return; } var curveUpdated = false; var property = m_PropertiesMap[binding]; if (property.propertyType == SerializedPropertyType.Boolean) { TimelineAnimationUtilities.ConstrainCurveToBooleanValues(curve); curveUpdated = true; } else { var range = AnimatedParameterUtility.GetAttributeForProperty <RangeAttribute>(property); if (range != null) { TimelineAnimationUtilities.ConstrainCurveToRange(curve, range.min, range.max); curveUpdated = true; } } if (!curveUpdated) { return; } using (new RebuildGuard(this)) { AnimationUtility.SetEditorCurve(m_ProxyCurves, binding, curve); } }
public static EditorCurveBinding GetCurveBinding(this ICurvesOwner curvesOwner, string parameterName) { return(AnimatedParameterUtility.GetCurveBinding(curvesOwner.asset, parameterName)); }
public void ApplyExternalChangesToProxy() { using (new RebuildGuard(this)) { if (m_OriginalOwner.curves == null) { return; } var curveInfo = AnimationClipCurveCache.Instance.GetCurveInfo(m_OriginalOwner.curves); for (int i = 0; i < curveInfo.bindings.Length; i++) { if (curveInfo.curves[i] != null && curveInfo.curves.Length != 0) { if (m_PropertiesMap.TryGetValue(curveInfo.bindings[i], out var prop) && AnimatedParameterUtility.IsParameterAnimatable(prop)) { AnimationUtility.SetEditorCurve(m_ProxyCurves, curveInfo.bindings[i], curveInfo.curves[i]); } } } } }
public static IEnumerable <SerializedProperty> GetAllAnimatableParameters(this ICurvesOwner curvesOwner) { return(AnimatedParameterUtility.GetAllAnimatableParameters(curvesOwner.asset)); }
public static bool HasAnyAnimatableParameters(this ICurvesOwner curvesOwner) { return(AnimatedParameterUtility.HasAnyAnimatableParameters(curvesOwner.asset)); }
public static bool IsParameterAnimated(this ICurvesOwner curvesOwner, string parameterName) { return(AnimatedParameterUtility.IsParameterAnimated(curvesOwner.asset, curvesOwner.curves, parameterName)); }
public static AnimationCurve GetAnimatedParameter(this ICurvesOwner curvesOwner, string bindingName) { return(AnimatedParameterUtility.GetAnimatedParameter(curvesOwner.asset, curvesOwner.curves, bindingName)); }