Unity中如何通过脚本控制Blend Shape动画,实现随分数展开地毯?
解决方案:修复Blend Shape属性路径 + 分数驱动展开的优化方案
一、修复AnimationClip的属性路径问题
你代码里的"Blend Shape.Key 1"是错误的,Unity中SkinnedMeshRenderer的Blend Shape动画属性路径格式为两种:
- 按索引:
blendShape.[索引值](索引从0开始,对应Blender里第一个ShapeKey) - 按名称:
blendShape."[Blend Shape名称]"(名称需和Unity中显示的一致,比如Blender里的"Key 1",这里写blendShape."Key 1")
修正后的SetCurve代码二选一即可:
// 按索引(假设Key1是第一个Blend Shape,索引为0) clip.SetCurve("", typeof(SkinnedMeshRenderer), "blendShape.0", curve); // 或者按名称 clip.SetCurve("", typeof(SkinnedMeshRenderer), "blendShape.\"Key 1\"", curve);
另外注意:你当前用的是Legacy Animation系统,Unity现在更推荐使用Animator(Mecanim),如果要兼容新系统,建议改用Animator + AnimationClip绑定到Animator Controller的方式。
二、更适合分数驱动的优化方案
因为你需要根据分数实时控制地毯展开进度,直接通过代码设置Blend Shape权重比创建动画剪辑更灵活,步骤如下:
- 在脚本中引用SkinnedMeshRenderer组件
- 监听分数变化,根据当前分数计算对应的Blend Shape权重(比如分数0对应权重0,分数100对应权重100)
- 调用
SetBlendShapeWeight方法设置权重
示例代码:
using UnityEngine; public class CarpetUnfold : MonoBehaviour { public SkinnedMeshRenderer skinnedMeshRenderer; public int targetScore = 100; // 完全展开需要的分数值 private int currentScore = 0; // 外部调用此方法更新分数 public void UpdateScore(int addScore) { currentScore = Mathf.Clamp(currentScore + addScore, 0, targetScore); UpdateCarpetUnfold(); } private void UpdateCarpetUnfold() { // 计算权重:当前分数占目标分数的百分比 * 100(Blend Shape权重范围为0-100) float weight = (float)currentScore / targetScore * 100f; // 假设Blend Shape是第一个(索引0),如果是其他索引修改对应数字即可 skinnedMeshRenderer.SetBlendShapeWeight(0, weight); } // 测试用:按空格增加分数 private void Update() { if (Input.GetKeyDown(KeyCode.Space)) { UpdateScore(10); } } }
使用说明:
- 将脚本挂在地毯物体上,拖入对应的SkinnedMeshRenderer组件
- 设置
targetScore为完全展开需要的分数 - 当分数变化时,调用
UpdateScore方法,地毯会根据分数实时展开
三、确认Blend Shape的索引或名称
如果你不确定Blend Shape的索引或名称,可以在Unity编辑器中:
- 选中地毯物体,查看SkinnedMeshRenderer组件
- 在"Blend Shapes"列表中,第一个条目对应索引0,第二个对应索引1,以此类推
- 列表中显示的文字就是Blend Shape的名称(和Blender中ShapeKey名称一致)
内容的提问来源于stack exchange,提问作者Leon Ristic
相关产品推荐
相关产品推荐

