播放动作和手势
通过脚本在 Convai 角色上播放命名动作、锚定动作和指向手势,并读取每次调用返回的句柄。
通过脚本播放命名动作或手势,让角色走到锚点并在那里执行动作,或者指向目标——全部通过脚本,借助 ConvaiBodyAnimationController 以及每次调用返回的句柄。请在角色上运行 Convai Body Animation,并且其动画集已编写好你想触发的动作或指向方向后再使用本页。
前提条件
ConvaiBodyAnimationController已添加到角色上,并分配了动画集。参见 构建动画集 用于编写动作和指向方向。对控制器的引用,可通过以下方式解析:
GetComponent<ConvaiBodyAnimationController>()在角色上。
播放命名动作或手势
调用 PlayAction 使用动作名称或别名——匹配不区分大小写,并将空格、连字符和下划线视为等价。
using Convai.Modules.BodyAnimation;
using Convai.Modules.BodyAnimation.Components;
using UnityEngine;
public sealed class WaveOnCue : MonoBehaviour
{
[SerializeField] private ConvaiBodyAnimationController bodyAnimation;
public async void PlayWave()
{
BodyAnimationActionHandle handle = bodyAnimation.PlayAction("wave",
new ActionPlayOptions { HoldSeconds = 3f });
if (handle.Failed)
{
Debug.Log($"Wave didn't play: {handle.FailureReason}");
return;
}
bool completedNaturally = await handle.Completion; // false when interrupted
}
}ActionPlayOptions 字段:
SpeedMultiplier
float
<= 0 = 条目默认值
在条目编排速度基础上的播放速度乘数。
HoldSeconds
float
<= 0 = 持续保持直到停止
对于“持续保持直到停止”的动作:在主循环经过这么多秒后会自动请求停止。
FadeInSeconds
float
<= 0 = 条目 / 配置默认值
图层淡入覆盖。
FadeOutSeconds
float
<= 0 = 条目 / 配置默认值
图层淡出覆盖。也用于 StopActionImmediate.
WeightMultiplier
float
<= 0 = 现有行为
动作图层权重乘数。
BodyAnimationActionHandle (由 PlayAction):
ActionName
string 返回)——请求的名称或别名。
Failed / FailureReason
请求是否从未开始,以及原因。
IsDone
true 动作完全结束或被中断后。
完成
Task<bool> ——在以下情况下解析: true 播放完成时, false 被中断时。
Stop()
请求平滑停止;如果条目编排了退场段,则会播放退场。可安全重复调用。
StopImmediate(float blendOutSeconds = -1f)
立即停止,并在 blendOutSeconds (<= 0 (= 动作解析后的淡出时长)内交叉淡出,跳过剩余链路或退场段。
可直接通过控制器停止或中断当前正在播放的动作: StopAction() (平滑,播放退场)或 StopActionImmediate(float blendOutSeconds = -1f) (立即交叉淡出)。 CurrentActionName 读取当前正在播放的动作名称,若无则为空。
后端触发的手势通过与 PlayAction相同的名称/别名匹配来解析,因此 Convai 响应中的动作名 "pick_up" 会触发名为 "Pick Up" 或别名 "pick-up" 的条目,无需额外连线。
播放锚定动作
PlayActionAt 让角色走到锚点,根骨对齐到其姿态,然后播放命名动作——即“坐到长椅上”/拾取/使用道具流程。
PlayActionAt(Transform anchor, string actionNameOrAlias)
走到 锚点,对齐并播放。
PlayActionAt(Transform anchor, string actionNameOrAlias, ActionAnchorOptions anchorOptions, ActionPlayOptions playOptions = default)
同上,但可显式调整接近/对齐参数和动作播放细节。显式的 anchorOptions 会覆盖动作条目自身编排的默认值。
ActionAnchorOptions 没有公共构造函数,无法在脚本中使用自定义值来创建实例——其字段只能通过 Inspector 在动画集中的动作条目 Anchor Options 字段里设置。只有在想复用另一个条目的调参时,才向该重载传入已有的编排实例;否则请调用双参数重载,让条目自身编排的默认值生效。
锚点高度在对齐时会被忽略——只考虑其 XZ 位置和偏航角,因此请将锚点放在角色预期的站立点,而不是座位或道具的高度上。
PlayActionAtHandle (由 PlayActionAt):
ActionName
string ——请求的动作名称。
Phase
PlayActionAtPhase ——请求当前所处阶段。
Failed / FailureReason
请求是否从未开始,以及原因。
IsDone
true 当请求完成或被取消时。
完成
Task<bool> ——在以下情况下解析: true 当动作播放完成时, false 当被取消时。
Cancel()
在请求当前所处的任何阶段取消:在 Approaching期间停止移动,在 Aligning期间冻结对齐插值,或在 PlayingAction期间平滑停止动作。幂等。
指向目标或位置
PointAt 将手臂抬向世界坐标中的位置或一个会移动的 Transform,停在顶点,然后放下。
PointAt(Vector3 worldPosition, float holdSeconds = -1f)
指向固定的世界坐标位置。
PointAt(Transform target, float holdSeconds = -1f)
指向一个(会移动的)Transform,在保持期间持续重新瞄准。
PointAt(Transform target, in PointingPlayOptions options)
同上,但可调整播放细节:速度、淡入/淡出时长,以及经过一段保持后如何自动释放。
holdSeconds < 0 (或 PointingPlayOptions.HoldSeconds <= 0)会保持直到 StopPointing/Release() 被调用。
HoldSeconds 在 SDK 4.5.0 中已更改。 它一直只表示指向顶点处的暂停,而不是整个手势时长——抬起和放下属于动画片段。在 4.5.0 之前,没有办法缩短那段抬起/放下,因此在一个五秒顶点片段上设置一秒保持,仍然会得到大约六秒的指向。 PointingPlayOptions.Speed 现在会同时乘以抬起和放下速度,而 ReleaseStyle 设置为 Blend 会在保持结束时直接淡出姿态,而不是播放下放手臂的尾段。两者默认都沿用 4.5.0 之前的行为,因此现有场景不受影响;大约一秒的指向是 Speed = 1.5f 和 ReleaseStyle = PointingReleaseStyle.Blend.
PointingPlayOptions 字段:
Speed
float
<= 0 = 原生(1)
抬起/放下速度乘数。保持本身不受影响。
HoldSeconds
float
<= 0 = 保持直到释放
在顶点处保持的秒数。
BlendInSeconds
float
<= 0 = 配置 PointingFadeSeconds
图层淡入秒数。
BlendOutSeconds
float
<= 0 = 配置 PointingFadeSeconds
图层淡出秒数。
ReleaseStyle
PointingReleaseStyle
PlayTail
经过一段时间后的 HoldSeconds 自动释放会做什么:播放下放手臂尾段(PlayTail,默认)或立即交叉淡出姿态(Blend).
WeightMultiplier
float
<= 0 = 现有行为
指向图层权重乘数。
BodyAnimationPointingHandle (由每个 PointAt 重载返回):
Failed / FailureReason
请求是否从未开始,以及原因。
IsDone
true 当点指手势完全结束时(手臂放下)。
完成
Task ——在手势完全结束时解析。
Release()
现在结束保持;在完成前会先播放下放手臂尾段。
ReleaseImmediate(float blendOutSeconds = -1f)
立即停止并交叉淡出姿态,跳过下放手臂尾段。
SetSpeed(float speed)
实时调整正在运行的手势抬起/放下速度。保持期间无效果。
可直接通过控制器停止当前的指向保持: StopPointing() (平滑,播放尾段)或 StopPointingImmediate(float blendOutSeconds = -1f) (立即交叉淡出)。
面向某个方向并设置会话锚点
FaceTowards(Vector3 worldDirection, string reason = "FaceTowards") 使用动画化的原地转身系列让角色转向某个方向——无需 NavMeshAgent required. It returns false 当请求无法被满足时(功能被禁用、片段缺失、移动中忙碌)。
SetConversationAnchor(Transform anchor) 会覆盖 transform 的社交间距、近距离表现以及环境抑制,将其视为“这个角色正在和谁说话”——默认解析链的终点是 Camera.main,这对于 XR 设备、第二个本地玩家,或没有 MainCamera 标签的过场摄像机来说,都是错误的锚点。 ClearConversationAnchor() 会恢复为默认解析链。
故障排除
句柄的 Failed 为 true
症状: 该调用会立即返回,且不会播放任何内容。
原因: FailureReason 会说明原因——常见原因包括 “运行时尚未构建” (图未就绪), “未知动作” (动画集中没有匹配的名称或别名), “有一个正在播放的、不可中断的动作”, “没有移动” (PlayActionAt 且角色上没有 ConvaiNavMeshLocomotion ),或 “该集合没有指向片段”.
解决方法: 用于 “运行时尚未构建”,请订阅 ConvaiBodyAnimationController.RuntimeReady 并从处理器中调用,而不是 Start()/Awake() ——过早调用也会被记录到一个单独的延迟槽中并自动重放,但该事件能保证调用成功落地。对于其他原因,请检查动画集里编排的动作和指向方向,或者添加 ConvaiNavMeshLocomotion.
验证: handle.Failed 为 false 和 完成 在手势播放完成时解析。
下一步
配置移动身体动画配置参考身体动画脚本参考最后更新于
这有帮助吗?