- Home /
UI Text to Display Loading Progress of Songs in Music Folder
OK I have this music player scrip that basically all that is missing is a way for it to display the progress of the songs being loaded so that the player does not think its broken while nothing is happening. How can I do this with the existing UI text that also displays the song currently being played?
Or would I need a totally different UI text reference?
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine.UI;
public class AltMusicPlayer : MonoBehaviour
{
public Text MusicListText;// Reference to my UI Display Text for Songs
private string display = "";//UI Text reference
public enum SeekDirection { Forward, Backward }
public AudioSource source;
bool playing = true;
public List<AudioClip> clips = new List<AudioClip>();
[SerializeField] [HideInInspector] private int currentIndex = 0;
private FileInfo[] soundFiles;
private List<string> validExtensions = new List<string> { ".ogg", ".wav" }; // Don't forget the "." i.e. "ogg" won't work - cause Path.GetExtension(filePath) will return .ext, not just ext.
private string absolutePath = "./Audio/Music"; // relative path to where the app is running - change this to "./music" in your case
void Start()
{
//being able to test in unity
if (Application.isEditor)
absolutePath = "Assets/Audio/Music";
if (source == null)
source = gameObject.AddComponent<AudioSource> ();
ReloadSounds ();
}
void Update(){
if(!source.isPlaying && playing)
{
Seek(SeekDirection.Forward);
PlayCurrent();
}
}
//My New UI Buttons Added
public void PlayPrevious (){
Seek(SeekDirection.Backward);
PlayCurrent();
}
public void PlayCurrentClip () {
PlayCurrent();
playing = true;
}
public void PlayNext () {
Seek(SeekDirection.Forward);
PlayCurrent();
}
public void ReloadAudio () {
ReloadSounds();
}
public void StopAudio () {
source.Stop ();
playing = false;
}
public void PauseAudio () {
source.Pause ();
playing = false;
}
void Shuffle()
{
//Shuffle or Randomize Songs in Array List
//ShuffleMusic();
}
//End My New UI Buttons Added
void Seek(SeekDirection d)
{
if (d == SeekDirection.Forward)
currentIndex = (currentIndex + 1) % clips.Count;
else {
currentIndex--;
if (currentIndex < 0) currentIndex = clips.Count - 1;
}
}
void PlayCurrent()
{
source.clip = clips[currentIndex];
source.Play();
Debug.Log (source.clip);
MusicListText.text = clips[currentIndex].name;
}
void ReloadSounds()
{
clips.Clear();
// get all valid files
var info = new DirectoryInfo(absolutePath);
soundFiles = info.GetFiles()
.Where(f => IsValidFileType(f.Name))
.ToArray();
// and load them
foreach (var s in soundFiles)
StartCoroutine(LoadFile(s.FullName));
}
bool IsValidFileType(string fileName)
{
return validExtensions.Contains(Path.GetExtension(fileName));
// Alternatively, you could go fileName.SubString(fileName.LastIndexOf('.') + 1); that way you don't need the '.' when you add your extensions
}
IEnumerator LoadFile(string path)
{
WWW www = new WWW("file://" + path);
print("loading " + path);
AudioClip clip = www.GetAudioClip(false);
while(!clip.isReadyToPlay)
yield return www;
print("done loading");
clip.name = Path.GetFileName(path);
clips.Add(clip);
//Count Array List Length
//source.clip = clips[currentIndex];
Debug.Log (clip);
//int List = clips.Count;
//Debug.Log (List);
}
//NEW
void AddText()
{
display = currentIndex + " : " + clips[currentIndex].name;
MusicListText.text = display;
}
//END NEW
//Quit Button
public void GoQuit(){
StartCoroutine(LoadQuit("MainScreen"));
}
IEnumerator LoadQuit(string levelMain){
yield return new WaitForSeconds(0.5f); // wait time
Application.LoadLevel(levelMain);
}
}
Answer by fafase · Dec 12, 2015 at 06:49 PM
You add two Image objects, one parent of the other. Make the parent the size you want the bar and the color of the under section (Grey for instance). Then the child one, has anchor in each four corners of the parent and a red color for instance (min 0,0, max 1,1). All values on top at 0 so that the child occuppies the whole space
Then you can access the anchorMax vector2 of your moving loading bar and make it increase until 1:
float valueX = elapsedSongTime / fullSongTime;
loadingBar.GetComponent<RectTransform>().anchorMax = new Vector2(valueX, 1);
This will automatically update the bar based on the sizeDelta which is 0 and it will follow the movement.
@fafuase, Where and how would I implement this into that existing script?
You would not touch the script you displayed, it is meant to deal with the player and should not do anything else.
You should have a public method that reports the seek pointer, another one for the full counter of the song and one that reports the percentage of elapsed time:
public float ElapsedPercentage(){
return current / fullLength; // not sure of variable names, you should know
}
You add a new script to control your bar and you listen to those values and update the bar appropriately.
@fafase, So I would put the script on the load bar object? Which part, the child or the parent?
Plus I'm not fully sure I understand what this completed script should look like?
@fafase, I added this to a new script, I have not put it on the load bar as I get errors?
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class $$anonymous$$usicLoadBar : $$anonymous$$onoBehaviour {
float valueX = elapsedSongTime / fullSongTime;
loadingBar.GetComponent<RectTransform>().anchor$$anonymous$$ax = new Vector2(valueX, 1);
public float ElapsedPercentage(){
return current / fullLength; // not sure of variable names, you should know
}
}
ElapsedPercentage is on the $$anonymous$$usic player script. It returns the percentage of the song that was played. It goes on the one you showed in the question and uses some of the variables in there.
Another script goes on the loading bar, it gets a reference to the loading and the music player script so that it can update the anchor$$anonymous$$ax value on the rect transform of the loading bar with the value of the elapsed time.