【unity】麦克风声音驱动,控制身体做出不同动作

news2025/2/22 8:28:52

1.在角色对象上挂在animator组件,并将动作控制器与其关联
在这里插入图片描述
2.在角色对象上挂在audio source组件。
3.新建voice control脚本,编写代码如下:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Animations;
public class VoiceControl : MonoBehaviour
{
    public Animator animator;
    public float volumeThreshold = 0f; // 调整为一个更合理的阈值
    private string talkingParamName = "Talk";
    public AudioSource audioLocal;
    private string device;
    private IEnumerator coroWaitMic;
    private const float coroutineLoggingIfDebug = 5f; // debug log ERROR every 5 seconds while audiodevice error
    const int loopLength = 5;
    const int sampleRate = 16000;
    // Start is called before the first frame update
    void Start()
    {
        // 设置初始动画状态为NotTalking
        
        audioLocal = GameObject.Find("xiaoyang").GetComponent<AudioSource>(); // 1 定位本地音频设备audioLocal
        if (Microphone.devices.Length <= 0)
        {
            Debug.LogError("没有麦克风或麦克风权限未打开");
            throw new Exception("没有麦克风或麦克风权限未打开");
        }
        else
        {
            device = Microphone.devices[0];//获取麦克风名 
        }
        StartMicrophone(device);
        animator.SetBool(talkingParamName, false);
    }
    // Update is called once per frame
    void Update()
    {
        float currentVolume = GetAverageAmplitude();
        Debug.Log($"Current Average Amplitude: {currentVolume}, Volume Threshold: {volumeThreshold}");
        // 根据音量大小切换Talk参数和动画状态
        // 根据当前音量大小决定是否切换动画状态
        if (currentVolume > volumeThreshold)
        {
            animator.SetBool("Talk", true);
            Debug.Log("true执行");
        }
        else
        {
            animator.SetBool("Talk", false);
            Debug.Log("false执行");
        }
    }
    private void StartMicrophone(string mic)
    {
        // Start and wait for the microphone to start recording data
        if (coroWaitMic != null)
            StopCoroutine(coroWaitMic);
        coroWaitMic = WaitForMic(device);
        StartCoroutine(coroWaitMic);
    } // end StartMicrophone()
    IEnumerator WaitForMic(string mic)
    {
        float timeCheck = Time.time;
        if (audioLocal == null)
        {
            Debug.LogWarning("[WaitForMic()] - AudioSource is not present...bailing...");
            yield break;
        }
        audioLocal.clip = Microphone.Start(mic, true, loopLength, sampleRate);
        // Let the Microphone start filling the buffer prior to activating the AudioSource.
        while (!(Microphone.GetPosition(mic) > 0))
        {
            if (Time.time - timeCheck > coroutineLoggingIfDebug)
            {
                Debug.Log("[WaitForMic()] - is waiting for the mic to record.");
                timeCheck = Time.time;
            }
            // Wait for Microphone to start gathering data.
            yield return null;
        }
        audioLocal.Play();
        audioLocal.loop = true;
    } // end WaitForMic() 录音设备开始录音


    private float GetAverageAmplitude()
    {
        float[] data = new float[sampleRate]; // 假设每次读取sampleRate个样本数据,实际项目中可以根据需要调整
        audioLocal.clip.GetData(data, 0); // 获取麦克风实时输入的数据

        float sumOfSquares = 0f;
        for (int i = 0; i < data.Length; i++)
        {
            float sampleValue = Mathf.Abs(data[i]); // 取绝对值计算振幅
            sumOfSquares += Mathf.Pow(sampleValue, 2); // 将样本平方累加,用于计算均方根(RMS)
        }
        float averageAmplitude = Mathf.Sqrt(sumOfSquares / data.Length); // 计算均方根得到平均振幅大小
        Debug.Log($"Current Average Amplitude: {averageAmplitude}, Volume Threshold: {volumeThreshold}");
        return averageAmplitude;
    }
}

4.将动作控制器关联到脚本上
在这里插入图片描述
5.设置音量阈值,使得当达到某个音量值时切换动画
在这里插入图片描述
6.在动作控制器中设置不同的动作状态
(1)添加没说话时和说话时的状态并添加自循环,使动作能够重复播放
在这里插入图片描述
(2)新建布尔参数,用于控制状态
在这里插入图片描述
(3)设置Notalking→talking过渡动画的属性和出发布尔值的条件
在这里插入图片描述
(4)设置talking→Notalking过渡动画的属性和出发布尔值的条件
在这里插入图片描述

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

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

相关文章

vue2 使用vuex状态管理工具 如何配置与搭建。

等我研究研究&#xff0c;下一期给大家出一个后台管理左侧侧边栏如何搭建的。 首先我们先下载一下 vuex包 yarn add vuex3 1.先导入我们需要的 Vue 和 vuex 2.注册vuex 3.创建vuex实例 4.导出store export default store 5.在main.js中导入并挂载到全局。 Vuex如何实…

C++编写、生成、调用so库详解(二)

我们上篇中主要讲了怎么去打包so库 C编写、生成、调用so库详解(一) 这篇我们就来说一些怎么调用so库 目录 1.调用符合JNI标准的so库 2.调用不符合JNI标准的so库 上面说了两种不同类型的so库,我们分别来看一下怎么调用这两种,在调用so库之前,我们先说一下直接调用上面写的C…

全球网络是如何互联的?

1.Internet 在之前的学习中我们知道了Internet和internet的区别&#xff0c;也知道了Internet目前是全球最大的网络&#xff0c;并且由很多规模不同的网络互联而成。到目前已经有超过90个国家接入了Internet&#xff0c;主机超过400万台&#xff0c;可以说Internet是全人类的信…

【Ubuntu18.04安装Labelme】

Ubuntu18.04安装Labelme 1 安装Anaconda并创建conda环境2 安装依赖3 安装Labelme4 安装验证 1 安装Anaconda并创建conda环境 Anaconda3安装教程&#xff1a;https://blog.csdn.net/dally2/article/details/108206234 "ctrlaltt"快捷键打开终端&#xff0c;创建conda…

gateway Redisson接口级别限流解决方案

文章目录 前言1. 计数器算法&#xff08;固定窗口限流器&#xff09;2. 滑动窗口日志限流器3. 漏桶算法&#xff08;Leaky Bucket&#xff09;4. 令牌桶算法&#xff08;Token Bucket&#xff09;5. 限流队列应用场景实现工具 一、Redisson简介二、Redisson限流器的原理三、Red…

利用 ChatGPT 高效搜索:举一反三的思考方式,高效查找解决方案

文章目录 基础思路举一反三基于我的已知推荐 Web 框架系统方案建议 - 让 ChatGPT 推断我的一些微末思考结论 本文只是我的一些尝试&#xff0c;基于 ChatGPT 实现系统化快速搜索某编程语言的特定领域相关包或者基于其他语言类推荐落地方案的尝试。 这篇文章中描述的方式不一定…

ABAP IDOC 2 XML

有个需求&#xff0c;外围系统希望我们给到一个IDOC 记录的样例&#xff0c;但是我们we02中并无法看到 就找了一个demo去直接展示IDOC内容 *&---------------------------------------------------------------------* *& Report Z_IDOC_TO_XML *&------------…

关于前端或者postman传递Date数据测试接口报错

错误&#xff1a; org.apache.ibatis.exceptions.PersistenceException: \r\n### Error querying database. Cause: java.lang.IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String\r\n### Cause: java.lang.IllegalArgumentException: invali…

服务器运维小技巧(一)——如何进行远程协助

服务器运维中经常会遇到一些疑难问题&#xff0c;需要安全工程师&#xff0c;或者其他大神远程协助。很多人会选择使用todesk或者向日葵等一些远控软件。但使用这些软件会存在诸多问题&#xff1a; 双方都需要安装软件&#xff0c;太麻烦需要把服务器的公钥/密码交给对方不知道…

Android WorkManager入门(二)

WorkManager入门 上一篇前言创建 WorkRequest并提交 定时的任务&#xff08;PeriodicWorkRequest&#xff09;配合约束使用定义执行范围失败后的重试为WorkRequest打上TAG其他取消方法 传参和返回参数总结参考资料 上一篇 Android WorkManager入门&#xff08;一&#xff09; …

权威认证!腾讯微搭入选Forrester《2023年第四季度中国专业开发人员低代码平台市场分析报告》

在Forrester近日发布的《The Low-Code Platforms For Professional Developers Landscape In China,Q4 2023》&#xff08;《2023年第四季度中国专业开发人员低代码平台市场分析报告》&#xff09;中&#xff0c;腾讯云成功入选。该报告通过对中国的低代码市场进行了深入的研究…

2018年认证杯SPSSPRO杯数学建模C题(第一阶段)机械零件加工过程中的位置识别全过程文档及程序

2018年认证杯SPSSPRO杯数学建模 基于轮廓特征的机械零件位置识别研究 C题 机械零件加工过程中的位置识别 原题再现&#xff1a; 在工业制造自动生产线中&#xff0c;在装夹、包装等工序中需要根据图像处理利用计算机自动智能识别零件位置&#xff0c;并由机械手将零件自动搬…

[Android] Android架构体系(1)

文章目录 Android 的框架Dalvik 虚拟机JNI原生二进制可执行文件Android NDK中的binutils Bionic谷歌考虑到的版权问题Bionic与传统的C标准库&#xff08;如glibc&#xff09;的一些不同 参考 Android 的框架 Android 取得成功的关键因素之一就是它丰富的框架集。 没有这些框架…

游卡:OceanBase在游戏核心业务的规模化降本实践

从 2023 年 9 月测试 OceanBase&#xff0c;到如今 3 个核心业务应用 OceanBase&#xff0c;国内最早卡牌游戏研发者之一的游卡仅用了两个月。是什么原因让游卡放弃游戏行业通用的 MySQL方案&#xff0c;选择升级至 OceanBase&#xff1f;杭州游卡网络技术有限公司&#xff08;…

WordPress设置回收站自动清理天数的插件Change Empty Trash Time

前面boke112百科跟大家分享的『WordPress回收站自动清空时间&#xff1f;如何关闭回收站或设置自动清理天数&#xff1f;』一文&#xff0c;就介绍了可以添加一行代码实现关闭或设置回收站自动清理时间&#xff0c;也可以通过安装Change Empty Trash Time插件来实现。 今天bok…

Jenkins-Pipeline

Pipeline 1 安装插件 2 新建一个 Pipline 工程 3 配置Pipeline 脚本 agent的使用可以参考这个文档 pipeline {agent anystages {stage(Build) { steps {echo Building project...}}stage(Test) { steps {echo Testing project...}}stage(Deploy) { steps {echo Deploying …

模具制造企业ERP系统有哪些?企业怎么选型适配的软件

模具的生产管理过程比较繁琐&#xff0c;涵盖接单报价、车间排期、班组负荷评估、库存盘点、材料采购、供应商选择、工艺流转、品质检验等诸多环节。 有些采用传统管理手段的模具制造企业存在各业务数据传递不畅、信息滞后、不能及时掌握订单和车间生产情况&#xff0c;难以对…

SD-WAN企业组网:实现高效、安全的跨国企业连接

在当今数字化时代&#xff0c;企业日益全球化&#xff0c;跨国办公成为常态。为了应对这一挑战&#xff0c;越来越多的企业选择采用先进的网络技术&#xff0c;其中SD-WAN&#xff08;软件定义广域网&#xff09;便是一种备受青睐的解决方案。 什么是SD-WAN企业组网&#xff1…

【LeetCode每日一题】2171. 拿出最少数目的魔法豆

2024-1-18 文章目录 [2171. 拿出最少数目的魔法豆](https://leetcode.cn/problems/removing-minimum-number-of-magic-beans/)思路&#xff1a; 2171. 拿出最少数目的魔法豆 思路&#xff1a; 对输入的数组进行排序&#xff0c;使得数组中的元素按照升序排列。初始化一个变量s…

易懂的方式讲解ARM中断原理以及中断嵌套方法

ARM有七种模式&#xff0c;我们这里只讨论SVC、IRQ和FIQ模式。 我们可以假设ARM核心有两根中断引脚&#xff08;实际上是看不见的&#xff09;&#xff0c;一根叫 irq pin, 一根叫fiq pin。在ARM的cpsr中&#xff0c;有一个I位和一个F位&#xff0c;分别用来禁止IRQ和FIQ。 先…