您的位置:首页 > 移动开发 > Unity3D

#游戏unity-音之国度#实现语音控制

2017-05-22 23:06 1306 查看

#游戏unity-音之国度#实现语音控制

纯原创,转侵删!用于交流学习,请不要用于商业用途

语音控制的基础是语音识别,而语音识别又分为大致如下几个阶段:初始化->开始录音->结束录音->上传音频->语言识别。建议同学可以去看团队中朋友的博客进行学习语音识别的详细解释 http://blog.csdn.net/qq_33999892 这样我的博客也比较容易看懂;这里就不做赘述了。

好了,现在我们已经大致了解了腾讯语音识别技术的代码中的原理,以及对音频文件的处理。现在我们将相关的脚本导入进我们的“音之国度”工程,编写语音控制的脚本。

先展示几张我们的项目图片啦^. ^

Game视图中——



Scene中——



- UI中的按钮浅析

这个是个手机游戏,但为了调试更方便,就在PC端上进行测试,为了方便控制更好的调试,我在界面上放置了三个UI按钮,用来分步的进行语音控制,便于观察控台的输出和调试程序。如图:(简单的UI按钮)



考虑到有些朋友是自学unity,对UI系统不太熟悉,我就简单讲解一下Button事件的添加吧。(以“开始录音”按钮为例)

首先在Hierarchy视图中右键,点选UI中的Button组件,就会看到出现了一个canvas和eventsystem(这个不用管是用来协助UI系统的不可以删掉哦),而Button作为canvas的子物体出现了;点选Button,在Inspector视图中找到on Click(),是很方便的方法,直接在下面添加你想要调用的脚本中的方法,这样就可以作为Button点选后的点击事件进行响应啦。如图:



注意:这个脚本中的方法一定要声明为public的,否则会找不到的。

- 语音控制的脚本实现

1.主要的属性声明

SoundEngine t;
string s = "123456";
string save = Application.dataPath + "/d.dat" ;
GameObject role;
Animation anim;
string reallys;


第一行是建立了声音系统的实例t(不懂得可以看同组朋友博客中的完整代码【网址已在开头标出】,有问题还可以留言);字符串s是为了给多名玩家同时使用的时候传递的一个参数,这里可以自定义随意设置;save是储存数据的路径,用来声明存储数据的文件和位置;接下来是unity中的两个属性声明,物体和动画组件;字符串reallys是真正录音得到的需要进行处理的字符串。

[HideInInspector]
public stringsystem ss;
public int attackinstruct;
public int runinstruct;
public int laugeinstruct;
string[] testarray = { "攻击", "fire", "上啊", "公鸡", "攻级" };


testarray是在测试是自定义的一个字符串数组,存放语音命令,用来与表格中准确的命令进行配对比较。

2. 初始化

在Start()方法中(运行后进行一次初始化 注意与Update()的区别)

role = GameObject.Find("TestACT2");
anim = GameObject.Find("TestACT2").GetComponent<Animation>();

GameObject.Find("GameObject").GetComponent<SoundEngine>().Init(s);
ss = new stringsystem();
attackinstruct = ss.InsertInstruct();
runinstruct = ss.InsertInstruct();
laugeinstruct = ss.InsertInstruct();


将role声明为角色物体,anim是角色物体上的动画Animation组件

第三行代码,是找到挂在角色物体上的SoundEngine脚本,并执行其中的Init(s)方法(这是SoundEngine的初始化方法)

string testpath = Application.dataPath + "/1.xlsx";
List<DepenceTableData> listdata = ExcelLoad.ExcelLoad.Load(testpath);
foreach (DepenceTableData dtd in listdata)
{
Debug.Log(dtd.instruct + " " + dtd.word);
Insert_depence(dtd.instruct, dtd.word);
}
}


这个部分的遍历是一定要有的是必写代码,”/1.xlsx”是我们自己定义的有效指令表格文件。

3. 新命令的插入

书写Insert_depence方法,简单的进行新命令的插入。先去表格中遍历,是否有可以执行的命令,没有再插入。(详细代码在文末)

4. 语音控制动画

在Update()中书写,保证每一帧都可以进行调用

关于控制动画播放的代码——

anim.Play("idle");


还有,就是语音的采集、停止、处理与语音识别脚本中方法的传参与衔接也是需要特别注意的,一个不小心就会出错。

完整源码:我添加了详细的注释,有问题的可以留言交流

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GVoice_Sound;
using ExcelLoad;
using STRINGTOINSTRUCT;
using gcloud_voice;

public class SaveSound : MonoBehaviour
{

SoundEngine t;
string s = "123456";
string save = Application.dataPath + "/d.dat" ;
GameObject role;
Animation anim;
string reallys;//真正录音得到的字符串

[HideInInspector]
public stringsystem ss;
public int attackinstruct;
public int runinstruct;
public int laugeinstruct;
string[] testarray =
bfcd
{ "攻击", "fire", "上啊", "公鸡", "攻级" };
// Use this for initialization
void Start()
{

role = GameObject.Find("TestACT2");
anim = GameObject.Find("TestACT2").GetComponent<Animation>();

GameObject.Find("GameObject").GetComponent<SoundEngine>().Init(s);
ss = new stringsystem();
attackinstruct = ss.InsertInstruct();
runinstruct = ss.InsertInstruct();
laugeinstruct = ss.InsertInstruct();
//以下这个部分必须要有
string testpath = Application.dataPath + "/1.xlsx";
List<DepenceTableData> listdata = ExcelLoad.ExcelLoad.Load(testpath);
foreach (DepenceTableData dtd in listdata)
{
Debug.Log(dtd.instruct + " " + dtd.word);
Insert_depence(dtd.instruct, dtd.word);
}
}

// Update is called once per frame
void Update()
{
anim.Play("idle");
GameObject.Find("GameObject").GetComponent<SoundEngine>().Update();
}

public void Begin()
{

Debug.Log("开始录音");
GameObject.Find("GameObject").GetComponent<SoundEngine>().Start_Recording(save);//传入的参数是你想要它储存数据的一个路径位置

}
public void Stop()
{

Debug.Log("停止录音");
reallys = GameObject.Find("GameObject").GetComponent<SoundEngine>().End_Recording();

}
public void Done()
{
Debug.Log("开始处理");
string s1;//就是作为一个找到temp的中介
s1 = GameObject.Find("GameObject").GetComponent<SoundEngine>().translation(reallys);

float temp = 0.0f;
int tempi = 0;
tempi = ss.Find(s1, ref temp);
Debug.Log(s1);

if (tempi == attackinstruct)
{
Debug.Log("attack " + temp.ToString());
anim.Play("attack");

}
if (tempi == runinstruct)
{
Debug.Log("run " + temp.ToString());
anim.Play("walk");

}
if (tempi == laugeinstruct)
{
Debug.Log("lauge " + temp.ToString());
anim.Play("die");
}

}
void Insert_depence(string instruct, string word)
{
int _instruct = -1;
switch (instruct)
{
case "attack":
_instruct = attackinstruct;
break;
case "run":
_instruct = runinstruct;
break;
case "lauge":
_instruct = laugeinstruct;
break;
}
if (_instruct != -1)
ss.Insert_Index(_instruct, word);
}
}


以上,已经可以通过语音控制实现与角色的交互。

期待下一篇博主的博客干货吧~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息