![在这里插入图片描述](https://img-blog.csdnimg.cn/dc943fe79dd14681874832aa7d3fc286.png)
介绍
首先,这个功能的实现仅为demo,给予正在实现本功能的小伙伴一点思路.如果帮到了一些人也属初心所向,不喜勿喷!
工程源码::Demo源码工程
逻辑
主要依赖于UGUI Scroll View通过调用它的verticalNormalizedPosition属性来实现轮播滚动的效果.
歌词的存储格式常见的为**.lrc文件,通过IO将每一行读取到一个List**里,再由循环将每段歌词实例化在Scroll View 的 Content节点下.
场景搭建
创建一个Scene场景 : VideoScene
创建一个Scroll View 如图:
在父物体 Canvas层 挂载一个 Audio Source 同时把我们想要播放的歌曲文件拖到 AudioCilp这个属性里
配置 Content节点的组件
代码部分
可以创建一个脚本 命名 AudioTest.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
public class AudioTest : MonoBehaviour
{
public GameObject lrcText;
public Transform lrcTextparent;
public ScrollRect ScrollRect;
public AudioSource audioSource;
public float GridIndexList;
public float GridIndexList2;
public float EndPos;
private bool m_IsLock = false;
private void Start()
{
audioSource.Play();
//ProcessingData(ReadLrcFile(Application.dataPath + "/lyric/好久不见-陈奕迅.lrc"));
ProcessingData(Readlyirc(src));
Debug.Log("floattimelist:" + floattimelist.Count);
Debug.Log("stringlyriclist:" + stringlyriclist.Count);
ShowLrc();
currindex = 0;
ScrollRect.verticalNormalizedPosition = 0;
}
int lastindex = -1;
int currindex = 0;
// private void Update()
// {
// for (int i = 0; i < floattimelist.Count; i++)
// {
// if (audioSource.time >= floattimelist[i] && audioSource.time < floattimelist[i + 1])
// {
// currindex = i;
// if (currindex != lastindex)
// {
// lastindex = currindex;
// Debug.Log("句子:" + currindex);
// ShowLrc(currindex);
// }
// return;
// }
// }
// }
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
m_IsLock = true;
}
for (int i = 0; i < floattimelist.Count; i++)
{
if (audioSource.time >= floattimelist[i] && audioSource.time < floattimelist[i + 1])
{
currindex = i;
if (currindex != lastindex)
{
lastindex = currindex;
//Debug.Log("句子:" + ScrollRect.verticalNormalizedPosition);
ShowLrc(currindex);
m_IsLock = false;
}
return;
}
}
}
private void FixedUpdate()
{
if (!m_IsLock)
{
PlayUIAnim(EndPos, 0.05f);
}
}
public void PlayUIAnim(float endPos, float endTime)
{
ScrollRect.verticalNormalizedPosition = Mathf.Lerp(ScrollRect.verticalNormalizedPosition, endPos, endTime);
}
float temp = 1;
/// <summary>
/// 显示lyric
/// </summary>
/// <param name="index"></param>
void ShowLrc(int index)
{
// if (index >= 1)
// {
// temp -= offest;
// if (temp >= 0)
// {
// ScrollRect.verticalNormalizedPosition = temp;
// Debug.Log(temp);
// }
// }
// texts[index].color = Color.green;
// if (index > 0 && index < stringlyriclist.Count)
// {
// texts[index - 1].color = Color.gray;
// }
index -= 1;
//ScrollRect.verticalNormalizedPosition = 1f - ((float)index / ((float)texts.Count - 3f));
EndPos = 1f - ((float)index / ((float)texts.Count - 3f));
GridIndexList = (index / texts.Count);
GridIndexList2 = 1f - (index / texts.Count);
texts[index + 1].color = Color.black;
texts[index + 1].fontStyle = FontStyle.Bold;
texts[index + 1].fontSize = 30;
if (index > 0 && index < stringlyriclist.Count)
{
texts[index].color = Color.gray;
texts[index].fontStyle = FontStyle.Normal;
texts[index].fontSize = 24;
}
}
List<Text> texts = new List<Text>();
float offest = 0;
void ShowLrc()
{
ScrollRect.verticalNormalizedPosition = 1;
offest = 1f / (stringlyriclist.Count / 2f);
Debug.Log("offset" + offest);
for (int i = 0; i < stringlyriclist.Count; i++)
{
GameObject lyirc = Instantiate<GameObject>(lrcText, lrcTextparent);
Text text = lyirc.GetComponent<Text>();
text.text = stringlyriclist[i];
text.color = Color.gray;
lyirc.SetActive(true);
texts.Add(text);
}
}
/// <summary>
/// 读取 lyric 文件
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
List<string> ReadLrcFile(string path)
{
//存放歌词list
List<string> lyric = new List<string>();
StreamReader sr = new StreamReader(path, Encoding.Default);
string str = "";
while ((str = sr.ReadLine()) != null)
{
lyric.Add(str);
//Debug.Log(str);
}
return lyric;
}
/// <summary>
/// 读取 lyric 文件
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
List<string> Readlyirc(string lyirc)
{
List<string> lyric = new List<string>();
string[] strArr = lyirc.Split(new char[] { '\n' });
for (int i = 0; i < strArr.Length; i++)
{
lyric.Add(strArr[i]);
}
return lyric;
}
// 时间
public List<float> floattimelist = new List<float>();
// 句子
public List<string> stringlyriclist = new List<string>();
/// <summary>
/// 解析数据
/// </summary>
/// <param name="dataList">数据</param>
/// <returns></returns>
void ProcessingData(List<string> dataList)
{
// 所有数据
for (int i = 0; i < dataList.Count; i++)
{
//Debug.Log(dataList[i]);
string[] strarry = dataList[i].Split(new char[] { '[', ']' });
if (strarry != null && strarry.Length > 0)
{
for (int j = 1; j < strarry.Length; j++)
{
string tempstr = strarry[j];
//这是标题 --- 创作者
if (tempstr.StartsWith("ti") || tempstr.StartsWith("ar") || tempstr.StartsWith("al") || tempstr.StartsWith("by") || tempstr.StartsWith("offset"))
{
string[] strarry1 = tempstr.Split(':');
//valuePairs.Add(strarry1[0], strarry1[1]);
}
else
{
//这是内容
if (tempstr.Contains(":"))
{
string[] strarry1 = tempstr.Split(':');
float m = float.Parse(strarry1[0]) * 60;
float s = float.Parse(strarry1[1]);
//ms ms = (m + s).ToString();
//Debug.Log(ms);
//时间
floattimelist.Add(m + s);
}
else
{
//句子
stringlyriclist.Add(tempstr);
}
}
}
}
}
}
string src = "[00:00.17]苏星婕 - 不期而遇的风\n" +
"[00:00.67]作词:峦无眠\n" +
"[00:00.88]作曲:辛雯\n" +
"[00:01.10]编曲:闫天聪\n" +
"[00:01.31]音乐制作:翌月文化\n" +
"[00:01.67]监制:成若颖、Wenasa黄嘉雯\n" +
"[00:02.09]混音、母带:无机草莓\n" +
"[00:02.45]录音师:无机草莓\n" +
"[00:02.81]录音棚:莫非录音棚(成都)\n" +
"[00:03.23]总企划:zoki、佰\n" +
"[00:03.45]总策划:包包子\n" +
"[00:03.73]艺人统筹:zoki、佰、要回家\n" +
"[00:17.80]听说晚风来的时候适合遇见\n" +
"[00:21.59]如星星和海平面\n" +
"[00:25.01]总相遇在晴天的夜晚\n" +
"[00:27.81]我想我和你只是缺对的时间\n" +
"[00:33.15]你说我对星空许过的每个愿\n" +
"[00:37.10]有一天都会实现\n" +
"[00:40.11]而那些放飞过的思念\n" +
"[00:43.24]会带着你如约而来的出现\n" +
"[00:47.20]我知道你会像不期而遇的风\n" +
"[00:51.24]突然出现在某一个黄昏\n" +
"[00:54.83]和落日一起穿过人潮汹涌\n" +
"[00:58.81]扑面而来和我相拥\n" +
"[01:02.58]我知道你会像不期而遇的风\n" +
"[01:06.69]携带着我等候已久的梦\n" +
"[01:10.30]借月亮的光和山野的雾灯\n" +
"[01:14.27]填满遗憾的每个裂缝\n" +
"[01:35.14]你说我对星空许过的每个愿\n" +
"[01:38.97]有一天都会实现\n" +
"[01:41.95]而那些放飞过的思念\n" +
"[01:45.21]会带着你如约而来的出现\n" +
"[01:48.95]我知道你会像不期而遇的风\n" +
"[01:53.08]突然出现在某一个黄昏\n" +
"[01:56.85]和落日一起穿过人潮汹涌\n" +
"[02:00.71]扑面而来和我相拥\n" +
"[02:04.62]我知道你会像不期而遇的风\n" +
"[02:08.45]携带着我等候已久的梦\n" +
"[02:12.25]借月亮的光和山野的雾灯\n" +
"[02:16.18]填满遗憾的每个裂缝\n" +
"[02:20.04]我知道你会像不期而遇的风\n" +
"[02:23.88]突然出现在某一个黄昏\n" +
"[02:27.84]和落日一起穿过人潮汹涌\n" +
"[02:31.69]扑面而来和我相拥\n" +
"[02:35.49]我知道你会像不期而遇的风\n" +
"[02:39.41]携带着我等候已久的梦\n" +
"[02:43.26]借月亮的光和山野的雾灯\n" +
"[02:47.16]填满遗憾的每个裂缝";
}