Search Unity

Changing loop property on Audio PlayableAsset programmatically

Discussion in 'Timeline' started by Suduckgames, Jul 4, 2018.

  1. Suduckgames

    Suduckgames

    Joined:
    Nov 28, 2016
    Posts:
    218
    Hi, I have a timeline that I edit in function of the user choice.

    For AudioPlayableAsset I change the clip with this code



    Code (CSharp):
    1.  var timelineAsset = director.playableAsset as TimelineAsset;
    2.  
    3.  
    4.         foreach (var track in timelineAsset.GetOutputTracks())
    5.         {
    6.             AudioTrack audioTrack = track as AudioTrack;
    7.  
    8.             if (audioTrack == null)
    9.                 continue;
    10.             IEnumerable<TimelineClip> lista = audioTrack.GetClips();
    11.             foreach (TimelineClip timeClip in lista)
    12.             {
    13.                 AudioPlayableAsset ac = timeClip.asset as AudioPlayableAsset;            
    14.                 ac.clip = clip;
    15.             }
    16.  
    17.         }
    However on the editor there is another property called "Loop" that I am unable to achieve from code.
    Some audios can loop while others just should stay at Hold.

    Is there anyway to accomplish this?
     
  2. julienb

    julienb

    Unity Technologies

    Joined:
    Sep 9, 2016
    Posts:
    177
    There is no getter/setter for the loop field in AudioPlayableAsset, but there should be one, which is an oversight from our part. I'll open a bug to correct that.

    Meanwhile, you have two options. You can use SerializedObject to change the loop field:
    Code (CSharp):
    1. var audioAssetSo = new SerializedObject(ac);
    2. var loopProperty = audioAssetSo.FindProperty("m_Loop");
    3. loopProperty.boolValue = true;
    4. audioAssetSo.ApplyModifiedProperties();
    If you need your code to execute at runtime, you will have to change the loop field through reflection.
    Code (CSharp):
    1. var loopField = typeof(AudioPlayableAsset).GetField("m_Loop", BindingFlags.NonPublic | BindingFlags.Instance);
    2. loopField.SetValue(ac, false);
     
    Last edited: Jul 4, 2018
  3. Suduckgames

    Suduckgames

    Joined:
    Nov 28, 2016
    Posts:
    218
    Thanks for your answer,

    It works but a some times It doesn't (tested on editor),

    When it don't work, it shows in the console a warning regarding the delay near to 0 or something like that (Unable to reproduce currently, I will update if I get the same warning again)

    Also, reflection has some disavantages in other plataforms, It is ok to use it in unity?
     
  4. julienb

    julienb

    Unity Technologies

    Joined:
    Sep 9, 2016
    Posts:
    177
    Reflection is ok to use, although if you need to call this frequently, you'll probably want to cache the loopField variable or create a delegate to speed things up.

    Keep in mind that if you change loop or clip in AudioPlayableAsset, you'll need to rebuild the graph to apply your changes.
     
    Suduckgames likes this.