ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

新建工程写HoloLens 1程序:Artery场景下VS2017与HoloToolkit的GetTargetedObject问题排查与TaoToken配置

新建工程写HoloLens 1程序:Artery场景下VS2017与HoloToolkit的GetTargetedObject问题排查与TaoToken配置 1. 新建 HoloLens 1 工程时 GetTargetedObject 报错的真实场景如果你正在用 VS2017 打开一个 HoloLens 1 的新建工程导入 HoloToolkit 后想复刻 Artery 场景里的 gaze 加 gesture 交互结果一挂 CursorFeedback.cs 就报HoloToolkit.Unity.InputModule.Cursor 中不存在 GetTargetedObject()那你不是一个人。这个报错几乎每个从 HolographicAcademy 的 Gaze 例子过渡到 Gesture 例子的开发者都会撞上我第一次遇到时也以为是命名空间写错了查了半天才发现是 HoloToolkit 包里 Cursor.cs 的版本差异。先把场景说清楚。HoloLens 1 的开发环境是 Unity 2017.x 加 VS2017官方教程分两条线一条是 Origami 那种纯手势点击不需要额外导入包另一条是 HolographicAcademy210-Gaze 的 starting 文件夹里面带了完整的 HoloToolkit 包。问题就出在这里——只有 Gaze 例子的 starting 文件夹里有这个包后面 Gesture、Manipulation 这些例子里反而没有独立包你只能复用 Gaze 里那份。而 Gaze 那份 HoloToolkit 的 Cursor.cs 是精简版缺少 GetTargetedObject() 这个函数Gesture 例子里用的 Cursor.cs 才是完整版。所以当你把 Gesture 例子里的 CursorFeedback.cs 拖进自己的工程它调用Cursor.GetTargetedObject()时编译器在 Gaze 版 Cursor.cs 里找不到这个方法直接报错。这不是命名空间问题也不是引用丢失纯粹是两份 Cursor.cs 内容不一致。解决办法很直接把 Gesture 例子中 Cursor.cs 里 GetTargetedObject() 那段实现补到你工程的 Cursor.cs 末尾保存后重新编译报错立刻消失。这个场景还牵出两个新手常踩的坑。第一是三维物体的 Transform 操作从 Hierarchy 拖进来的物体Unity 会自动生成一个父文件夹真实模型以 Default 命名挂在下面。你要调角度或位置只动 Default 子物体的 Transform别碰父文件夹否则后面用 TapToPlaceParent 脚本时会出各种位置漂移和角度错乱很难排查。第二是碰撞体物体必须加 Box Collider而且不要勾 Is Trigger否则初始化后它不会悬在空中会直接坠到地面TapToPlaceParent 也没法把它放到任意平面上。这篇内容就是围绕这条真实开发链路展开的。我会先讲清楚 VS2017 加 HoloLens 1 新建工程的完整配置步骤再给出 HoloToolkit 导入和组件挂载清单然后重点拆解 GetTargetedObject 的补全与调试验证动作。同时因为现在很多团队会把语音、视觉这类服务调用统一走 API 通道管理我也会说明怎么用 TaoToken 把 Key 和 API 通道集中管起来避免在多个脚本里散落硬编码。适合谁看正在用 HoloLens 1 做 Artery 类交互场景、被 VS2017 编译报错卡住、想快速定位并解决构建与交互异常的开发者。2. TaoToken 前置准备统一 Key 与 API 通道管理在动手改 Cursor.cs 之前先把服务调用的通道理顺。HoloLens 1 工程里如果涉及语音识别、图像理解或者自定义的模型推理通常会在 C# 脚本里直接写 API 地址和 Key。工程一多Key 散落在各个文件里换环境时改到崩溃。TaoToken 的作用就是把这些调用统一到一个入口你只需要维护一份 Key 和 Base URL脚本里引用同一套配置。先明确三个核心信息后面所有配置都围绕它们展开项目值说明Base URLhttps://taotoken.net/api所有 API 请求的统一入口不加 UTMAPI Key在控制台生成形如sk-开头只显示一次务必保存Model ID按需选择例如对话类、代码类模型填在请求体里获取 Key 的路径是打开官网https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content进入控制台在 API Keys 页面新建一个 Key。控制台地址是https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewriteAPI Keys 页面是https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite。生成后复制保存页面刷新就看不到了。如果你只是想在 HoloLens 工程里验证模型调用是否通可以先用模型对话页面测一下https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite。这个页面能直接发请求确认 Key 和 Base URL 没问题再写进 Unity 脚本。对于长期做 HoloLens 交互开发、需要频繁调用模型能力的团队建议直接上 Coding Plan把额度、Key 和调用通道一起管起来https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite。这样你在 VS2017 里调试 C# 脚本时模型调用不会因为 Key 过期或额度不足中断。接入文档在https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite里面有完整的请求格式和参数说明。如果你用的是 Claude Code 这类工具做辅助开发Anthropic 兼容入口是https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite配置方式在文档里有写。这里要强调一点TaoToken 是统一的 API 通道管理服务不是让你绕过任何本地环境。HoloLens 1 的构建、部署、VS2017 编译这些步骤完全在本地完成TaoToken 只负责你工程里那些需要调用外部模型能力的请求。两者互不干扰别混在一起理解。配置好 Key 之后建议在 Unity 工程里建一个ApiConfig.cs把 Base URL、Key、Model ID 集中放进去其他脚本引用这个类。这样后面改配置只动一个文件也方便你在 VS2017 里做断点调试。具体写法在下一节的配置片段里给出。3. 可复制配置VS2017 工程、HoloToolkit 导入与 ApiConfig 片段这一节给出可以直接复制粘贴的配置。先讲 Unity 工程侧的设置再给 HoloToolkit 导入和组件挂载清单最后是 ApiConfig.cs 的完整代码。3.1 Unity 2017 工程基础设置新建工程时选 3D 模板然后按顺序改这几项打开Edit Project Settings Player在Other Settings里把Scripting Runtime Version设为.NET 4.6 EquivalentApi Compatibility Level设为.NET 4.6。这两项不改后面 HoloToolkit 的某些 API 会编译不过。在Publishing Settings里Capabilities勾选Microphone、SpatialPerception、InternetClient。Microphone 是语音交互用的SpatialPerception 是空间映射和 gaze 用的InternetClient 是你调用 TaoToken API 时必须的不勾的话 HoloLens 上运行时会直接拒绝网络请求。Quality Settings里把Pixel Light Count降到 2 以下HoloLens 1 的 GPU 性能有限阴影和实时光太多会掉帧。3.2 HoloToolkit 导入与组件挂载清单从 HolographicAcademy210-Gaze 的 starting 文件夹里找到 HoloToolkit 包拖进 Unity 的 Assets 目录。导入后确认目录结构里有HoloToolkit/InputModule/Scripts/InputSources和HoloToolkit/InputModule/Scripts/Cursor。场景里需要挂载的组件清单如下物体组件作用HoloLensCameraGazeManager管理 gaze 射线和命中检测HoloLensCameraGestureManager管理 tap、manipulation 手势InputManagerInputManager统一输入事件分发CursorCursor显示 gaze 光标CursorCursorFeedback光标状态反馈调用 GetTargetedObject三维物体 DefaultBox Collider碰撞检测不勾 Is Trigger三维物体 DefaultTapToPlaceParent放置到空间平面注意 CursorFeedback 挂在 Cursor 上而 Cursor 上的 Cursor.cs 就是需要补 GetTargetedObject() 的那个文件。3.3 ApiConfig.cs 完整片段在 Assets 下新建Scripts/ApiConfig.cs内容如下using UnityEngine; public static class ApiConfig { // TaoToken 统一入口不加 UTM public const string BaseUrl https://taotoken.net/api; // 在控制台生成的 Key替换成你自己的 public const string ApiKey sk-你的Key; // 按需选择模型 ID public const string ModelId 你的模型ID; public static string ChatEndpoint { get { return BaseUrl /v1/chat/completions; } } }如果你用 JSON 配置文件的方式管理可以在 StreamingAssets 下放taotoken.json{ base_url: https://taotoken.net/api, api_key: sk-你的Key, model_id: 你的模型ID, timeout_seconds: 30 }然后在 C# 里用JsonUtility读取。这种方式适合需要频繁切换环境的团队改 JSON 不用重新编译。3.4 Cursor.cs 补全 GetTargetedObject打开HoloToolkit/InputModule/Scripts/Cursor/Cursor.cs在类末尾补上这段public GameObject GetTargetedObject() { if (GazeManager.Instance null) { return null; } return GazeManager.Instance.HitObject; }保存后回到 VS2017重新编译。如果 CursorFeedback.cs 还报错检查它的命名空间引用是否包含HoloToolkit.Unity.InputModule。3.5 VS2017 生成设置在 Unity 里File Build Settings平台选Universal Windows PlatformTarget Device选HoloLensBuild Type选D3DSDK选Latest Installed。点Build生成 VS2017 解决方案用 VS2017 打开 sln配置选Release和x86部署到 HoloLens 或模拟器。4. 验证请求与成功结果GetTargetedObject 调试验证动作配置改完必须验证两件事一是 GetTargetedObject 在运行时能正确返回被 gaze 命中的物体二是 TaoToken 的 API 请求能通。分开验证避免混在一起排查。4.1 GetTargetedObject 运行时验证在 CursorFeedback.cs 的 Update 或 OnInputClicked 里加一行调试输出void Update() { GameObject target GetComponentCursor().GetTargetedObject(); if (target ! null) { Debug.Log(Gaze 命中物体: target.name); } }部署到 HoloLens 后用 Visual Studio 的Debug Attach to Process连上 HoloLens 进程看 Output 窗口。当你 gaze 到三维物体时应该打印出物体的名字比如Default。如果一直是 null检查 GazeManager 是否挂在 HoloLensCamera 上以及物体的 Box Collider 是否勾了 Is Trigger。我实测下来最常见的 null 原因是 GazeManager 的MaxGazeDistance设得太小默认 5 米如果物体在 6 米外就命中不了。改成 10 米再试。4.2 TaoToken API 请求验证在 Unity 里写一个简单的测试脚本用 UnityWebRequest 发请求using UnityEngine; using UnityEngine.Networking; using System.Collections; public class ApiTest : MonoBehaviour { IEnumerator Start() { string json {\model\:\ ApiConfig.ModelId \,\messages\:[{\role\:\user\,\content\:\ping\}]}; UnityWebRequest req new UnityWebRequest(ApiConfig.ChatEndpoint, POST); req.uploadHandler new UploadHandlerRaw(System.Text.Encoding.UTF8.GetBytes(json)); req.downloadHandler new DownloadHandlerBuffer(); req.SetRequestHeader(Content-Type, application/json); req.SetRequestHeader(Authorization, Bearer ApiConfig.ApiKey); yield return req.SendWebRequest(); if (req.result UnityWebRequest.Result.Success) { Debug.Log(API 返回: req.downloadHandler.text); } else { Debug.LogError(API 错误: req.error 响应: req.downloadHandler.text); } } }把这个脚本挂到场景里任意物体上运行。如果返回里有choices字段说明 Key 和 Base URL 都通了。如果报 401检查 Key 是否复制完整如果报连接失败检查 Player Settings 里 InternetClient 是否勾选。4.3 成功结果对照GetTargetedObject 验证成功的标志是gaze 到物体时 Console 打印物体名移开时停止打印。API 验证成功的标志是返回 JSON 里包含choices数组且finish_reason为stop。两个都通过后把测试脚本从场景里移除避免正式构建时多余请求。CursorFeedback 的调试输出也建议注释掉减少运行时开销。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth这一节对照真实报错给出排查路径。每个报错都按「现象、原因、解决」三步写。5.1 401 Unauthorized现象API 请求返回 401响应体里写invalid api key或unauthorized。原因Key 复制不完整、Key 已过期、或者 Authorization 头格式写错。常见的是漏了Bearer前缀或者 Key 前后带了空格。解决重新在控制台生成 Key复制时确认没有多余字符。检查代码里SetRequestHeader(Authorization, Bearer ApiConfig.ApiKey)的拼接是否正确。如果用的是 JSON 配置文件确认读取时没有把引号读进去。5.2 local proxy failed现象请求报local proxy failed或连接被拒绝。原因本地网络配置问题或者 Base URL 写成了带 UTM 的地址导致路径不对。注意 API 入口是https://taotoken.net/api不要加任何查询参数。解决确认ApiConfig.BaseUrl就是https://taotoken.net/api后面拼接/v1/chat/completions。检查 Unity 的 Player Settings 里 InternetClient 是否勾选。如果公司网络有防火墙确认 443 端口出站正常。5.3 reading choices 报错现象返回 JSON 解析时报reading choices或choices is null。原因请求体格式不对或者模型 ID 填错导致返回了错误结构。比如把messages写成了message或者model字段为空。解决对照接入文档检查请求体。最小可用请求体是{ model: 你的模型ID, messages: [ {role: user, content: ping} ] }确认model字段和你在控制台看到的 Model ID 完全一致。如果返回里没有choices先打印完整响应体看错误信息。5.4 OAuth 相关报错现象报OAuth token invalid或authentication failed。原因如果你用的是 Claude Code 或类似工具可能配置了 OAuth 流程但 Key 填错了位置。TaoToken 的 API Key 是直接放在 Authorization 头里的不需要走 OAuth 授权码流程。解决检查工具的配置文件确认 Base URL 指向https://taotoken.net/apiKey 填在 API Key 字段而不是 OAuth Token 字段。Claude Code 的配置参考https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite里的说明。5.5 CursorFeedback 仍报 GetTargetedObject 找不到现象补了 Cursor.cs 后 VS2017 仍报GetTargetedObject不存在。原因Unity 没有重新编译或者 CursorFeedback.cs 引用的 Cursor 是另一个命名空间下的类。解决在 Unity 里点Assets Refresh然后Edit Preferences External Tools确认 External Script Editor 是 VS2017。回到 VS2017 重新生成解决方案。如果还报错在 CursorFeedback.cs 顶部确认有using HoloToolkit.Unity.InputModule;。5.6 TapToPlaceParent 位置漂移现象用 TapToPlaceParent 放置物体后物体位置或角度不对。原因动了父文件夹的 Transform或者物体没加 Box Collider或者勾了 Is Trigger。解决只调 Default 子物体的 Transform。给 Default 加 Box Collider不勾 Is Trigger。TapToPlaceParent 挂在 Default 上不要挂在父文件夹上。6. 语义一致 CTA把 Key 和通道管起来继续调试你的 HoloLens 工程GetTargetedObject 补全后你的 Artery 场景应该能正常跑 gaze 加 gesture 交互了。接下来如果还要接语音、视觉或者模型推理建议把 Key 和 API 通道统一到 TaoToken 管理别在每个脚本里散落硬编码。需要生成 Key 和查看调用额度去 API Keys 页面https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite。接入细节和请求格式看文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite。想先验证模型能不能通用模型对话页面https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite。长期做 HoloLens 交互开发、需要稳定调用通道的直接上 Coding Planhttps://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite。最后留一个我踩过的坑VS2017 部署到 HoloLens 时如果报DEP6957连接失败先确认 HoloLens 和开发机在同一网段然后在 VS2017 的Project Properties Debugging里把Authentication设为Universal (Unencrypted Protocol)。这个和 TaoToken 无关但会卡住整个部署流程排查时别混淆。
返回列表