传送门:(完整工程见第五章篇尾)
音乐播放器的实现(一)-- Audio Listener和Audio Source面板的介绍
音乐播放器的实现(二)---UI面板的制作
音乐播放器的实现(四)—— 歌曲列表、顺序播放、单曲循环、随机播放、自动下一曲
音乐播放器的实现(五)—— 音量的加减和静音
设计好面板,接下来就开始进行后台代码的编写了。
在Unity3D中的Project面板单机鼠标右键, Create—>C# Script,命名为Player,然后双击打开,进行编写。
核心代码讲解:
1.在Start方法中通过按钮名给各个按钮以及进度条加上监听,实现各个按钮的点击,每当拖拽或点击进度条(进度条的value值改变),音频就会播放到相应位置。
(2021.1.25更)
有一个兄弟提出这个方式播放时有滋滋啦啦的声音(在此感谢这位小哥[抱拳])
他也给我分享了原因,经检测后证实确实有这样的Bug,所以我对代码做出了一些修改(下面代码均为修改过后的,请放心!)
void Start()
{
_instance = this;
aus.Stop(); //开始运行时不播放,点播放键才开始播放
#region 注:该方式虽然可以直接达到拖动进度条就播放到进度条当前的音乐,但会产生滋滋啦啦的杂音,是因为进度条value变化,使之不断调用onValueChanged,从而让音乐的进度发生了变化,音乐前后颠倒,不断重叠
///
/// 所以新建了个DragSlider脚本,挂在进度条上,来实现拖动播放的效果
///
//slid.onValueChanged.AddListener(delegate
//{
// //加上之后,避免拖动进度条到最后不松手时报错
// if (slid.value == 1)
// return;
// //给进度条添加事件监听,每当拖动进度条,歌曲从相应的位置播放
// aus.time = slid.value * aus.clip.length;
//});
#endregion
foreach (Transform go in buttons) //遍历所有的操作按钮
{
go.GetComponent
2.获取当前播放的音频的总时间,并显示在面板。
void alltime()//歌曲总时间
{
//slid.value = 0;
clipHour = (int)aus.clip.length / 3600;//时
clipMinute = (int)(aus.clip.length - clipHour * 3600) / 60;//分
clipSecond = (int)(aus.clip.length - clipHour * 3600 - clipMinute * 60);//秒
//显示歌曲总时间
allTime.text = string.Format("{0:D2}:{1:D2}:{2:D2}",
clipHour, clipMinute, clipSecond);
}
3.获取当前播放音频的已播放时间,并显示在面板,进度条跟着变化,表示进程。
void nowtime()//当前播放过的时间
{
currentHour = (int)aus.time / 3600; //时
currentMinute = (int)(aus.time - currentHour * 3600) / 60;//分
currentSecond = (int)(aus.time - currentHour * 3600 - currentMinute * 60);//秒
//显示当前播放过的时间
nowTime.text = string.Format("{0:D2}:{1:D2}:{2:D2} ",
currentHour, currentMinute, currentSecond);
//进度条变化
//(之后更新版)如果当前没有拖拽进度条
if(!DragSlider.isDrag)
slid.value = aus.time / aus.clip.length;
}
4.显示当前正在播放的音频
void nowMusic() //当前的音频
{
AudioClip clip = aus.clip; //当前播放的音频
string n = aus.clip.name; //当前播放的音频的名字
string[] na = n.Split('-'); //以“-”为分割点,把音频名分为若干部分
//显示当前正在播放的歌曲的名字【歌曲名(默认字体,25号)+歌手名(默认字体,18号,红色)的形式】
musicName.text = string.Format("{0} " + "\n{1} ", na[0], na[1]);
index = Array.IndexOf(auc, clip);//当前播放的音频在aus数组中的索引
Slider(); //当进度条走到最后时,播放下一曲
}
using UnityEngine;
using UnityEngine.EventSystems;
public class DragSlider : MonoBehaviour,IPointerDownHandler,IPointerUpHandler
{
public static bool isDrag;
///
/// 鼠标按下
///
///
public void OnPointerDown(PointerEventData eventData)
{
isDrag = true;
}
///
/// 鼠标抬起
///
///
public void OnPointerUp(PointerEventData eventData)
{
OnMouseUp();
isDrag = false;
}
void OnMouseUp()
{
//加上之后,避免拖动进度条到最后不松手时报错
if (Player._instance.slid.value == 1)
{
//进度条拉到最后,直接播放下一曲
Player._instance.NextMusic();
return;
}
//给进度条添加事件监听,每当拖动进度条,歌曲从相应的位置播放
Player._instance.aus.time = Player._instance.slid.value * Player._instance.aus.clip.length;
}
}
using System;
using UnityEngine;
using UnityEngine.UI;
public class Player: MonoBehaviour {
public Text musicName; //显示歌曲的名字及歌手
public Text nowTime; //显示歌曲已播放的时间长度
public Text allTime; //显示当前歌曲的总时间长度
public Slider slid; //进度条
public Transform buttons; //按钮所在的集合体
public AudioClip[] auc; //存放歌曲的数组
public AudioSource aus; //音频播放器
private int index; //数组aus的索引
private int currentHour, currentMinute, currentSecond; //已播放的时间(时、分、秒)
private int clipHour, clipMinute, clipSecond; //总时间(时、分、秒)
public static Player _instance;
void Start()
{
_instance = this;
aus.Stop(); //开始运行时不播放,点播放键才开始播放
#region 注:该方式虽然可以直接达到拖动进度条就播放到进度条当前的音乐,但会产生滋滋啦啦的杂音,是因为进度条value变化,使之不断调用onValueChanged,从而让音乐的进度发生了变化,音乐前后颠倒,不断重叠
///
/// 所以新建了个DragSlider脚本,挂在进度条上,来实现拖动播放的效果
///
//slid.onValueChanged.AddListener(delegate
//{
// //加上之后,避免拖动进度条到最后不松手时报错
// if (slid.value == 1)
// return;
// //给进度条添加事件监听,每当拖动进度条,歌曲从相应的位置播放
// aus.time = slid.value * aus.clip.length;
//});
#endregion
foreach (Transform go in buttons) //遍历所有的操作按钮
{
go.GetComponent
编辑完代码后保存,在unity面板中建一个空的GameObject,把代码挂上去,然后把对应的UI拖到相应的位置,具体如下图所示:
最终效果如下:
代码的备注写的也比较详细,欢迎评论区留言共同探讨。