脚本化凝视
从代码中将 Convai 角色的视线指向某个 Transform 或点,并等待结果,以便在其命中后再触发后续操作。
在代码中将角色的目光指向某个 Transform 或世界空间中的点,并使用返回的句柄来判断注视何时已就位。当过场动画节拍、动作执行器或 UI 事件需要控制角色看向哪里,而不是依赖目光策略已提供的自动瞄准时,请使用本页。
前提条件
ConvaiGazeController已添加到角色(Convai/具身/凝视).角色的
ConvaiGazeController,通过GetComponent<ConvaiGazeController>()或一个序列化字段。
请求一次脚本化注视
调用 GazeAt 用于会一直保持到被释放或保持时间耗尽的请求,或者 GlanceAt 用于短暂的一行式注视。两者都会返回一个 GazeHandle ,并且绝不会为 null 一个有效目标返回空值。
using Convai.Modules.Gaze.Components;
using UnityEngine;
public sealed class DisplayCaseCue : MonoBehaviour
{
[SerializeField] private Transform displayCase;
[SerializeField] private ConvaiGazeController gaze;
private void OnTriggerEnter(Collider other)
{
// 将注视保持 2 秒;如果展示柜不在轴线上,则允许全身转身。
gaze.GazeAt(displayCase, new GazeOptions
{
HoldSeconds = 2f,
Engagement = 1f,
AllowBodyTurn = true
});
}
}使用 GlanceAt 用于更短、优先级更低的注视,它绝不会让身体转身,并会自动恢复到策略目标:
脚本化请求始终优先于自动目标。 GazeAt 请求优先于 GlanceAt 请求:任何显式的 GazeAt 都会抢占正在进行的瞥视。
GazeOptions 字段
优先级
整数
0
脚本化请求之间的优先级(数值更高者获胜;相同时按最近性打破平局)。
HoldSeconds
float
0
来自请求的保持时长(秒)。数值 <= 0 保持直到 GazeHandle.Release() 被调用。
参与度
float
0
Engagement 覆盖值,位于 (0, 1]。数值 <= 0 使用当前对话状态的 engagement——当注视必须无论对话状态如何都要就位时,请传入显式值(例如 1),因为 空闲 默认为 0.
允许身体转向
布尔值
否
此请求是否可以触发朝目标的全身转身。
GlanceAt 会在内部自行构建它的 GazeOptions : HoldSeconds 来自其 durationSeconds 参数(默认 1.2f,最小裁剪为 0.2f), 参与度 固定为 1以及 允许身体转向 固定为 否.
在 Unity 中等待句柄
GazeHandle.Settled 在 是 注视对齐到目标后完成,或者 否 当请求在对齐前结束时完成。 GazeHandle.Completion 在请求结束时完成——无论是保持时间耗尽、被释放,还是目标丢失。请在 Settled 在后续动作之前等待,例如拾取手势这类依赖角色先明显看向目标的动作。
Settled 可以完成 否 用于明确未被接受的请求——参见 GazeOutcome.HeldEyeContactInstead 下方——而不仅仅是用于真正的失败。应当根据 结果 而不是只看布尔值本身,再将一个 否 结果视为错误。
调用 handle.Release() 以提前结束请求。 释放 可以安全地多次调用,也可在取消回调中调用。调用 ConvaiGazeController.ReleaseAllScriptedGaze() 可一次性结束角色上的每个脚本化请求,例如在过场动画中止时。
GazeOutcome 值
Taken
0
请求处于活动状态,或者它已抵达目标。默认状态,直到另有说明。
被打断
1
请求在注视抵达前结束——被释放、过期、被更高优先级的注视取代,或者其目标已被销毁。
HeldEyeContactInstead
2
角色刻意保持了眼神接触,瞥视被并入其中而没有被接管,因为 LockBlocksGlances 已开启。没有出错——角色选择了人而不是物。
眼神接触锁定如何改变脚本化请求
AllowScriptedOverridesDuringExactFocus 和 LockBlocksGlances,在 ConvaiGazeController,决定在眼神接触锁定(ConversationLock 或 AlwaysLock EyeContactMode)生效时,脚本化请求是否会被接受:
当
FocusFidelity是精确时,显式的GazeAt请求会被直接拒绝,除非AllowScriptedOverridesDuringExactFocus是是。被拒绝的请求会返回一个其Completion已经完成,并且其Settled会解析为否.当
FocusFidelity是社交时,显式的GazeAt请求始终会抢占该锁。GlanceAt请求会在LockBlocksGlances是是(默认值)期间被吸收:返回的句柄会立即以结果设置为HeldEyeContactInstead完成,且目光绝不会离开玩家锚点。设置LockBlocksGlances移动到否可让瞥视穿过该锁继续播放。
故障排查
一个 GazeAt 请求永远不会稳定下来
症状: handle.Settled 等待并返回 否.
原因: 该请求被更高优先级的脚本化请求中断、其目标被销毁,或者 精确 focus 拒绝了它。
解决方法: 检查 handle.Outcome 在……之后 Settled 的解析结果以区分 被打断 来自 HeldEyeContactInstead,并触发 优先级 或设置 AllowScriptedOverridesDuringExactFocus 如果该请求应当胜出。
验证: 后续动作只会在以下情况后运行 Settled 会解析为 是.
下一步
凝视目标与提供器配置眼神接触凝视脚本参考最后更新于
这有帮助吗?