Search Unity

Create Keyframe for _MainTex_ST via code.

Discussion in 'Shaders' started by ian_unity431, Jan 8, 2019.

  1. ian_unity431

    ian_unity431

    Joined:
    Oct 12, 2018
    Posts:
    10
    Hi, does anyone know how I might go about programming a keyframe animation clip for _MainTex_ST with incoming data of tiling, offset, and time?
    I'm trying this out, but can't seem to get around the 'Object' limitation.

    AnimationClip clip = new AnimationClip();

    EditorCurveBinding binding = new EditorCurveBinding();
    binding.type = typeof(MeshRenderer);
    binding.path = "";
    binding.propertyName = textureManager.materialGroups[0].texturePropertyName + "_ST";

    ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[Data.Length];
    for (int i = 0; i < (Data.Length); i++)
    {
    Vector2 value = Data.textureOffset;// Stores a Vector2 of the material offset I want to save in an animation.

    keyFrames = new ObjectReferenceKeyframe();
    keyFrames.time = Data.time;
    keyFrames.value = value; // a Vector2 is obviously not a UnityEngine.Object.
    }
    AnimationUtility.SetObjectReferenceCurve(clip, binding, keyFrames);


    Any help would be much appreciated! @Aras
     
  2. ian_unity431

    ian_unity431

    Joined:
    Oct 12, 2018
    Posts:
    10
    I also tried this with no success.

    AnimationClip clip = new AnimationClip();
    EditorCurveBinding binding = new EditorCurveBinding();
    binding.type = typeof(MeshRenderer);
    binding.path = "";
    binding.propertyName = "_MainTex_ST";

    Keyframe[] keyFrames = new Keyframe[Data.Length];
    for (int i = 0; i < (Data.Length); i++)
    {
    Vector4 value = Data.textureOffset;

    keyFrames = new Keyframe();
    keyFrames.time = Data.time;
    keyFrames.value = value;
    }

    AnimationCurve curve = new AnimationCurve(keyFrames);
    clip.SetCurve(binding.path, binding.type, binding.propertyName, curve);
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    https://docs.unity3d.com/ScriptReference/AnimationClip.SetCurve.html

    clip.SetCurve("", typeof(MeshRenderer), "material._MainTex_ST.x", curveX);
    clip.SetCurve("", typeof(MeshRenderer), "material._MainTex_ST.y", curveY);
    clip.SetCurve("", typeof(MeshRenderer), "material._MainTex_ST.z", curveZ);
    clip.SetCurve("", typeof(MeshRenderer), "material._MainTex_ST.w", curveW);
     
  4. ian_unity431

    ian_unity431

    Joined:
    Oct 12, 2018
    Posts:
    10
    Thanks bgolus, that's exactly what I was looking for! For anyone else looking for this in the future, here's my final solution.

    Void Main()
    {
    AnimationClip clip = new AnimationClip();
    Keyframe[] keyFramesX = new Keyframe[Data.Length];
    Keyframe[] keyFramesY = new Keyframe[Data.Length];
    Keyframe[] keyFramesZ = new Keyframe[Data.Length];
    Keyframe[] keyFramesW = new Keyframe[Data.Length];
    for (int i = 0; i < (Data.Length); i++)
    {
    keyFramesX = new Keyframe();
    keyFramesX.time = Data.time;
    keyFramesX.value = Data.x;

    keyFramesY = new Keyframe();
    keyFramesY.time = Data.time;
    keyFramesY.value = Data.y;

    keyFramesZ = new Keyframe();
    keyFramesZ.time = Data.time;
    keyFramesZ.value = Data.z;

    keyFramesW = new Keyframe();
    keyFramesW.time = Data.time;
    keyFramesW.value = Data.w;
    }

    ApplyKeyFramesToTexture(clip, texturePropertyName + "_ST.x", keyFramesX);
    ApplyKeyFramesToTexture(clip, texturePropertyName + "_ST.y", keyFramesY);
    ApplyKeyFramesToTexture(clip, texturePropertyName + "_ST.z", keyFramesZ);
    ApplyKeyFramesToTexture(clip, texturePropertyName + "_ST.w", keyFramesW);
    }


    private void ApplyKeyFramesToTexture(AnimationClip clip, string texturePropertyName, Keyframe[] keyFrames)
    {
    EditorCurveBinding binding = new EditorCurveBinding();
    binding.type = typeof(MeshRenderer);
    binding.path = "";
    binding.propertyName = "material." + texturePropertyName;

    AnimationCurve curve = new AnimationCurve(keyFrames);

    // Sets the curves to constant so that the frames don't lerp between each other.
    for (int i = 0; i < (keyFrames.Length); i++)
    {
    AnimationUtility.SetKeyLeftTangentMode(curve, i, AnimationUtility.TangentMode.Constant);
    AnimationUtility.SetKeyRightTangentMode(curve, i, AnimationUtility.TangentMode.Constant);
    }

    clip.SetCurve(binding.path, binding.type, binding.propertyName, curve);
    }