Unity Animator.MatchTarget 详解:匹配处决和暗杀位置

一、MatchTarget 核心概念

1.1 功能定义

Animator.MatchTarget 是Unity动画系统中的高级功能,用于在动画播放过程中精确控制角色位置,实现:

  • 角色与特定目标点精确对齐
  • 动画过程中的位置矫正
  • 交互式动画的精准定位

1.2 主要参数说明

参数 类型 用途
targetPosition Vector3 目标世界坐标位置
targetRotation Quaternion 目标旋转
targetBodyPart AvatarTarget 要对齐的身体部位
weightMask MatchTargetWeightMask 位置/旋转匹配权重
startNormalizedTime float 开始匹配的时间点(0-1)
targetNormalizedTime float 完成匹配的时间点(0-1)

二、处决与暗杀位置匹配实现

2.1 处决动画位置匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
if (_animator.AnimationAtTag("Finish"))
{
// 1. 面向处决目标的背后
transform.rotation = Quaternion.LookRotation(-_CurrentEnemy.forward);

// 2. 避免重复调用与状态检查
if (!_animator.isMatchingTarget && !_animator.IsInTransition(0))
{
// 3. 获取偏移距离
float offset = _FinishCombo.ComboPositionOffsite(_executingComboIndex);

// 4. 计算目标位置(敌人后方)
Vector3 targetPosition = _CurrentEnemy.position + (-transform.forward * offset);

// 5. 执行位置匹配
_animator.MatchTarget(
targetPosition, // 目标位置
Quaternion.identity, // 保持当前旋转
AvatarTarget.Body, // 整个身体对齐
new MatchTargetWeightMask( // 权重设置
Vector3.one, // 位置匹配权重=1
0f), // 旋转匹配权重=0
0f, // 开始时间(动画开始时)
0.03f // 完成时间(动画3%进度时)
);
}
}

2.2 暗杀动画位置匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
else if (_animator.AnimationAtTag("Assassination"))
{
// 1. 面向与敌人相同的方向
transform.rotation = Quaternion.LookRotation(_CurrentEnemy.forward);

// 2. 避免重复调用与状态检查
if (!_animator.isMatchingTarget && !_animator.IsInTransition(0))
{
// 3. 获取暗杀动画专用偏移
float offset = _AssCombo.ComboPositionOffsite(_executingComboIndex);

// 4. 计算目标位置(敌人后方)
Vector3 targetPosition = _CurrentEnemy.position + (-transform.forward * offset);

// 5. 执行位置匹配(参数同上)
_animator.MatchTarget(
targetPosition,
Quaternion.identity,
AvatarTarget.Body,
new MatchTargetWeightMask(Vector3.one, 0f),
0f,
0.03f
);
}
}

三、位置匹配技术要点解析

3.1 关键技术细节

  1. 方向设置差异

    • 处决动画:LookRotation(-_CurrentEnemy.forward) - 面向敌人背后
    • 暗杀动画:LookRotation(_CurrentEnemy.forward) - 与敌人朝向相同
  2. 时间控制

    • 匹配在动画开始阶段完成(0f0.03f)
    • 确保角色在动画早期就到达正确位置
  3. 防重入处理

    • !_animator.isMatchingTarget - 避免重复调用匹配
    • !_animator.IsInTransition(0) - 避免在过渡期调用

3.2 位置计算解析

1
2
3
4
5
6
7
处决动画:                        暗杀动画:

敌人 ←───── 玩家 玩家 ─────→ 敌人
↑ ↑ ↑ ↑
│ │ │ │
forward -forward forward forward
+ offset + offset

3.3 MatchTargetWeightMask 参数说明

1
new MatchTargetWeightMask(Vector3.one, 0f)
  • Vector3.one: 完全匹配XYZ位置(权重=1)
  • 0f: 不匹配旋转(权重=0),保留动画中的旋转

四、优化与扩展建议

4.1 代码优化建议

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
private void MatchFinishPosition()
{
// 前置条件检查
if (_CurrentEnemy == null || !_animator) return;

bool isFinish = _animator.AnimationAtTag("Finish");
bool isAssassination = _animator.AnimationAtTag("Assassination");

if (!isFinish && !isAssassination) return;

// 设置朝向
transform.rotation = Quaternion.LookRotation(
isFinish ? -_CurrentEnemy.forward : _CurrentEnemy.forward);

// 状态检查
if (_animator.isMatchingTarget || _animator.IsInTransition(0)) return;

// 获取对应的偏移和组合数据
CharaCombo currentActionCombo = isFinish ? _FinishCombo : _AssCombo;
float offset = currentActionCombo.ComboPositionOffsite(_executingComboIndex);

// 执行位置匹配
_animator.MatchTarget(
_CurrentEnemy.position + (-transform.forward * offset),
Quaternion.identity,
AvatarTarget.Body,
new MatchTargetWeightMask(Vector3.one, 0f),
0f,
0.03f
);
}

4.2 功能扩展方向

  1. 动态偏移调整

    • 根据角色体型差异调整偏移
    • float adjustedOffset = offset * targetHeightRatio;
  2. 多点匹配

    • 不同处决动画的不同阶段匹配不同位置
    • 实现更复杂的处决动画效果
  3. 环境检测

    • 添加射线检测避免穿墙
    • if (Physics.Raycast(start, direction, out hit, offset))

五、技术实现原理

5.1 MatchTarget 工作流程

  1. 动画系统记录当前位置/目标位置
  2. 计算匹配所需位移曲线
  3. 在指定时间段内应用位移
  4. 完成匹配后恢复动画控制

5.2 常见问题与解决方案

问题 可能原因 解决方案
角色抖动 匹配时间过短 延长匹配时间段
位置不准确 偏移计算错误 调整offset或使用调试可视化
不触发匹配 状态条件冲突 检查isMatchingTarget和过渡状态

这种精确的位置匹配技术是实现高质量处决/暗杀动画的关键,确保玩家与敌人之间的空间关系始终正确,提供流畅的视觉体验。