因之前一直在开发项目,断断续续写了一点博客,最后统一写了一下博客记录学习内容。
可以看到我的工作一直在进行。

目录
[1. 创建齿轮按钮 UI](#1. 创建齿轮按钮 UI)
[2. 创建使用说明面板 UI](#2. 创建使用说明面板 UI)
[3. 编写控制脚本](#3. 编写控制脚本)
[4. Inspector 中绑定组件](#4. Inspector 中绑定组件)
[5. 使用说明示例内容](#5. 使用说明示例内容)
一、识别内容语音读取
通过手机摄像头识别一个现实世界中的物体,如显示器、鼠标等:
-
利用百度图像识别 API 识别出中文名称;
-
使用百度翻译 API 翻译成英文;
-
使用 Android 系统自带 TTS 播放英文读音;
-
在 UI 上显示识别结果,并 10 秒后自动清除。
技术 | 用途 |
---|---|
Unity 2022.3 | 主引擎 |
Vuforia Engine | AR识别、摄像头控制 |
百度 AI 平台 | 图像识别 + 翻译 |
安卓 TTS | 英文读音播放 |
TextMeshPro | 结果显示 UI |
Newtonsoft.Json | JSON 解析 |
修改之前的脚本
1.ARRecognitionController.cs
cs
using UnityEngine;
using System.Collections;
using TMPro;
using Newtonsoft.Json.Linq;
using System.IO;
public class ARRecognitionController : MonoBehaviour
{
public CameraCapture cameraCapture;
public BaiduAuth auth;
public BaiduObjectRecognition recognition;
public BaiduTranslate translator;
public TextMeshProUGUI resultText;
public TTSController ttsController;
public void StartRecognition()
{
StartCoroutine(auth.GetAccessToken(() =>
{
StartCoroutine(DelayedRecognition());
}));
}
IEnumerator DelayedRecognition()
{
yield return new WaitForSeconds(0.3f);
StartCoroutine(StartRecognitionFlow());
}
IEnumerator StartRecognitionFlow()
{
resultText.text = "识别中...";
Texture2D img = cameraCapture.CaptureImage();
if (img == null)
{
Debug.LogWarning("截图失败!");
resultText.text = "无法捕获图像";
yield break;
}
byte[] imageData = img.EncodeToJPG();
string imageBase64 = System.Convert.ToBase64String(imageData);
Debug.Log("上传图像Base64长度: " + imageBase64.Length);
string savePath = Path.Combine(Application.persistentDataPath, "captured.jpg");
File.WriteAllBytes(savePath, imageData);
Debug.Log("截图已保存到: " + savePath);
yield return recognition.RecognizeObject(img, json =>
{
Debug.Log("百度物体识别返回: " + json);
var result = JObject.Parse(json);
if (result["result"] != null && result["result"].HasValues)
{
string chineseName = result["result"][0]["keyword"].ToString();
Debug.Log($"识别结果: {chineseName}");
StartCoroutine(translator.Translate(chineseName, translationJson =>
{
Debug.Log("百度翻译返回: " + translationJson);
var transResult = JObject.Parse(translationJson);
string english = transResult["trans_result"][0]["dst"].ToString();
Debug.Log($"翻译结果: {english}");
resultText.text = $"{english}\n{chineseName}";
ttsController.Speak(english); // 播放英文语音
StartCoroutine(ClearResultTextAfterDelay(10f)); // 显示 10 秒后清空
}));
}
else
{
Debug.LogWarning("未识别出任何物体!");
resultText.text = "未识别出物体";
StartCoroutine(ClearResultTextAfterDelay(10f));
}
});
}
// 自动清除文本协程
IEnumerator ClearResultTextAfterDelay(float delay)
{
yield return new WaitForSeconds(delay);
resultText.text = "";
}
}
注意:TTSController 是挂在另一个空物体上的脚本,需要通过 public TTSController ttsController;
引用并在 Inspector 拖入。
2.TTSController.cs
cs
using UnityEngine;
public class TTSController : MonoBehaviour
{
AndroidJavaObject ttsObject;
void Start()
{
#if UNITY_ANDROID && !UNITY_EDITOR
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject context = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaClass ttsClass = new AndroidJavaClass("android.speech.tts.TextToSpeech");
ttsObject = new AndroidJavaObject("android.speech.tts.TextToSpeech", context, new TTSListener());
#endif
}
public void Speak(string message)
{
#if UNITY_ANDROID && !UNITY_EDITOR
if (ttsObject != null)
{
ttsObject.Call<int>("speak", message, 0, null, null);
}
#endif
}
// 内部监听器类(可为空)
class TTSListener : AndroidJavaProxy
{
public TTSListener() : base("android.speech.tts.TextToSpeech$OnInitListener") { }
public void onInit(int status)
{
Debug.Log("TTS 初始化状态:" + status);
}
}
}
注意:Unity 编辑器中无法播放,需真机测试。
二、点击齿轮按钮弹出使用说明界面
实现:点击右上角齿轮图标,弹出一块"使用说明"界面,并且可以关闭。引导用户进行操作。
实现以下逻辑:
-
场景右上角有一个齿轮图标(代表"设置")
-
用户点击齿轮后,弹出一个使用说明的 UI 面板
-
面板中包含简单的说明文字与一个关闭按钮
-
点击关闭按钮后,面板隐藏
开发步骤
1. 创建齿轮按钮 UI
在 Canvas 下创建一个按钮(UI → Button):
-
将其命名为
GearButton
-
替换默认按钮图片为一个齿轮图标(建议 PNG 格式透明背景)

- 设置位置为右上角(可以使用
Anchor Preset
设置为 Top-Right)
2. 创建使用说明面板 UI
在 Canvas 下再创建一个 Panel,命名为 InstructionsPanel
:
-
设置背景颜色为半透明灰色
-
添加一个
TextMeshPro
用于显示使用说明内容 -
添加一个关闭按钮
CloseButton
,可以是 "X" 图标(找一个图标即可)
注意:在 Hierarchy 中选中
InstructionsPanel
,取消勾选勾选框 ,让它在启动时默认隐藏(等同于SetActive(false)
)。
3. 编写控制脚本
新建脚本 GearSettingsUI.cs
,实现点击按钮的显示/隐藏逻辑:
cs
using UnityEngine;
using UnityEngine.UI;
public class GearSettingsUI : MonoBehaviour
{
public GameObject instructionsPanel;
public Button gearButton;
public Button closeButton;
void Start()
{
instructionsPanel.SetActive(false); // 初始隐藏
gearButton.onClick.AddListener(ShowInstructions);
closeButton.onClick.AddListener(HideInstructions);
}
void ShowInstructions()
{
instructionsPanel.SetActive(true);
}
void HideInstructions()
{
instructionsPanel.SetActive(false);
}
}
4. Inspector 中绑定组件
把对应的 UI 拖入:
-
gearButton
→ 齿轮按钮 -
instructionsPanel
→ 说明面板 -
closeButton
→ 面板里的关闭按钮
5. 使用说明示例内容
在 BodyText
中写入我的内容:
-
拖动模型旋转视角
-
捏合手势放大缩小
-
点击物体查看详情
-
点击"返回"退出体验
