Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on Thursday, June 8, for a Q&A with Unity's Content Pipeline group here on the forum, and on the Unity Discord, and discuss topics around Content Build, Import Workflows, Asset Database, and Addressables!
    Dismiss Notice

Question How to find the driver property names? to save Material on Renderer while Timeline Preview

Discussion in 'Timeline' started by Sangemdoko, Nov 28, 2022.

  1. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    209
    So when I want to get a property on my own scripts that's fine because I wrote them and I know what they are.
    But I can't figure out how to do it on Unity compoenent or if it is even possible in my particular case.

    I have a custom track that changes the material of an object. But when I exit prefab mode while previewing my material gets set to none.
    So I want to save it with a driver.

    Code (CSharp):
    1. public override void GatherProperties(PlayableDirector director, IPropertyCollector driver)
    2. {
    3.     if (director == null)
    4.         return;
    5.     var materialControl = GetBinding(director);
    6.     if (materialControl == null) {
    7.         return;
    8.     }
    9.     var renderer = materialControl.Renderer;
    10.     if (renderer != null) {
    11.         var fields = typeof(Renderer).GetFields();
    12.         Debug.Log(fields.Length);
    13.        
    14.         for (int i = 0; i < fields.Length; i++) {
    15.             Debug.LogWarning(fields[i].Name);
    16.         }
    17.        
    18.         Debug.Log("Not Null! "+renderer);
    19.         driver.AddFromName(renderer,"m_Materials");
    20.         driver.AddFromName(renderer,"_Materials");
    21.         driver.AddFromName(renderer,"Materials");
    22.         driver.AddFromName(renderer,"Materials");
    23.         driver.AddFromName(renderer,"Materials");
    24.         driver.AddFromName(renderer,"Materials");
    25.         driver.AddFromName<Renderer>(renderer.gameObject, "Materials");
    26.         driver.AddFromName<Renderer>(renderer.gameObject, "materials");
    27.         driver.AddFromName<Renderer>(renderer.gameObject, "material");
    28.         driver.AddFromName<Renderer>(renderer.gameObject, "sharedMaterials");
    29.         driver.AddFromName<Renderer>(renderer.gameObject, "sharedMaterial");
    30.     }
    31.        
    32. }
    All of these "AddFromName" functions return an error saying the property does not exist.

    The typeof(Renderer).GetFields() returns an empty array.

    So I'm not really sure where to look next.
    Has someone tried to change materials with a timeline and succeeded nr keeping the material references after exiting preview halfway through?
     
  2. akent99

    akent99

    Joined:
    Jan 14, 2018
    Posts:
    588
    Would you be able to describe in a bit more detail what you are trying to do? You mention "exit prefab mode" - I assume you mean "preview mode"? When you say the material is lost, I assume you mean the object property is reset? Timelines tend to reset values back to their initial values, but clips have properties that give you some control. I have no experience with AddFramName(), but I am wondering if there is a different solution to the problem - (but some more details/clarity on the problem would help).
     
  3. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    209
    Ok sorry, I'll try to explain step by step.

    1. I have a custom Track and Clip
    2. The Playable Director is set as a child of a character prefab and is used for a Spawn/Despawn effect
    3. The custom clip replaces a material in the array of materials on the Character and animates some values
    4. Once the clip ends it resets the material back to its original value
    5. The issue is that sometimes the value is not reset properly when the prefab mode is exited while previwing in the middle of the custom material clip
    6. So my idea was using drivers such that the material would not be saved/reset by me but by Unity since I assume they can do it more properly.
    Materials can be a bit tricky because Unity sometimes duplicates materials automatically to avoid editing the material asset, so I might be doing something wrong there.

    My work around for now is to set the material of the character in OnValidate from another script, this way even if the material is set to none by my custom clip, it gets reassigned correctly before play... but it's not very clean and can be a bit confusing.
     
  4. akent99

    akent99

    Joined:
    Jan 14, 2018
    Posts:
    588
    Ah, I think I understand. I have had similar problems jumping between Timelines in preview mode. Things can be left in the state they were when you jumped to the new Timeline (it did not reset like it does when it reaches the end of the Timeline). I don't have a solution for that, but maybe someone else does! (And I have no experience with "drivers" sorry.)

    In my case I use Sequences and I make a local copy of everything I animate for that Sequence to avoid messing things up globally. You probably cannot do the same.
     
  5. apkdev

    apkdev

    Joined:
    Dec 12, 2015
    Posts:
    226
    Unity is a frustrating black box sometimes.

    Anyway, I just figured it out - to address elements in the materials array use this syntax:
    Code (CSharp):
    1. collector.AddFromName(renderer, "m_Materials.Array.data[0]");
    You might need to iterate over the array and add each element separately if you're interested in more than one.

    This probably works for registering any serialized array - I think that's the path syntax Unity uses for array serialization.