Пример #1
0
        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);
        }
Пример #2
0
        // 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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        // 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;
        }
Пример #5
0
        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;
        }
Пример #6
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        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;
                    }
                }
            }
        }
Пример #10
0
        // 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);
        }
Пример #12
0
        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));
        }
Пример #14
0
        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;
        }
Пример #15
0
        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);
        }
Пример #16
0
        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;
            }
        }
Пример #17
0
        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);
            }
        }
Пример #18
0
 public static EditorCurveBinding GetCurveBinding(this ICurvesOwner curvesOwner, string parameterName)
 {
     return(AnimatedParameterUtility.GetCurveBinding(curvesOwner.asset, parameterName));
 }
Пример #19
0
        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]);
                        }
                    }
                }
            }
        }
Пример #20
0
 public static IEnumerable <SerializedProperty> GetAllAnimatableParameters(this ICurvesOwner curvesOwner)
 {
     return(AnimatedParameterUtility.GetAllAnimatableParameters(curvesOwner.asset));
 }
Пример #21
0
 public static bool HasAnyAnimatableParameters(this ICurvesOwner curvesOwner)
 {
     return(AnimatedParameterUtility.HasAnyAnimatableParameters(curvesOwner.asset));
 }
Пример #22
0
 public static bool IsParameterAnimated(this ICurvesOwner curvesOwner, string parameterName)
 {
     return(AnimatedParameterUtility.IsParameterAnimated(curvesOwner.asset, curvesOwner.curves, parameterName));
 }
Пример #23
0
 public static AnimationCurve GetAnimatedParameter(this ICurvesOwner curvesOwner, string bindingName)
 {
     return(AnimatedParameterUtility.GetAnimatedParameter(curvesOwner.asset, curvesOwner.curves, bindingName));
 }