Unity Audio -- (2)创建动态音效

news2024/12/24 2:13:44

评估场景需求

        本节的目标是添加脚步声到角色身上,当角色走路时,触发动画事件并播放声音。

        脚步声是我们在真实世界中常常被我们所忽视的声音,但脚步声能够传达出许多环境信息。你现在可以花一小段时间绕着你周围的环境走一走并仔细听听脚步声。如果可能的话,在不同的表面上都行走一下,然后感受一下脚步声在不同的表面上的声音有什么不同(比如地毯和木地板上)?光脚和穿鞋时声音有什么不同?

        在示例场景中,我们可以看到三种不同的地面:草地、池子的水和洞穴。当玩家走过这些表面时,应该有不同的脚步声。

添加动画事件(Animation Events)

        我们希望达到的效果是,当角色的脚正好碰到地面时,会播放对应的脚步声。在Unity中,我们可以通过使用动画事件来完成这个功能,将角色动画动作过程的某个部分关联出对应音效的播放。动画事件的工作原理和关键帧是类似的,但它不是用来告诉角色该如何运动,而是发送一个消息,这个消息能够被脚本用来做一些事情。在案例中,我们会使用一个预先写好的脚本来播放脚步声。

        1. 进入到放置动画的目录,Assets > CreativeCore_Audio > StarterAssets > ThirdPersonController > Character > TutorialAnimations。

        2. 选择Locomotion--Walk_N动画

        3. 在Inspector中,选择Animation标签页,展开Events部分。

        Events展开后,主要有一个小的时间轴和一不同类型数据的列表,这些数据是能够被发送出去的,但目前我们没有添加任何事件,因此是灰色的。 

        4. 我们可以按住并向上拖动动画预览窗口上的带两条线的地方,将预览窗口放大一些。

        我们想要做的是在动画播放到角色的脚步刚好接触地面的时候,触发一个动画事件。为了达成这个目标,我们需要先在动画中定位到这个点。我们可以通过在动画预览窗口中手动拖动关键帧来得到这个点(左键按住播放键右边的那个灰色条进行拖动)。在拖动过程中, Event时间轴会调整到预览动画的对应位置。

        5. 拖动到角色左脚刚好接触地面的这一帧(大概是第9帧的位置)。

        6. Inspector中回到Events部分,点击Add Event按钮。

        此时在Event时间轴上动画指定的点上,会出现一个小的标志。这会启用时间轴下方的数据类型。

        7. 在funtion参数中,输入“PlayStep”。这个名字是后面我们要使用的脚本里的一个方法是对应的,因此确保这个名字拼写是没有问题的。

        8. 重复这个步骤,将玩家右脚正好接触地面时的PlayStep的Event也设置好。

        9. 在Inspector的底部,点击Apply按钮,保存事件到动画中。

        10. 在Animations目录中找到Run和Jump Landing的动画,重复上面添加event的过程。记住最后要点击Apply按钮保存修改。

应用Audio脚本

        目前动画已经配置成了当角色脚接触地面的时候,会发送出一个事件请求。这个事件会传递给和动画相连接的游戏对象,因此管理脚步声播放的脚本必须被用到角色上。为了能实际为动画播放声音,我们还需要给角色增加一个Audio Source组件。

        1. 在Scritps目录下,找到FootstepManager脚本。将这个脚本添加到Hierarchy里的ThirdPersonController里的PlayerArmature游戏物体上。

        2. 保持player被选中,在其Inspector中点击Add Component按钮,然后搜索并选择Audio Source。

 

探索声音脚本

        我们简单看看FootstepManager脚本。在Inspector中,我们可以看到它下面有三个下拉菜单,标记为grass,water和cave,分别对应三种不同的脚步声。这些下拉菜单表示的是多个脚步声的list。在后面我们会讨论原因。

        如果我们想更深入了解一下脚本里到底干了什么事,可以打开脚本,重点关注一下几点:

        OnControllerColliderHit方法会检测player当前行走在什么类型的表面上,它是通过检查关联的tag来实现这个功能的(这些tag我们会在后面添加)。

        当场景中发生了我们之前配置的动画事件,它会调用PlayStep方法,这个方法会随机从前面我们看到的不同类型的表面的脚步声list中选择其中一种出来进行播放。

给场景的不同表面打tag

        为了要让脚本知道该播放哪类声音,FootstepManager首先需要知道player当前站在哪种类型的表面上。我们可以通过使用tag来实现这个功能。

        1. 在场景视图中选择grass表面。在Inspector的顶部,选择Tag处的下拉菜单,然后在列表底部选择Add Tag。

        2. 在Tags and Layers中,选择“+”按钮,添加一个新的tag。将新tag命名为“Grass”,注意这里因为脚本需要使用,名字必须拼写正确。

        3. 再创建两个新的tag:Water和Cave。

        4. 在场景中再次选择grass表面,将tag设置为Grass。

        5. 选择场景视图中的water表面,将tag设置为Water。

        6. 选择场景视图中的cave,将tag设置为Cave。

添加脚步音频片段

        目前场景已经为脚步声脚本播放合适的声音做好了配置,接下来我们要将对应的音频片段添加进来了。之前我们说过,脚本的每种类型的Audio clip片段变量是一个列表,这个列表可以包含多个音频片段。脚本里会随机选择其中一个进行播放。这里为什么要用多个音频片段呢?如果我们只为每种类型的脚步声添加一个音频片段会怎样呢?

        1. 在Audio文件夹中,选择一种grass脚步声片段,将它拖动到FootstepManager脚本组件(和PlayerArmature关联)里的Grass Steps变量上。在列表中会自动出现这个音频片段。

        2. 重复上面的步骤,添加water和cave的脚步声片段。

        3. 运行场景,四处走动一下,控制角色分别在三种不同的表面上行走。

        刚开始我们可能还没什么感觉,但如果我们在场景上控制角色多走一会儿,我们会很快开始觉得脚步声没有什么变化。也许在切换到不同表面的时候,我们还能有点明显的感受,但最终我们都会注意到其实每种声音都是固定的一种,没有变化,会让人感到无聊。

        由于角色在实际的游戏中在各个场景里基本是保持不变的,可以确定的一件事是玩家最终肯定会察觉到这些单调的脚步声。脚步声只有一种,也不符合我们在真实世界中的体验。真实世界中,我们的每一步即便踩在相同的地面上,由于动作上的细微差异,可能重一点或轻一点,也可能是会多摩擦了一会儿地面,会导致声音有变化。虽然我们不可能在游戏中为一种脚步声添加成百上千种音频片段,但多几个片段随机选择总会比单一重复的一种片段要好得多。

        4. 在Audio目录中选择所有的grass脚步声片段,拖动它们到Inspector中FootstepManager脚本组件(和PlayerArmature关联)里的Grass Steps列表上。

        5. 重复上面的步骤添加water和cave对应的所有脚步声片段。

        6. 运行场景,控制角色在不同的平面上行走,听听看效果有什么不同。

探索:进一步定制脚步声

        在前面我们用了一些不同的脚步声音频片段来实现草地、水面和洞穴情况时的音效。实际在在Unity中替换这些音频片段非常简单。接下来我们可以去试试加入不同的音频片段,可以天马行空一下,比如角色踩到草地上时,我们播放羊叫的声音。

        除了Unity的资源商店,网络上还有很多地方提供了很不错的音效文件。比如:
OpenGameArt.orghttps://opengameart.org/Freesound - FreesoundFreesound: collaborative database of creative-commons licensed sound for musicians and sound lovers. Have you freed your sound today?https://freesound.org/        不管我们怎么拿到音频文件的,有一点需要我们注意的是我们所使用的音频的license。license类型会告诉我们对应音频文件的使用者所需要注意的地方,比如下面这个Open Game Art的例子(Public Domain):

        更多关于音频文件license的说明,可以参考一下这里:

用别人的音乐做背景音乐的各类短视频侵权了吗? - 知乎认同@广州版权产业服务中心 的说法,首先音乐是有版权的,无论是谁使用这段音乐都需要授权,不分个人用还…https://www.zhihu.com/question/277603079/answer/831076868        在Unity中,可以使用的音频文件格式有:aif, .wav, .mp3 以及.ogg。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/503225.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CLIP : Learning Transferable Visual Models From Natural Language Supervision

CLIP : Learning Transferable Visual Models From Natural Language Supervision IntroductionApproach Introduction 在raw的数据上自监督的训练模型,已经在NLP领域取得了革命性进展,这种模型需要收到硬件、数据的限制,但是能得到很好的迁…

算法 DAY55 动态规划11 392.判断子序列 115.不同的子序列

392.判断子序列 本题可以直接用双指针解法。但是本题是编辑距离的入门题目,故采用动态规划解法为后序“编辑距离”类题目打基础。 本题与最大子序列非常相似,但不同的是s必须连续,t可以不连续。 五部曲 1、dp[i][j] 表示以下标i-1为结尾的字…

Seata介绍

介绍: Seata的设计目标是对这个业务无侵入,因此从业务无侵入的2PC方案开始的,在传统的2PC的基础上演进的。它把一个分布式事务拆分理解成一个包含了若干分支事务的全局事务。全局事务的职责是协调其下管辖的分支事务达成一致性,要…

25.自定义注解

自定义注解 一、什么是注解 Annontation是Java1.5开始引入的新特征,中文名称叫注解。 它提供了一种安全的类似注释的机制,用来将信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。为程序…

大数据技术之SparkSQL——数据的读取和保存

一、通用的加载和保存方式 SparkSQL提供了通用的保存数据和数据加载的方式。根据不同的参数读取,并保存不同格式的数据。SparkSQL默认读取和保存的文件格式为Parquet。 1.1 加载数据 spark.read.load 是加载数据的通用方式。 如果读取不同格式的数据,可…

如何编译DPDK静态库

阅读前面文章https://blog.csdn.net/qq_36314864/article/details/130243348,知道了哪些dpdk文件可以在windows下生成。 打开vs,新建一个生成静态库工程,在生成的lib文件中找到D:\dpdk-21.07\build\lib D:\dpdk-21.07\build\drivers找到对应的文件,并按照路径,新建筛选项…

【Vue学习笔记7】Vue3中如何开发组件

重点学习:vue3.0之组件通信机制defineProps(组件接收外部传来的参数)、defineEmits(向组件外部传递参数)。 1. 评级组件第一版 简单的评级需求,只需要一行代码就可以实现: "★★★★★☆…

SLAM面试笔记(5) — ROS面试

目录 1 ROS概述 2 ROS通信机制 问题:服务通信概念 问题:服务通信理论模型 3 常见面试题 问题:roslaunch和rosrun区别? 问题:什么是ROS? 问题:ROS中的节点是什么? 问题&…

挠性航天器姿态机动动力学模型及PD鲁棒控制

挠性航天器姿态机动动力学模型及PD鲁棒控制 1挠性航天器姿态机动动力学模型2挠性航天器姿态机动PD鲁棒控制2.1 动力学模型及PD控制律2.2仿真模型2.3 控制程序2.4 被控对象程序2.5 绘图程序2.6 结果 1挠性航天器姿态机动动力学模型 2挠性航天器姿态机动PD鲁棒控制 2.1 动力学模…

【NLP开发】Python实现聊天机器人(ChatterBot,集成web服务)

🍺NLP开发系列相关文章编写如下🍺: 🎈【NLP开发】Python实现词云图🎈🎈【NLP开发】Python实现图片文字识别🎈🎈【NLP开发】Python实现中文、英文分词🎈🎈【N…

澳大利亚兔灾和——栈?

一.背景 1859年,当一位叫托马斯奥斯汀的农民收到英国老家送来的24只野兔并将它们放归农场的时候,他绝对意想不到,这些看似人畜无害的小兔子,竟为古老的澳洲大陆带来一场巨大的生态破坏。到20世纪初,澳大利亚的兔子数量…

操作系统内存管理(上)——内存管理基础

一、内存的基本知识 1.什么是内存?有什么作用? 内存可存放数据。程序执行前先放到内存才能被CPU处理——缓和CPU和硬盘之间的速度矛盾。 给内存的存储单元编址。如果计算机按字节编址,则每个存储单元大小为1字节。即1B8b(8个二进…

智能医院导航导诊系统,门诊地图导航怎么做?

现在很多医院都是综合化大型医院,有很多的科室,院区面积也逐渐扩大,一方面给病患提供了更为全面的医疗资源,另一方面,医院复杂的环境也给病患寻医问诊带来了一定的困扰。电子地图作为大家最喜闻乐见的高效应用形式&…

Python的socket模块及示例

13.2 socket模块 socket由一些对象组成,这些对象提供网络应用程序的跨平台标准。 13.2.1 认识socket模块 socket又称“套接字”,应用程序通常通过“套接字”向网络发出请求或应答网络请求,使主机间或一台计算机上的进程间可以通信。sock…

Android 路由框架ARouter源码解析

作者:小马快跑 我们知道在使用ARouter时,需要在build.config里配置: annotationProcessor com.alibaba:arouter-compiler:1.2.2并且知道annotationProcessor用来声明注解解析器,arouter-compiler用来解析ARouter中的各个注解并自…

代码管理记录(一): 码云Gitee代码提交和维护

文章目录 Gitee介绍登录地址代码提交 Gitee介绍 Gitee 是一个类似于GitHub的代码托管平台,是中国的开源社区和开发者社区。它为开发者提供了基于Git的代码托管、协作、部署、代码质量检测、漏洞扫描、容器镜像等服务,同时也提供了一系列的个人资料和社交…

gitlab使用docker简单快速部署

文章目录 前言一、下载gitlab镜像二、安装步骤1.创建docker-compose文件2. 启动及登陆 三、配置页面总结 前言 GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务。本文主要用来记录如何使用docker快速搭…

c#笔记-类成员

声明类 类可以使用帮助你管理一组相互依赖的数据,来完成某些职责。 类使用class关键字定义,并且必须在所有顶级语句之下。 类的成员只能有声明语句,不能有执行语句。 class Player1 {int Hp;int MaxHp;int Atk;int Def;int Overflow(){if (…

七大排序算法一文通(易懂图解+优化代码)

目录 1.直接插入排序 2.希尔排序 3.选择排序 4.堆排序 5.冒泡排序 6.快速排序 6.1 递归实现——Hoare版 6.2 递归实现——挖坑法 6.3 非递归实现 6.4 优化 7.归并排序 7.1 归并排序——递归实现 7.2 归并排序——非递归实现 8.复杂度以及稳定性 1.直接插入排序 …

一列数到中位数的总距离最小

一列数到中位数的总距离最小 3554.二进制(二进制数的加减法-转化为十进制运算再将结果转回二进制3565.完美矩阵1824.钻石收藏家(经典双指针) 3554.二进制(二进制数的加减法-转化为十进制运算再将结果转回二进制 输入样例&#xff…