Expose shader properties to animator

Hi,
I have a bunch of custom shaders that I want to be able to control using an animator controller and animation clips. Is this possible?

I’ve tried adding an animation controller/clip to the object with the shader/material applied to it, but when I go to the animation dope sheet and try to add a shader property to the animation it doesn’t seem to be available.

For example I have a shader with a blur effect that is controlled by a slider called “magnitude”. When I go to the animation window, I can see the “standard” properties to add, like colour, for example. But my own properties are missing.

Is there something I need to add to the properties to make them exposed to the animator?
Thanks

1 Like

You may create custom script for that with properties you want.

public float myCustomFloat {
   get { return GetComponent<MeshRenderer>().sharedMaterial.getFloat("myCustomFloat"); }
   set { GetComponent<MeshRenderer>().sharedMaterial.setFloat("myCustomFloat", value); }
}

What version of Unity are you using? What kind of component are you looking to animate? How are you creating the animation?

In 2018.2 if I select a game object with a mesh renderer component, go to the Animation tab and create a new clip, I can see all of the properties of the material listed in the Properties block of the shader. Just for an example, here’s a custom circular bar shader with a lot of non-standard property names. They all show up.
4534771--420202--upload_2019-5-13_8-32-25.png
This works in 2019, and worked in 2017 and all versions of Unity 5.

2 Likes

What about shaders assigned to UI elements? They don’t show in animator, apparently.

I’m running into the same issue as @xVictor .

For a UI element the material properties are not showing up in the animator. Even if I right click on a property I don’t get the “add keyframe” option.

As a workaround I’ll trigger an animation event and animate from there, but that breaks the preview, and complicates the animation process.

Yes it doesn’t work for UI :s

Anyone has a solution?

This is becouse CanvasRenderer does not expose its material directly. You need to retrive it and modify manually using CanvasRenderer-GetMaterial - Unity Scripting API. Use my approach above.

2 Likes

this does not work for me, here is why: https://answers.unity.com/questions/144431/how-can-i-change-properties-by-set-function-in-ani.html

For animations use this code

[SerializeField] private float _myCustomFloat;

private float __myCustomFloatActualValue;

private void Awake() {
    __myCustomFloatActualValue = GetComponent<MeshRenderer>().sharedMaterial.getFloat("myCustomFloat");
}

private void LateUpdate() {
    if(_myCustomFloat != __myCustomFloatActualValue) {
        __myCustomFloatActualValue = _myCustomFloat;
        GetComponent<MeshRenderer>().sharedMaterial.setFloat("myCustomFloat", __myCustomFloatActualValue)  
    }
}

Do not forget to add [ExecuteAlway] to make your script work in edit mode too.

2 Likes

Has anything changed ?
Is it still that painful to animate Material properties for UI GameObjects ?

Is there a way to animate the material properties from a custom script? Example, when I have this:

public class Blerp : MonoBehaviour
{
    public Material materialField; // Nope
    [field: SerializeField] public Material materialProperty { get; set; } // Nada
}

In my animation window I see Blerp.materialField, and Blerp.materialProperty, but not say Blerp.materialField_Base Color.

I can see it has to do with MaterialPropertyBlock, as material and sharedMaterial on a renderer never change, but the GetPropertyBlock does, but I don’t know how to use that to my advantage.

Same exact issue. Animating UI materials cleanly requires:

Using IMaterialModifier, create a script to inject a temporary material to your Graphic

Create a public property for the material property name you want to change, and one for the value.

Apply the properties on callback, and then:

OnValidate => GetComponent().SetMaterialDirty();

And then just spend some time seething about the whole process

You might want to have an array of such properties, but you can’t animate arrays.

You might want multiple override components, but you can’t animate two components of the same type.

The only solution is to have a bunch of gameobject children, each with this script.

I created a basic package to animate UI shader properties using the solution mentioned above GitHub - lgarczyn/AnimateUIMaterials: Unity asset to allow animating UI materials

5 Likes

Thank you so much!! I’m an unreal tech artist and going to unity has been absolutely painful! Your asset has bridged my pain!

1 Like