文章目录

  • 一、前言
  • 二、获取UI素材
  • 三、使用UGUI制作界面
    • 1、界面布局
    • 2、账号圆形头像
    • 3、搜索框
    • 4、调节UI层
    • 5、黑色按钮悬浮高亮效果
    • 6、纯文字按钮
    • 7、滚动列表自适应
    • 8、歌名与视频图标混排
    • 9、点击按钮切换图片
    • 10、进度条
  • 四、写代码
    • 1、歌曲的播放与暂停
    • 2、声音频谱特效
    • 4、获取声音总时长
    • 5、设置当前时间戳
    • 6、发布exe隐藏标题栏
  • 五、工程源码
  • 六、完毕

一、前言

嗨,大家好,我是新发。
事情是这样的,我在听歌的时候听到了滨崎步的MY ALL,热泪盈眶,旋律起,爷青回,

【4K收藏级画质】滨崎步神曲《My All》唱哭全场!!!

我点开酷狗,端详了一下,冒出个想法,我能不能用Unity做一个高仿酷狗音乐播放器,只播放滨崎步的这首歌。
于是,我就做了一个,最终效果如下:

运行效果:


发布成exe,运行效果:

下面,我来讲讲我的制作过程~

二、获取UI素材

下面是真酷狗界面,

根据界面,去阿里图标库搜索需要的素材,
阿里图标库地址:https://www.iconfont.cn/
比如我们要找这一块的图标素材,

我的电台为例,

你就搜电台,找到一个形状相似的图标,如下

点击图标,可以先设置图标的颜色为白色,然后再下载,

以此类推,我找的素材如下:

所有的UI素材图片格式都设置为Sprite (2D and UI)

有一部分UI需要设置一下九宫格,不然可能会变形,比如这个椭圆按钮,

三、使用UGUI制作界面

最终界面效果如下,

下面我会挑一下重点讲一下。

1、界面布局

在开始做UI界面之前,我们要先分析一下界面布局,首先从大布局看,是上、中、下,

那我们做界面时,就按上、中、下三块来做,

如下:

中间布局,又可以继续拆分成顶部标签栏和底部详细面板,以我的音乐为例,底部面板可以分为左右布局,如下:

这样子,我们中间就可以分成tabsleftright三块,

如下:

以此类推,大布局里嵌小布局,小布局里继续嵌小小布局,根据界面进行合理设计。

2、账号圆形头像

头像图片是正正方方的,如下:

我们需要显示圆形头像,可以使用Mask组件,如下head_frame节点,

使用一张圆形的图片显示,并挂上Mask组件,

子节点head_img就是头像图片了,

使用RawImage组件来显示头像,

效果如下:

3、搜索框

搜索框使用InputField组件,

替换框的图片,设置颜色,如下,

搜索框中再放一个Button来显示放大镜图片,


效果如下:

4、调节UI层

我的音乐这个按钮,

正确是要显示在最前面,

它之所以被挡住,是因为UGUI默认是按节点的顺序来渲染的,后面的按钮排在它下面,所以后面的按钮会盖住它,

如果我们不想调节节点的顺序,但又想让我的音乐按钮显示在前面,我们可以给它单独挂一个Canvas组件,并设置Sort Order为一个大于上一级CanvasSort Order的值,

这样它就可以正常显示在前面了,

5、黑色按钮悬浮高亮效果

鼠标悬停在按钮上时,按钮呈高亮状态,如下,

如果你把按钮Image图片设置为黑色,那么是没有这个高亮效果的,因为一个按钮是由ImageButton配合工作的,Button组件可以设置各个状态的颜色,Button组件的颜色和Image的颜色相乘就是最终的按钮状态颜色,如果Image颜色你设置成黑色,那么相乘得出的结果都是黑色,你也就看不到高亮效果了,

正确做法是,Image为白色,ButtonNormal Color为黑色,其他状态的颜色根据具体需求而定,比如高亮Hightlighted Color为灰色,最终颜色设置如下:

6、纯文字按钮

这排按钮是纯文字按钮,

UGUI创建的默认按钮是带图片的,做下小改动即可,我们通过菜单创建一个Button

Image组件移除掉,

然后把子节点的Text赋值给Button组件的Target Graphic即可,

设置一下按钮的各个状态颜色,

我们直接调节Button节点的宽高即可调节响应区域啦~

鼠标靠近文字时,按钮可以检测到,如下,

注:对于有图片的按钮,如果也想扩大按钮的响应区域但又不想扩大图片本身,也可以利用这个技巧,把按钮背景图作为Button组件的子节点显示即可

7、滚动列表自适应

滚动列表用的是ScrollView

需要处理的是Content的自适应,首先列表是竖向滑动的,我们给Content节点挂上VerticalLayoutGroup组件,

要让Content的高度随着列表item的数量增多而增大,我们可以使用ContentSizeFitter组件,把Vertical Fit设置为Preferred Size

然后给item设定一个高度,

这样子,当item增多的时候,Content节点就会自动扩大高度啦,

8、歌名与视频图标混排

在单曲列表中,歌名和视频图标混排在一起,视频图标需要跟在歌名后面,歌名文字增多,视频图标需要自动往后移动,如下:

这个要用到锚点,视频图标作为歌名文字的子节点,然后视频图标的锚点设置为middle-right,如下,这样子,视频图标就会以文字框的右边为参考线计算相对位置了,

9、点击按钮切换图片

点击按钮切换按钮图片,如下

这里要写点代码,在代码中替换Button组件的ImageSprite对象,例:

playBtn.onClick.AddListener(() =>
{if (!audioSource.isPlaying){audioSource.Play();playBtn.image.sprite = pauseSprite;}else{audioSource.Pause();playBtn.image.sprite = playSprite;}
});

10、进度条

进度条使用Slider组件,

需要解决的是进度条很细的情况下,扩大进度条的操作区域,解决办法是给Slider添加一个Image组件,并设置透明度为0

调整Slider的高为一个稍微大一点的值,

调整BackgroundTopBottom,使其变细,

同理,Fill Area也调整一下TopBottom,使其变细,

这样子做出来的进度条,就可以很细,但是操作区域又得到保证,

四、写代码

1、歌曲的播放与暂停

Unity中要播放一个声音并听到,需要两个组件配合,一个是AudioSource(相当于喇叭),另一个AudioListener(相当于耳朵),
其中,AudioListener默认挂在摄像机上,如果你有多个摄像机,要确保场景中只有一个激活状态的AudioListener,否则会报错。
AudioSource需要赋值AudioClip成员,即设置具体的声音文件,我们可以直接拖拽一个声音文件到AudioSourceAudioClip成员上,如下:

我们也可以在代码中动态设置:

// AudioClip audioClip = TODO 动态加载AudioClip文件;
audioSource.clip = audioClip;

动态加载资源文件我之前的文章有讲过三种主要方式,大家感兴趣的可以看下,
《Unity游戏开发——新发教你做游戏(三):3种资源加载方式》

然后播放声音和暂停播放,调用AudioSourcePlayPause方法即可:

// (继续)播放
audioSource.Play();
// 暂停
audioSource.Pause();

2、声音频谱特效

声音播放过程中,可以实时显示频谱特效,

这里要用到AudioSourceGetSpectrumData接口,这个接口可以采样声谱数据块,

public static void GetSpectrumData(float[] samples, int channel, FFTWindow window);

参数说明:
samples: 函数返回值。将音频样本数据传送至samples数组,数组大小必须为2的n次方,最小64,最大8192
channel: 声道,一般设置为0
window: 转换信号所用的窗函数,算法越复杂,声音越柔和,但速度更慢。
用法 :
先声明一个浮点数组:

public float[] samples = new float[512];

然后在Update方法里面使用方法:

audiosource.GetSpectrumData(samples, 0, FFTWindow.BlackmanHarris);

我这里封装了一个脚本,如下:

using UnityEngine;/// <summary>
/// 声音特效
/// </summary>
public class AudioEffect : MonoBehaviour
{// 用于显示的方块public GameObject cubeObj;// 方块的其实点public Transform startPoint;// 采样数据长度private const int SPECTRUM_CNT = 512;// 采样数据private float[] spectrumData = new float[SPECTRUM_CNT];// 方块Transform数组private Transform[] cubeTransforms = new Transform[SPECTRUM_CNT];void Start(){//cube生成与排列Vector3 p = startPoint.position;for (int i = 0; i < SPECTRUM_CNT; i++){p = new Vector3(p.x + 0.11f, p.y, p.z);GameObject cube = Instantiate(cubeObj, p, cubeObj.transform.rotation);cube.transform.parent = startPoint;cubeTransforms[i] = cube.transform;}}/// <summary>/// 当前帧频率波功率,传到对应cube的localScale/// </summary>public void UpdateEffect(AudioSource audioSource){audioSource.GetSpectrumData(spectrumData, 0, FFTWindow.BlackmanHarris);float scaleY;for (int i = 0; i < SPECTRUM_CNT; i++){scaleY = Mathf.Lerp(cubeTransforms[i].localScale.y, spectrumData[i] * 10000f, 0.5f);// 限制一下功率if (scaleY > 400){scaleY -= 400;}else if (scaleY > 300){scaleY -= 300;}else if (scaleY > 200){scaleY -= 200;}else if (scaleY > 100){scaleY -= 100;}cubeTransforms[i].localScale = new Vector3(0.15f, scaleY, 0.15f);}}
}

其中cubeObj是一个用于显示的小方块,我们做一下方块预设,如下:

材质球用的shaderUnlit/Texture,贴图是上面白下面黑的渐变色,

因为这个特效要显示在UI界面中,并且是穿插在UI层中,我这里使用RenderTexture来解决。
先创建一张RenderTexture

然后创建一个独立的摄像机EffectCamera(记得把AudioListener组件去掉),Culling Mask只勾选Water层,

主摄像机记得把Water去掉,

把特效的Layer设置为Water

这样子,特效就只会在EffectCamera摄像机中渲染了,
我们把刚刚的RenderTexture拖给EffectCamera摄像机的Target Texture,如下,

接着,给audioEffect节点挂AudioEffect脚本,并赋值成员对象,如下,

这样特效就会渲染到RenderTexture上了,如下:

我们再使用一张RawImage来显示它,

我们可以调节RawImage的颜色来调整特效的颜色,如下:

4、获取声音总时长

var len = audioSource.clip.length;

5、设置当前时间戳

根据进度条进度设置当前时间戳

slider.onValueChanged.AddListener((v) =>{if (v < 1)audioSource.time = v * audioSource.clip.length;});

6、发布exe隐藏标题栏

发布成exe,运行时自动隐藏默认的标题栏,

隐藏标题栏的方法,我之前有写过相关文章,《Unity发布PC平台exe的窗口花样(WindowsAPI、捕获关闭事件、隐藏窗口标题栏、隐藏最小化最大化关闭按钮等等)》
用到了几个Windows API,如下:

[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();[DllImport("user32.dll")]
public static extern long GetWindowLong(IntPtr hwd, int nIndex);[DllImport("user32.dll")]
public static extern void SetWindowLong(IntPtr hwd, int nIndex, long dwNewLong);[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hwd, int cmdShow);

隐藏标题栏:

#if UNITY_STANDALONE && !UNITY_EDITOR
/// <summary>
/// 窗口风格
/// </summary>
const int GWL_STYLE = -16;
/// <summary>
/// 标题栏
/// </summary>
const int WS_CAPTION = 0x00c00000;// 隐藏标题栏
var hwd = GetForegroundWindow();
var wl = GetWindowLong(hwd, GWL_STYLE);
wl &= ~WS_CAPTION;
SetWindowLong(hwd, GWL_STYLE, wl);
#endif

另外,我们需要实现这三个按钮的逻辑,

最小化窗口:

#if UNITY_STANDALONE && !UNITY_EDITOR
/// <summary>
/// 最小化
/// </summary>
const int SW_SHOWMINIMIZED = 2;// 获得窗口句柄
var hwd = GetForegroundWindow();
// 设置窗口最小化
ShowWindow(hwd, SW_SHOWMINIMIZED);
#endif

最大化窗口:

#if UNITY_STANDALONE && !UNITY_EDITOR
/// <summary>
/// 最大化
/// </summary>
const int SW_SHOWMAXIMIZED = 3;// 获得窗口句柄
var hwd = GetForegroundWindow();
// 设置窗口最小化
ShowWindow(hwd, SW_SHOWMAXIMIZED);
#endif

关闭程序:

Application.Quit();

五、工程源码

本文的工程源码我以上传到CODE CHINA,感兴趣的同学可自行下载学习,
地址:https://codechina.csdn.net/linxinfa/UnityMusicPlayer
注:我使用的Unity版本为Unity 2020.1.14f1c1 (64-bit)
温馨提示:本工程仅供学习使用,禁止用于商业用途,否则后果自负

六、完毕

最后,附上滨崎步MY ALL的歌词,初识不知曲中意,再听已是曲中人!

多少时光
我们一同经历
多少路程
我们一起走过
至今我们所留下的
虽然不够完美却也灿烂过
如今在这里 那些结晶
正闪耀著骄傲的光辉
一直都那麽开心和快乐
坦白说并不是那麽回事
然而我们永远
都不会是孤身一人
想让你看见梦想的所在
没有终结 没有消亡
真的很想看见那样的梦想
那正是我的愿望
想要一直守护在你身旁
不管即将发生什么
我将用我的全部
一直将你守护
从不曾有丝毫后悔
知道现在我都可以这样断言
我们一直都在竭尽全力地
奋战到底
在那些铭心的夜晚
事实上也会常常想起你
然而我们永远
都不是孤身一人
看到你的笑颜
令人爱恋 令人目眩
多想再看到那样的笑颜
所以我仍活到今天
我能感觉到你的爱
有力而温暖
那样无偿的爱情
我尽全力地感受著
想让你看见梦想的所在
没有终结 没有消亡
真的很想让你看见那样的梦想
那正是我的愿望
我想守护在你的身旁
不管即将发生什麽
我将用我的全部
一直将你守护


好了,就到这里吧,我要再去单曲循环听亿编了~
我是林新发:https://blog.csdn.net/linxinfa
原创不易,若转载请注明出处,感谢大家~
喜欢我的可以点赞、关注、收藏,如果有什么技术上的疑问,欢迎留言或私信,我们下期见~

【游戏开发创新】手把手教你使用Unity制作一个高仿酷狗音乐播放器,滨崎步,旋律起,爷青回(声音可视化 | 频谱 | Audio)相关推荐

  1. 仿酷狗音乐播放器开发日志二十二 动态调色板控件第二版(性能大幅提升附源码)...

    转载请说明原出处,谢谢~~ 在上次写的博客<仿酷狗音乐播放器开发日志二十一 开发动态调色板控件(附源码)>发布后,我在群里和网友讨论这个控件的性能和优 缺点,发现了他很多不足,还有很多提升 ...

  2. 仿酷狗音乐播放器开发日志——整体框架分析

    转载请说明出处,谢谢~~ 学习duilib界面库有一段时间了,除了仓鼠软件共享以外还没用它开发过什么完整的软件项目.今天看到酷狗音乐播放器做得不错,经过几年的改革,酷狗现在的UI已经相当不错了.在这个 ...

  3. 仿酷狗音乐播放器开发日志二十一 开发动态调色板控件(附源码)

    转载请说明原出处,谢谢~~ 上一篇仿酷狗日志结束后,整个换肤功能就只剩下调色板功能没有做了,我本以为会很简单,但是研究了酷狗的调色板功能后发现不是那么简单的事情.首先看一下酷狗的调色板的样子: 我原本 ...

  4. 仿酷狗音乐播放器开发日志二十一 开发动态调色板控件(附源代码)

    转载请说明原出处,谢谢~~ 上一篇仿酷狗日志结束后,整个换肤功能就仅仅剩下调色板功能没有做了.我本以为会非常easy.可是研究了酷狗的调色板功能后发现不是那么简单的事情.首先看一下酷狗的调色板的样子: ...

  5. 仿酷狗音乐播放器开发日志二十四 选项设置窗体的实现(附328行xml布局源码)

    转载请说明原出处,谢谢~~ 花了两天时间把仿酷狗的选项设置窗体做出来了,当然了只是做了外观.现在开学了,写代码的时间减少,所以整个仿酷狗的工程开发速度减慢了.今天把仿酷狗的选项设置窗体的布局代码分享出 ...

  6. 仿酷狗音乐播放器开发日志二十四 选项设置窗体的实现(附328行xml布局源码)...

    转载请说明原出处,谢谢~~ 花了两天时间把仿酷狗的选项设置窗体做出来了,当然了只是做了外观.现在开学了,写代码的时间减少,所以整个仿酷狗的工程开发速度减慢了.今天把仿酷狗的选项设置窗体的布局代码分享出 ...

  7. 仿酷狗音乐播放器开发日志二十三 修复Option控件显示状态不全的bug(附源码)...

    转载请说明原出处,谢谢~~ 整个仿酷狗工程的开发将近尾声,现在还差选项设置窗体的部分,显然在设置窗体里用的最多的就是OptionUI控件,我在写好大致的布局后去测试效果,发现Option控件的显示效果 ...

  8. Redrain仿酷狗音乐播放器开发完毕,发布测试程序

    转载请说明原出处,谢谢~~ 从暑假到现在中秋刚过,我用duilib开发仿酷狗播放器大概经历了50天.做仿酷狗的意图只是看原酷狗的界面比较漂亮,想做个完整一些的工程来练习一下duilib.今天把写好的程 ...

  9. 仿酷狗音乐播放器开发日志十八——换肤功能的实现二:改变控件和窗体透明度(附挂件类源码)...

    转载请说明原出处,谢谢~~ 昨天把大致布局分析了一下,昨天晚上把布局写好实现了,今天把大致的功能完成了一下,现在的外观已经和原酷狗的换肤界面完全一样,其中的调整播放列表透明度和设置整个软件透明度的代码 ...

最新文章

  1. Open Street Map维基世界地图初探--概念、开发
  2. 另一个日历(根据农历网上的寿星万年历修改)最新修改适应FF
  3. mysql5.6.37免安装_mysql5.6免安装配置
  4. [NOI2019] 序列(模拟费用流)
  5. java反射源码_java反射技术详解附源码
  6. 华为EMUI10带来开发者福音:一次开发多端部署
  7. 根据函数名称调用函数
  8. VScode下载安装及使用教程
  9. 戒指你戴对了吗?Meet Surprise教你正确的戴法
  10. 7、高德地图(定位、复位功能)
  11. 三星s8html查看器,拆解三星S8手机
  12. NLog NETCore 3.0 Porting
  13. 收藏向:看完此篇让你轻松玩转领英
  14. TikTok与抖音有什么不同?为什么TikTok被称为“海外版抖音”?
  15. 解决layui的table数据重载reload where参数会保留上次条件的问题
  16. 华为为什么认可这四所大学?(附微电子高校排行榜)
  17. Unity3d学习笔记 var 关键字
  18. 房贷利率下调 现在是买房的时机吗?
  19. 洛谷[USACO06JAN]把牛Corral the Cows
  20. 全网最全面的npm包管理学习

热门文章

  1. 《机器学习实战:基于Scikit-Learn、Keras和TensorFlow(第2版)》学习笔记
  2. QT中的视频显示优化
  3. python实现《直觉模糊集决策与对策分析方法》08直觉模糊数的矩阵对策解法
  4. AVR单片机与C语言的一些入门简要概述
  5. 分频电路的实现:奇数分频、偶数分频和小数分频
  6. PIO操作与DMA操作
  7. 学汇率规避风险知识做懂汇率的外贸人
  8. 十年互联网项目实战经验分享:项目经理成长之路的三个层次
  9. Cisco测试命令和TCP/IP连接故障处理整理集合
  10. 无线室内定位系统和技术在地下采矿中的应用综述2021Applications of Wireless Indoor Positioning Systems and Technologies in U