0


Unity做一个剪辑声音的工具 在编辑器模式实时剪辑声音

Unity音频剪辑工具的实现

在游戏开发中,音频是一个至关重要的元素。音频剪辑工具能够帮助开发者高效地编辑和管理音频文件。本文将解析一个基于Unity编辑器的音频剪辑工具的实现方法

效果

在这里插入图片描述

工具功能

该音频剪辑工具允许用户在Unity编辑器中加载音频片段,并通过图形化界面进行剪辑、预览和保存操作。以下是该工具的主要功能:

  • 加载音频片段:用户可以通过工具界面选择并加载音频文件。
  • 波形显示:工具会生成音频的波形图,以帮助用户可视化音频数据。
  • 剪辑操作:用户可以通过滑动条调整音频的起始和结束时间,以便进行剪辑。
  • 音量控制:提供音量滑块,用户可以调整音频播放的音量。
  • 预览播放:用户可以播放剪辑后的音频片段进行预览。
  • 保存剪辑结果:工具支持将剪辑后的音频片段保存为新的音频文件。

代码解析

1. 显示工具窗口

首先,工具通过[MenuItem(“Tools/音频剪辑工具”)]创建一个菜单项,点击该菜单项可以显示音频编辑器窗口。
[MenuItem("Tools/音频剪辑工具")]publicstaticvoidShowWindow(){
    GetWindow<AudioClipEditor>("音频编辑器");}

2. 初始化音频资源

在OnEnable方法中,工具创建了一个隐藏的AudioSource用于播放音频。
privatevoidOnEnable(){
    audioSource = EditorUtility.CreateGameObjectWithHideFlags("AudioSource", HideFlags.HideAndDontSave ,typeof(AudioSource)).GetComponent<AudioSource>();}

3. 用户界面

工具通过OnGUI方法绘制用户界面,用户可以选择音频文件并进行编辑操作。
privatevoidOnGUI(){
    EditorGUILayout.BeginVertical();

    audioClip = EditorGUILayout.ObjectField("声音片段", audioClip ,typeof(AudioClip),false)as AudioClip;if(audioClipTemp != audioClip){
        audioClipTemp = audioClip;Init();}if(audioClip){DisplayAudioClipInfo();AdjustClipSection();DisplayVolumeControl();

        GUILayout.Space(10);if(GUILayout.Button("听", GUILayout.Height(40))){PlayTestAudio();}

        GUILayout.Space(10);if(GUILayout.Button("保存片段", GUILayout.Height(40))){ClipAndSave();}}

    EditorGUILayout.EndVertical();}

4. 初始化和显示音频信息

Init方法负责加载音频数据并生成波形图,DisplayAudioClipInfo方法显示音频的基本信息。
privatevoidInit(){if(audioClip !=null){
        endTime = audioClip.length;
        samples =newfloat[audioClip.samples * audioClip.channels];
        audioClip.GetData(samples ,0);UpdateWaveformTexture();}}privatevoidDisplayAudioClipInfo(){
    EditorGUILayout.LabelField($"开始时间: {startTime:F2}s");
    EditorGUILayout.LabelField($"结束时间: {endTime:F2}s");

    GUILayout.Space(10);}

5. 剪辑和预览功能

工具通过AdjustClipSection方法调整剪辑区间,通过PlayTestAudio方法进行预览播放。
privatevoidAdjustClipSection(){
    GUILayout.Label("调整剪辑片段");

    Rect waveformRect = GUILayoutUtility.GetRect(position.width ,64);if(waveformTexture ==null|| waveformTexture.width !=(int)waveformRect.width){UpdateWaveformTexture();}if(waveformTexture !=null){
        EditorGUI.DrawPreviewTexture(waveformRect , waveformTexture);}

    EditorGUILayout.MinMaxSlider("", ref startTime , ref endTime , 0f , audioClip !=null? audioClip.length : 10f);}privatevoidPlayTestAudio(){if(audioClip !=null){
        AudioClip clippedAudioClip =ClipAudio(audioClip , startTime , endTime);
        audioSource.clip = clippedAudioClip;
        audioSource.volume = volume;
        audioSource.Play();}else{
        Debug.LogError("请指定一段音频");}}

6. 保存剪辑后的音频

ClipAndSave方法允许用户将剪辑后的音频片段保存到文件。
privatevoidClipAndSave(){if(audioClip !=null){
        AudioClip clippedAudioClip =ClipAudio(audioClip , startTime , endTime);
        string savePath = EditorUtility.SaveFilePanel("保存剪辑的音频","Assets", audioClipTemp.name +"_New","wav");if(!string.IsNullOrEmpty(savePath)){SaveAudioClipToFile(clippedAudioClip , savePath);}}else{
        Debug.LogError("请指定一段音频");}}

7. 波形图生成

UpdateWaveformTexture方法更新波形图,GenerateWaveformTexture方法生成音频波形图像。
privatevoidUpdateWaveformTexture(){if(samples !=null){
        waveformTexture =GenerateWaveformTexture(samples , audioClip.channels ,(int)position.width ,64);}}private Texture2D GenerateWaveformTexture(float[] samples , int channels , int width , int height){
    Texture2D texture =newTexture2D(width , height , TextureFormat.RGBA32,false);
    Color[] colors =newColor[width * height];for(int i =0; i < colors.Length; i++){
        colors[i]= Color.black;}
    texture.SetPixels(colors);

    int packSize =( samples.Length / channels )/ width;for(int x =0; x < width; x++){
        float max =0;for(int i =0; i < packSize; i++){
            float sampleValue = samples[( x * packSize + i )* channels]* volume;if(sampleValue > max) max = sampleValue;}
        int heightValue =(int)( max * height );for(int y =0; y < heightValue; y++){
            texture.SetPixel(x , y , Color.yellow);}}
    texture.Apply();return texture;}

8. 剪辑音频片段

ClipAudio方法根据用户指定的起始和结束时间剪辑音频片段,并返回新的AudioClip。
private AudioClip ClipAudio(AudioClip originalClip , float start , float end){
    float[] data =newfloat[originalClip.samples * originalClip.channels];
    originalClip.GetData(data ,0);

    int newSampleCount =(int)(( end - start )* originalClip.frequency );
    float[] newData =newfloat[newSampleCount * originalClip.channels];

    int startIndex =(int)( start * originalClip.frequency * originalClip.channels );for(int i =0; i < newSampleCount * originalClip.channels; i++){
        newData[i]= data[startIndex + i]* volume;}

    AudioClip clippedAudioClip = AudioClip.Create("ClippedAudio", newSampleCount , originalClip.channels , originalClip.frequency ,false);
    clippedAudioClip.SetData(newData ,0);return clippedAudioClip;}

我为什么要使用?

  • 用户友好:工具通过图形化界面,使得音频剪辑操作直观易用,即使对非程序员用户也非常友好。
  • 实时预览:用户可以即时预览剪辑后的音频片段,方便进行调整。
  • 高效:工具内嵌于Unity编辑器中,无需切换应用程序,提升了开发效率。
  • 灵活性:提供音量控制功能,用户可以根据需求调整音量,确保最终效果符合预期。
  • 便捷保存:工具支持将剪辑后的音频片段保存为文件,便于后续使用和管理。
通过实现这个音频剪辑工具,我们可以看到在Unity中集成自定义工具的强大功能。它不仅提升了工作效率,也为开发者提供了更多的创作自由。希望本文对你理解和实现类似的工具有所帮助。

虽然文章写的已经够详细了,但是还是放出来 Demo吧,我知道大家都很忙,直接用一个工具挺好的~

有时间一定回来看看具体实现,学会写一些小工具来提升自己的开发效率,一起加油!


本文转载自: https://blog.csdn.net/CTangZe/article/details/139855538
版权归原作者 唐沢 所有, 如有侵权,请联系我们删除。

“Unity做一个剪辑声音的工具 在编辑器模式实时剪辑声音”的评论:

还没有评论