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

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过渡动画的属性和出发布尔值的条件
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【OJ】牛客链表刷题

题目 1. 链表分割1.1 题目分析1.2 代码 2. 链表的回文结构2.1 题目分析2.2 代码 这里两道与链表有关的题目均来自牛客。 1. 链表分割 1.1 题目分析 因为这里代码不能选择用c语言写&#xff0c;所以选择用c,因为c兼容c。 题目要求分割链表&#xff0c;我们可以直接弄成两个带哨…

Codeforces Round 915 (Div. 2) D题 单调栈,特殊情况入手

Problem - D - Codeforces 目录 题意&#xff1a; 思路&#xff1a; 把0放后面&#xff1a; ———— 然后看懂下面思路&#xff0c;理解单调栈&#xff1a; 细节&#xff1a; 核心代码&#xff1a; 题意&#xff1a; mex指的是该数组缺的最小的自然数&#xff0c;例如…

2024最有发展潜力的代理项目!格行随身wifi代理项目分析测评,轻资产靠谱创业项目推荐

最近很多网友都有创业的想法&#xff0c;身边创业的朋友也不在少数&#xff0c;当然有成功的&#xff0c;也有亏的血本无归的。最近网上也有很多适合新手的创业或代理项目&#xff0c;什么单身经济啊&#xff0c;大健康啊还有创业圈一直在讨论的随身WiFi代理等。当然一些创投圈…

大文件的断点续传如何实现

断点续传 断点续传是一种数据恢复技术&#xff0c;主要用于在读取或发送数据时&#xff0c;因为网络问题、磁盘问题等原因导致数据传输中断。断点续传技术允许你在已经传输的数据基础上继续传输&#xff0c;从而节省数据传输时间。 断点续传通常用于文件传输过程中&#xff0c;…

由于找不到d3dcompiler_43.dll缺失,无法打开软件的解决方法分享

d3dcompiler43.dll是什么文件&#xff1f;为什么会出现丢失的情况&#xff1f;又该如何解决呢&#xff1f;本文将详细介绍d3dcompiler43.dll的作用和影响&#xff0c;并提供6个有效的解决方法。 一、d3dcompiler43.dll是什么文件&#xff1f; d3dcompiler43.dll是DirectX SDK…

SQL注入入门进阶_报错注入、延时注入、python脚本盲注

SQL注入入门进阶 学习目标 本篇文章入门SQL注入&#xff0c;除了回显的SQL注入还存在报错注入、布尔盲注和延时注入。如果sqlmap跑不出来的还可以使用burp intrude注入或者使用python编写脚本注入。 报错注入 concat() 函数的意思是讲&#xff0c;全部内容连成一个字符串&a…

书生·浦语大模型实战营第五节课笔记及作业

LMDeploy 大模型量化部署实践 1 大模型部署背景 1.1 模型部署及大模型特点 1.2 大模型部署挑战及方案 2 LMDeploy简介 2.1 核心功能-量化 2.2 核心功能-推理引擎TurboMind 2.1 核心功能-推理服务api server 3 动手实践及作业 按照文档LMDeploy 的量化和部署中的步骤在Intern…

【MIdjourney】一些材质相关的关键词

1.多维剪纸(Multidimensional papercut) "Multidimensional papercut"&#xff08;多维剪纸&#xff09;是一种剪纸艺术形式&#xff0c;通过多层次的剪纸技巧和设计来创造出立体感和深度感。这种艺术形式通常涉及在不同的纸层上剪裁不同的图案&#xff0c;并将它们…

鸿蒙开发-UI-布局-线性布局

鸿蒙开发-序言 鸿蒙开发-工具 鸿蒙开发-初体验 鸿蒙开发-运行机制 鸿蒙开发-运行机制-Stage模型 鸿蒙开发-UI 鸿蒙开发-UI-组件 鸿蒙开发-UI-组件-状态管理 鸿蒙开发-UI-应用-状态管理 鸿蒙开发-UI-渲染控制 鸿蒙开发-UI-布局 文章目录 前言 一、基本概念 二、布局子元素 1.子元…

大模型基础2

大模型基础2 第二章&#xff1a;大模型的能力 语言模型的适应性&#xff1a;从语言模型到任务模型的转化 语言模型转化为任务模型的过程称为"适应"&#xff1a; 任务的自然语言描述一组训练实例&#xff08;输入-输出对&#xff09; 进行适应的两个种方法&#xf…

OSI七层协议和五层协议

【 1 】互联网协议交互的基础 硬件设备 光缆 【 2 】OSI七层协议 物理层&#xff08;Physical Layer&#xff09;&#xff1a;负责传输比特流&#xff08;0和1&#xff09;以及物理连接的建立和维护。数据链路层&#xff08;Data Link Layer&#xff09;&#xff1a;提供可…

禅道下载安装及基本使用(项目周期管理)实施必会!!!

文章目录 前言&#xff1a;一、为什么要使用禅道&#xff1f;二、禅道的下载与安装 前言&#xff1a; 禅道的使用能使公司提高项目管理效率、促进团队协作、支持敏捷开发&#xff0c;并可根据具体需求进行个性化配置。 本文章博主将以一个项目周期来带你们了解禅道。 一、为什…

企业信息防泄漏管理的理念是什么?

在这个数字化的时代&#xff0c;信息数据的安全已经成为企业发展的关键要素。随着网络技术的飞速发展&#xff0c;信息安全的重要性日益凸显&#xff0c;它关乎企业的生死存亡。在企业的信息系统中&#xff0c;信息泄露是最常见和最严重的风险之一。因此&#xff0c;建立一套全…

django后台进行加密手机号字段,加密存储,解密显示

需求: 1 &#xff1a;员工在填写用户的手机号时&#xff0c;直接填写&#xff0c;在django后台中输入 2&#xff1a;当员工在后台确认要存储到数据库时&#xff0c;后台将会把手机号进行加密存储&#xff0c;当数据库被黑之后&#xff0c;手机号字段为加密字符 3&#xff1a;员…

Flutter编译报错Connection timed out: connect

背景&#xff1a;用Android Studo 创建了Flutter项目&#xff0c;编译运行报错java.net.ConnectException: Connection timed out: connect 我自己的环境&#xff1a; windows11 Android Studio Flutter 截图如下&#xff1a; 将错误日志展开之后&#xff1a; Exception…

银行家算法

文章目录 主要内容一.银行家算法1.需求分析 2.概要设计3.源代码代码如下&#xff08;示例&#xff09;: 总结 主要内容 一.银行家算法 1.需求分析 通过编写和调试一个系统动态分配资源的简单模拟程序&#xff0c;观察死锁产生条件&#xff0c;采用适当的算法&#xff0c;有效…

Java并发编程: 并发编程中的ExecutionException异常

一、什么是ExecutionException 在并发编程中在执行java.util.concurrent.Future实现类的get方法时&#xff0c;需要捕获java.util.concurrent.ExecutionException这个异常。Future.get()方法通常是要获取任务的执行结果&#xff0c;当执行任务的过程中抛出了异常&#xff0c;就…

WAF攻防相关知识点总结2-代码免杀绕过

WAF的检测除了有对于非正常的流量检测外还对于非正常的数据包特征进行检测 以宝塔为例 在宝塔的后台可以放置一句话木马的文件 宝塔不会对于这个文件进行拦截&#xff0c;但是一旦我们使用菜刀蚁剑等webshell工具去进行连接的时候&#xff0c;数据报中有流量特征就会被拦截 …

【十进制与二进制如何转换?推荐一个超好用的公式编辑器】

在计算机科学和电子工程中&#xff0c;二进制是一种非常重要的数字系统&#xff0c;因为它在数字处理和数据传输中被广泛使用。因此&#xff0c;理解如何将十进制数转换为二进制数是非常重要的。 可以使这个计算过程更加简单和快速。而且还可以用于其他数学方程式的编写和编辑。…

MAC磁盘空间不足怎么清理?MAC清理磁盘空间的五种方法

MAC磁盘空间不足怎么清理&#xff1f;当我们使用苹果MAC一段时间后&#xff0c;就会有大量的垃圾文件占用磁盘空间&#xff0c;例如系统缓存文件、应用程序缓存文件、备份和重复文件、旧版的应用程序及其部件等&#xff0c;为了不影响电脑的后续使用&#xff0c;我们需要经常清…