API for Animation panel previews and state restoration?

[Resolved] : See sample code below

Well I think everything is in the title.
Animating a material property nicely allows to animate the property only to the mesh it is animating without wondering how instantiation occurs at edit mode / runtime.

Now we’d want to animate a collection of meshes material, how would be the best way to do it so it behaves the same and handle back and forth preview correctly ?

What is happening behind the scene ?

Best

The question is motivated by the fact we have to do some hacking in order to be able to bulk animate materials at edit time. We have a [ExecuteAlways] script that :

  • takes a list of renderers,
  • instantiate them onEnable
  • animate them with in update()
  • restore them onDisable / OnBeforeSerialization / before enter playmode / Exit application

Uh if you are really using animations do have a look at Unity - Scripting API: AnimationMode
I use custom timeline clips to animate materials and use the GatherProperties callback of the track to reset them when exiting preview / animation mode.

1 Like

Man perfect link, I don’t know what I was looking for, I was not even sure there was an API for this and there actually is. I think I’m gonna be able to replace all my hacks by this. Looks like I will be able to add the transforms of objects modified by physic as well.

May I ask, would you be able to share your custom timeline clips/tracks ?

Looks like I’ll have to use AnimationMode.AddPropertyModification along EditorCurveBinding, I believe the property path has to be relative to the animator but not sure how to retrieve it yet from a Timeline Animation Track and a regular animation clip.

[Edit] : Resolved and code updated, indeed I understood things in reverse. PropertyModification is only here to “mark” the property with its initial value, you still have to set the value, it will be restored when animations stops.

private void SetMatsAndSave(Renderer r, Material[] sharedMats, Material[] newMats)
{
    var inAnimMode = false;
    #if UNITY_EDITOR
        inAnimMode = AnimationMode.InAnimationMode();
        IndusLogger.Debug("AdvancedCutoutRendererInstancer.SetMatsAndSave()",
            $"InAnimMode<{inAnimMode}>");

        if (!inAnimMode)
        {
            _manualAnimMode = true;
            AnimationMode.StartAnimationMode();
        }
      
        if (inAnimMode)
        {
            var serializedMesh = new SerializedObject(r);
          var matsRefProp = serializedMesh.FindProperty("m_Materials");
            var nbMat = matsRefProp.arraySize;

            for (var iMat = 0; iMat < nbMat; iMat++)
            {
                var matProp = matsRefProp.GetArrayElementAtIndex(iMat);

                /*Dummy path works ?*/
                var inPath = nameof(AdvancedCutoutRendererInstancer)+"/"+r.name;
                var materialsPPtrBinding = EditorCurveBinding.PPtrCurve(inPath , typeof(Renderer), matProp.name);

                var propModification = new PropertyModification
                {
                    target = r,
                    propertyPath = matProp.propertyPath,
                    objectReference = sharedMats[iMat]
                };
                AnimationMode.AddPropertyModification(materialsPPtrBinding, propModification, true);  
            }
          
          
        }
    #endif
    r.materials = newMats;
                }

[Original] :
I think I’m close, however what I see is actually the contrary of what I’d want, did I misunderstood the way PropertyModification should be set ?

Before script :


OnEnable (Correctly blue but the material is the same, it should be the clone)

OnDisable : Prefab value modified and set to the clone, should be restored to before script

Actually, I discovered that you can implement both ITimeControl and IPropertyPreview, initialize from the start function and then give whatever you want to to the IPropertyCollector and control these components from a control track. It handles state restoration perfectly without all the shenanigans ! Timeline is usually very hard to cop with but this combo is just a miracle.

9920247--1434726--upload_2024-7-2_22-43-2.png