Shuffling music tracks

The following is a custom Action that will play music tracks at random. It can be amended to play only within a selected range by changing the Random.Range values.

For details on how to implement custom Actions, see the Manual's "Custom Actions" chapter.

ActionShuffleMusic.cs

```
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

#if UNITY\_EDITOR
using UnityEditor;
#endif

namespace AC
{

 [System.Serializable]
 public class ActionShuffleMusic : Action
 {

 public float fadeTime;
 public int fadeTimeParameterID = -1;

 public bool loop;
 public bool isQueued;

 public bool resumeFromStart = true;
 public bool resumeIfPlayedBefore = false;

 private Music music;
 private int trackID;
 public bool willWaitComplete;

 public int minRange = 0;
 public int maxRange = -1;

 public override ActionCategory Category { get { return ActionCategory.Sound; }}
 public override string Title { get { return "Shuffle music"; }}
 public override string Description { get { return "Plays or queues random music clips."; }}

 public override void AssignValues (List<ActionParameter> parameters)
 {
 fadeTime = AssignFloat (parameters, fadeTimeParameterID, fadeTime);
 music = KickStarter.stateHandler.GetMusicEngine ();

 int runtimeMin = Mathf.Max (minRange, 0);
 int runtimeMax = Mathf.Min (maxRange+1, KickStarter.settingsManager.musicStorages.Count);
 trackID = Random.Range (runtimeMin, runtimeMax);
 }

 public override float Run ()
 {
 if (music == null)
 {
 return 0f;
 }

 if (!isRunning)
 {
 isRunning = true;
 float waitTime = Perform (fadeTime);

 if (willWait && waitTime > 0f && !isQueued)
 {
 return (waitTime);
 }
 else if (!loop && willWaitComplete)
 {
 return defaultPauseTime;
 }
 }
 else
 {
 if (!loop && willWaitComplete && music.GetCurrentTrackID () == trackID && music.IsPlaying ())
 {
 return defaultPauseTime;
 }
 isRunning = false;
 }
 return 0f;
 }

 public override void Skip ()
 {
 Perform (0f);
 }

 private float Perform (float \_time)
 {
 if (music != null)
 {
 return music.Play (trackID, loop, isQueued, \_time, resumeIfPlayedBefore);
 }
 return 0f;
 }

 #if UNITY\_EDITOR

 public override void ShowGUI (List<ActionParameter> parameters)
 {
 if (AdvGame.GetReferences ().settingsManager != null)
 {
 SettingsManager settingsManager = AdvGame.GetReferences ().settingsManager;

 if (GUILayout.Button ("Music Storage window"))
 {
 MusicStorageWindow.Init ();
 }

 if (settingsManager.musicStorages.Count == 0)
 {
 EditorGUILayout.HelpBox ("Before a track can be selected, it must be added to the Music Storage window.", MessageType.Info);
 return;
 }

 string fadeLabel = "Transition time (s):";

 loop = EditorGUILayout.Toggle ("Loop?", loop);
 isQueued = EditorGUILayout.Toggle ("Queue?", isQueued);
 resumeIfPlayedBefore = EditorGUILayout.Toggle ("Resume if played before?", resumeIfPlayedBefore);

 minRange = EditorGUILayout.DelayedIntField ("Min track index:", minRange);
 maxRange = EditorGUILayout.DelayedIntField ("Max track index:", maxRange);

 fadeTimeParameterID = Action.ChooseParameterGUI (fadeLabel, parameters, fadeTimeParameterID, ParameterType.Float);
 if (fadeTimeParameterID < 0)
 {
 fadeTime = EditorGUILayout.Slider (fadeLabel, fadeTime, 0f, 10f);
 }

 if (fadeTime > 0f && !isQueued)
 {
 willWait = EditorGUILayout.Toggle ("Wait until transition ends?", willWait);

 if (willWait && !loop)
 {
 willWaitComplete = EditorGUILayout.Toggle ("Wait until track ends?", willWaitComplete);
 }
 }
 else if (!loop)
 {
 willWaitComplete = EditorGUILayout.Toggle ("Wait until finish?", willWaitComplete);
 }
 }
 else
 {
 EditorGUILayout.HelpBox ("A Settings Manager must be defined for this Action to function correctly. Please go to your Game Window and assign one.", MessageType.Warning);
 }
 }

 #endif

 }

```