diff --git a/app/note/design_doc b/app/note/design_doc
index 023133b..970e838 100644
--- a/app/note/design_doc
+++ b/app/note/design_doc
@@ -303,4 +303,65 @@ https://tianchi.aliyun.com/dataset/93864
- 将 tuanjieLibrary/build.gradle 替换为完整的 Android library 模块构建文件(apply plugin: 'com.android.library'),
参考 launcher/build.gradle 的配置(compileSdkVersion、ndkVersion、ndkPath、aaptOptions、buildTypes 等),
并在 dependencies 中添加 implementation files('libs/unity-classes.jar')。
- - 注意:每次从 Tuanjie 重新导出后都需要重新替换该文件。
\ No newline at end of file
+ - 注意:每次从 Tuanjie 重新导出后都需要重新替换该文件。
+
+14. 从 Unity 导出 Android 项目(IL2CPP)推荐步骤
+ 下面按 Unity 2021/2022+ 通用流程写(菜单名可能略有差异,但逻辑一致)。
+
+ 1. 切到 Android 平台
+ File → Build Settings…
+ 左侧选中 Android
+ 若未切换过,点 Switch Platform(等切换完成)
+ 2. Player Settings(Android)
+ Build Settings 窗口里点 Player Settings…(或 Edit → Project Settings → Player)
+
+ 选中 Android 图标(或 Android 标签页)
+
+ 在 Other Settings 里检查并设置:
+
+ Scripting Backend:选 IL2CPP
+ Target Architectures:勾选 ARM64(你现在 app 的 abiFilters 也是 arm64-v8a,要一致)
+ Minimum API Level:与你们 Android 工程要求一致(你工程 minSdk 22,Unity 不要设得更高除非你有意为之)
+ (可选但常见)Publishing Settings / Keystore:导出后若要直接装真机,后面 Build 时可用 debug;发版再配正式签名。
+
+ 3. 选择导出方式
+ 在 Build Settings:
+
+ Export Project ✅ 勾选(你们要集成到现有 Android Studio 工程,必须勾)
+ Development Build:调试可开,发版关
+ 4. Export 输出目录
+ 点 Export(不要只点“生成文件夹”就关掉),选一个空目录或新版本目录,例如:
+
+ D:\unity_export\MyProject_Android_IL2CPP_20260424\
+
+ 等 Unity 完整跑完(控制台无失败)。
+
+ 5. 在导出结果里确认 libil2cpp.so
+ 在导出根目录里找 unityLibrary(或你们模块名):
+
+ unityLibrary\src\main\jniLibs\arm64-v8a\libil2cpp.so
+ 同目录通常还有 libmain.so、libunity.so 等
+ 若这里仍然没有,再回到 Player Settings → Android → Scripting Backend 逐项核对(尤其是是否被 Override 成 Mono)。
+
+ 6. 集成到你们 digital_person 工程
+ 原则:同一轮 Export 的 jniLibs/arm64-v8a 整包拷贝到你们 tuanjieLibrary/src/main/jniLibs/arm64-v8a/(或你们实际使用的 Unity module),不要“只替换较新文件”,也不要混两次导出的 so。
+
+15. Unity导出安卓工程目录之后,找不到 libil2cpp.so,可以通过先不export,先编译出apk,得到这个so,然后复制到对应的目录下:
+
+ power shell 命令
+ # 源文件路径
+ $source = "C:\Users\42087\My project\Library\Bee\Android\Prj\IL2CPP\Gradle\tuanjieLibrary\build\intermediates\stripped_native_libs\release\out\lib\arm64-v8a\libil2cpp.so"
+
+ # 目标路径(你的导出工程)
+ $targetDir = "D:\code\digital_person\tuanjieLibrary\src\main\jniLibs\arm64-v8a"
+
+ # 创建目标目录(如果不存在)
+ New-Item -ItemType Directory -Force -Path $targetDir
+
+ # 复制文件
+ Copy-Item -Path $source -Destination $targetDir -Force
+
+ # 验证复制成功
+ Get-ChildItem -Path $targetDir\libil2cpp.so | Select-Object Name, Length
+
+16. 有些Unity导出的问题,可以参考:https://blog.csdn.net/weixin_45774916/article/details/144171875
\ No newline at end of file
diff --git a/app/src/main/java/com/digitalperson/UnityDigitalPersonActivity.kt b/app/src/main/java/com/digitalperson/UnityDigitalPersonActivity.kt
index aa3e7cc..876bcc6 100644
--- a/app/src/main/java/com/digitalperson/UnityDigitalPersonActivity.kt
+++ b/app/src/main/java/com/digitalperson/UnityDigitalPersonActivity.kt
@@ -503,6 +503,10 @@ class UnityDigitalPersonActivity : UnityPlayerActivity(), LifecycleOwner {
val filteredText = ttsController.speakLlmResponse(finalText)
Log.d("UnityDigitalPerson", "LOCAL filtered: ${filteredText?.take(60)}")
if (filteredText != null) appendChat("助手: $filteredText")
+ // 本地 LLM 回复也要进入互动状态机:否则不会进入 WAITING_REPLY / PROACTIVE 的计时流程
+ val spoken = filteredText ?: finalText.trim()
+ maybeShowMatchedRefImage(spoken)
+ interactionCoordinator.onCloudFinalResponse(spoken)
}
localThoughtSilentMode = false
}
diff --git a/app/src/main/java/com/digitalperson/config/AppConfig.kt b/app/src/main/java/com/digitalperson/config/AppConfig.kt
index ced450e..8a29c09 100644
--- a/app/src/main/java/com/digitalperson/config/AppConfig.kt
+++ b/app/src/main/java/com/digitalperson/config/AppConfig.kt
@@ -9,7 +9,7 @@ object AppConfig {
const val SAMPLE_RATE = 16000
const val WINDOW_SIZE = 512
- const val SHOW_DEBUG_TEXT = true
+ const val SHOW_DEBUG_TEXT = false
const val USE_HOLD_TO_SPEAK = true // true: 按住说话, false: 传统按钮
object Tts {
diff --git a/app/src/main/java/com/digitalperson/interaction/BaseDigitalPersonCoordinator.kt b/app/src/main/java/com/digitalperson/interaction/BaseDigitalPersonCoordinator.kt
index 897a3bb..20b48a3 100644
--- a/app/src/main/java/com/digitalperson/interaction/BaseDigitalPersonCoordinator.kt
+++ b/app/src/main/java/com/digitalperson/interaction/BaseDigitalPersonCoordinator.kt
@@ -148,12 +148,13 @@ abstract class BaseDigitalPersonCoordinator(
* (i.e. after a cloud LLM response), NOT after greeting / farewell / proactive TTS.
*/
fun onTtsPlaybackCompleted() {
- // Let the controller advance its own timers (greeting/proactive/dlg all count as assistant speaking).
- controller.onAssistantTtsPlaybackCompleted()
if (pendingDialogueFinish) {
pendingDialogueFinish = false
controller.onDialogueResponseFinished()
}
+ // Let the controller advance its own timers after state transitions above.
+ // (greeting/proactive/dlg all count as assistant speaking)
+ controller.onAssistantTtsPlaybackCompleted()
}
fun isLlmInFlight(): Boolean = llmInFlight
diff --git a/app/src/main/res/layout/activity_unity_digital_person.xml b/app/src/main/res/layout/activity_unity_digital_person.xml
index caa728d..3e1c9a3 100644
--- a/app/src/main/res/layout/activity_unity_digital_person.xml
+++ b/app/src/main/res/layout/activity_unity_digital_person.xml
@@ -7,6 +7,27 @@
android:background="@android:color/transparent"
tools:context="com.digitalperson.UnityDigitalPersonActivity">
+
+
+
+
+ app:layout_constraintTop_toTopOf="parent"
+ tools:visibility="visible">
-
-
开始
结束
点击“开始”说话;识别后会请求大模型并用 TTS 播放回复。
- 你是一个特殊学校一年级的数字人老师,你的名字叫,小鱼老师,你的任务是教这些特殊学校的学生一些基础的生活常识,如生活语文,生活数学,生活适应等课程。和这些小学生说话要有耐心,一定要讲明白,尽量用简短的语句、活泼的语气来回复。你可以和他们日常对话和《教材》相关的话题。在生成回复后,请你先检查一下内容是否符合我们约定的主题。请使用口语对话的形式跟学生聊天。在每次回复的最前面,用方括号标注你的心情,格式为[中性、悲伤、高兴、生气、恐惧、撒娇、震惊、厌恶],例如:[高兴]同学你好呀!请问有什么问题吗?
+ 你是一个特殊学校一年级的数字人老师,你的名字叫,小鱼老师,你是女性,你的任务是教这些特殊学校的学生一些基础的生活常识,如生活语文,生活数学,生活适应等课程。和这些小学生说话要有耐心,一定要讲明白,尽量用简短的语句、活泼的语气来回复。你可以和他们日常对话和《教材》相关的话题。在生成回复后,请你先检查一下内容是否符合我们约定的主题。请使用口语对话的形式跟学生聊天。在每次回复的最前面,用方括号标注你的心情,格式为[中性、悲伤、高兴、生气、恐惧、撒娇、震惊、厌恶],例如:[高兴]同学你好呀!请问有什么问题吗?