48小时|我用Cocos+HarmonyOS NEXT做了一个实时 3D 汽车AI销售助理系统!

精彩 HarmonyOS NEXT 创意灵感优化

项目背景

项目灵感源于二喵在商场看车时,路过某4S店,店中一共2辆车,被人群围得密密麻麻,销售很难照护到每一个人,询问一些细节时,销售需要拿出 PAD 确认半天。

521e56642899797cf881588c44a7659b.jpeg

二喵想,同样是 PAD,如果能给等候的用户各配置一个,那用户可以在等候时进行360无死的看车,同时支持多模态的互动,用户更可以把自己定制的车型投影到线下,提供炫酷的Z时零售体验。

基于 HarmonyOS NEXT 的 AI 能力

恰逢 HarmonyOS NEXT 发布,二喵在参加极客松期间,花48小时,制作了一款基于 HarmonyOS NEXT 的汽车销售智能体。美术、策划、程序都是二喵一人完成,二喵计划将之开源

这个项目有3个目标:

  • 解决看车难:不排队,不等人;360度无死角看车,解决线下看车难的问题。

  • 解决沟通难:大数据更懂用户喜好,有助于提高销售转化率。

  • 解决定制难:多模态 AIGC,从内饰到车漆都支持UGC生成,满足用户无限需求。

  • 解决售后难:通过 HarmonyOS 元服务卡片追踪、同步订车信息,提升留存。

技术选型

前端采用了 Cocos Creator 3.8 版本。由于 Cocos 使用 TypeScript 作为脚本语言,与 NEXT 的 ArkTS 通信非常方便,因此可以通过 TypeScript 跨线程通信。同时由于 Cocos 采用 C++ 和 TS 双核引擎,可以保证在 NEXT 上的性能表现。

this.uiPort = globalThis.uiPort;
    this.uiPort.on('onASR', (text) => {
     console.log("cocos info onASR"+text)
      globalThis.startMic(text);
    });
    this.uiPort.on('endASR', (text) => {
      globalThis.endMic(text);
      console.log("cocos info endASR"+text)
    });

HarmonyOS NEXT 的新能力应用

这次 NEXT 更新了很多 AI 能力,如离线语音识别离线文字转语音。这两者都可以轻松在 Cocos 的 TS 代码层调用 NEXT 能力,也可以在 ArkTS 中使用 Cocos 的 TS 方法。

使用 API 11 端侧 ASR 和 TTS 服务,可以做到:

  • 减少了服务端两次 Post 请求 ASR 和 TTS。

  • 减少了三次音频文件上下行传输。

  • 整体请求时间降低40%。

  • 基于 OS 级服务,无任何额外费用。

尤其是 ASR 语音识别,由于传统的 ASR 识别延迟较高,借助 HarmonyOS NEXT 的离线语音识别,可以节省大量网络传输时间。

5416be6e013413674ed9e0ef8c3c596e.jpeg

同时 NEXT 的 ASR 和 TTS 都是 OS 层面的,在发热优化上相当不错。


在线SDK离线SDKNext OS服务
延迟
质量
发热

HarmonyOS NEXT 从 OS 层面降低了开发者的 AI 开发运营成本。

性能优化

HarmonyOS 主动发热优化

长时间连续使用ASRTTS,仍可能存在发热问题。这里主要借助 HarmonyOS 自带的电池性能发热分析,制定了性能优化策略。

  • 使用 ASR 时,前端会主动降低逻辑和渲染帧率,以 30FPS 执行渲染,5-15FPS 执行部分逻辑,降低前端的开销。

  • 定时器每30秒查询一次发热情况,如用户长期不使用且发热较高,会降低帧率到 30FPS,并冻结部分逻辑,直到用户触摸屏幕。

  • 同材质 Mesh 按需合并,减少 Drawcall。

  • 车门的 Mesh 比较多,进行了多材质合并,减少动画时的 RTS 开销,对半透明的玻璃单独处理。

  • 汽车 Mesh 分组,使用开销较低的 Planar Reflection,车底和内饰做了 RT 相机的剔除。

cf459d1226397a580f4026608d550015.jpeg

Prompt 优化

模型使用了两种,分别是 GPT4o-mini 和 Qwen Plus,效果相似,但 GPT4o-mini 整体速度更快。

你是问界M9的中文智能销售,判断用户意图并只回答与汽车有关的问题${knowledge}。
用户问你问界M9相关问题,请回答在90字内。
用户想查看后备箱或者打开车门,回答“正在打开后备箱”或“正在打开车门”。
用户想改变车漆颜色或需要推荐车漆颜色,回答“车漆:”+颜色的RGB值,例如红色车漆,“车漆:255,0,0”。
用户想改变内饰颜色或需要推荐内饰颜色,回答“内饰:”+颜色的RGB值,例如红色内饰,“内饰:255,0,0”。
用户想个性化车漆,只把个性化的内容翻译成英文prompt,返回“custom paint:”+翻译,例如“我想要小狗的车漆”,“custom paint:dog paint”。
用户想自定义或播放音乐,返回“播放音乐”。

用户输入:前端检测到用户提问度、速度、价格、配置等词时,会加入额外的知识库,否则使用通用知识库。

数据返回:

if (json != null && json[0]!= null) {
if (json) {
this.quickBox.updataBox();
const r = json[0].trim();
const q = json[1].trim();
if (/(后备箱)/.test(r)&& /打开/.test(r)) {
carCtrl.ins.openBack();
aiChat.createChat(replayName, json[0], index);
globalThis.tts&&globalThis.tts.speak(json[0]);
} else if (/(车门|侧门)/.test(r)&& /打开/.test(r)) {
console.log("车门");
carCtrl.ins.openSide();
aiChat.createChat(replayName, json[0], index);
globalThis.tts&&globalThis.tts.speak(json[0]);
} else if (/(车漆:)/.test(r)) {
const color = this.extractRGB(r);
console.log("changed paint rgb to "+color);
carCtrl.ins.setCarPaintColor(color);
aiChat.createChat(replayName, "已为您生成个性化车漆颜色", index);
globalThis.tts&&globalThis.tts.speak("已为您生成个性化车漆颜色");
} else if (/(内饰:)/.test(r)) {
const color = this.extractRGB(r);
console.log("changed inner rgb to "+color);
carCtrl.ins.setInnerColor(color);
carCtrl.ins.state = 0;
carCtrl.ins.enterInner();
aiChat.createChat(replayName, "已为您定制了个性化颜色内饰", index);
globalThis.tts&&globalThis.tts.speak("已为您定制了个性化颜色内饰");
} else if (/(播放音乐)/.test(r)) {
carCtrl.ins.playBGM();
aiChat.createChat(replayName, json[0], index);
globalThis.tts&&globalThis.tts.speak(json[0]);
} else if ((/(个性化)/.test(q)&& /车漆/.test(q))||(/custom paint/.test(r))) {
const res = r.replace(/custom paint:/gi, '');
aiChat.createChat(replayName, "正在为您生成个性化车漆,请稍等", index);
globalThis.tts&&globalThis.tts.speak("正在为您生成个性化车漆,请稍等");
aa.ui.get(ui.WaitView);
this.scheduleOnce(()=>{
aiChat.createChat(replayName, "个性化车漆生成中...", index);
globalThis.tts&&globalThis.tts.speak("个性化车漆生成中...");
aa.ui.put(ui.WaitView);
},2.1);
console.log("cocos info + prompt"+res);
const base64 = await Net.fetchBase64(res);
if(base64){
aa.sound.play("magic",1);
const tex = await aa.utils.createTexWithBase64(r,base64);
carCtrl.ins.reSkin(tex);
aiChat.createChat(replayName, "已为您定制了个性化图案车漆", index);
globalThis.tts&&globalThis.tts.speak("已为您定制了个性化图案车漆");
}
} else {
aiChat.createChat(replayName, json[0], index);
globalThis.tts&&globalThis.tts.speak(json[0]);
}
}
}

多模态优化

  • SD 多模态文生图:对每次生成的图片做指针存储,生成新图片后,释放老图片的内存和缓存。

  • Suno 文生音乐:新音乐生成后,释放之前的音乐。目前 Suno 不支持 API,因此使用了该仓库。

新的优化方向

HarmonyOS NEXT 凭借其开发便捷性和强大的新 AI 能力,整体开发一个汽车 AI Agent 还是挺方便的,为用户和开发者带来前所未有的便利和创新。

后续二喵也会继续优化这个项目,新增:

  • AI 天空盒生成,提供更多背景选择。

  • 优化线程通信,减少 GC。

  • 优化渲染效果。

  • 投影仪投屏,线下联动快闪。

预计会在10月底(NEXT Beta 公测后)开源。

764b9b85bfbef1da6d5e8c395e713b42.jpeg

感谢二喵带来的分享,大家可以在二喵的公众号中,查看更多精彩内容。

你可以使用Cocos Creator和JavaScript来编写一个AI跟踪敌人的脚本。以下是一个简单的示例: 首先,你需要在场景中创建一个敌人节点和一个玩家节点,并将它们添加到场景中。 然后,创建一个新的脚本组件并将其附加到敌人节点上。在脚本组件中,你可以使用Cocos Creator提供的API来实现AI跟踪敌人的逻辑。 下面是一个示例代码: ```javascript cc.Class({ extends: cc.Component, properties: { player: { default: null, type: cc.Node }, speed: 100, // AI移动速度 }, onLoad() { // 在游戏开始时,启动AI跟踪逻辑 this.schedule(this.trackPlayer, 0.1); }, trackPlayer() { // 获取敌人和玩家的位置 let enemyPos = this.node.position; let playerPos = this.player.position; // 计算敌人指向玩家的向量 let direction = playerPos.sub(enemyPos); // 标准化向量并乘以速度得到移动的位移 let distance = direction.normalize().mul(this.speed * 0.1); // 更新敌人的位置 this.node.setPosition(enemyPos.add(distance)); }, }); ``` 在上述示例代码中,我们定义了一个`player`属性来引用玩家节点,并设置了敌人的移动速度。在`onLoad`方法中,我们使用`schedule`方法来定时调用`trackPlayer`方法,以实现敌人的跟踪。 在`trackPlayer`方法中,我们获取敌人和玩家的位置,计算敌人指向玩家的向量,并将其标准化。然后,我们将标准化后的向量乘以速度得到移动的位移,并将其应用到敌人节点的位置上。 这只是一个简单的示例,你可以根据你的需求进行修改和扩展。希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值