Unity - 如何在运行时更改动画剪辑关键帧值

问题描述 投票:0回答:2

是否可以通过 Unity3d 中的脚本在运行时更改剪辑中的关键帧值? (非遗留)

我想更改“Body > arm”的值-rotation.z。正常剪辑有 3 个关键帧,我想将唯一的第二个关键帧值更改为 120f。

在下面的屏幕截图中,您可以看到我的“RightArm”属性(第一个关键帧值为 0)。结果一定是,当我抬起鼠标时(position.y 也可能是 120),在这个动画剪辑中,手臂必须跟随。

我希望我足够描述我的问题,以便您能够理解。每个谷歌解决方案和许多代码示例都不起作用......

谢谢!

我的Unity版本:2019.2.8

Screenshot

unity-game-engine
2个回答
1
投票

您可以使用

AnimationClip.SetCurve(string relativePath, Type type, string propertyName, AnimationCurve curve)

哪里

相对路径
该曲线适用的游戏对象的路径。

relativePath
的格式类似于路径名,例如
"root/spine/leftArm"
。如果
relativePath
为空,则指的是
GameObject
/
Animation
组件附加到的
Animator

在你的情况下可能是这样的

"Body/RightShoulder/RightArm"

类型
动画组件的类类型。

就你而言

typeof(Transform)

属性名称
动画属性的名称或路径。

请注意,对于 Unity 内置组件,属性名称有时与检查器中显示的名称不同!请始终参考 API。

就你而言

localRotation

曲线
动画曲线。

(已修改)文档中的示例:

public AnimationClip clip;

private void Start()
{
    // create a curve to move the GameObject and assign to the clip
    Keyframe[] keys;
    keys = new Keyframe[3];
    keys[0] = new Keyframe(0.0f, 0.0f);
    // within 12 seconds rotate to 120°
    keys[1] = new Keyframe(12.0f, 120f);
    // Whatever you need as 3. keyframe
    keys[2] = new Keyframe(16.0f, 0f);

    var curve = new AnimationCurve(keys);
    clip.SetCurve("Body/RightShoulder/RightArm", typeof(Transform), "localRotation.z", curve);
}

另请参阅

Keyframe
AnimationCurve


注:

不幸的是,不可能获取现有曲线(至少不是微不足道的),因此您始终必须从头开始设置


0
投票

正如@derHugo所说,直接访问曲线数据(get)是不可能的。但我发现了实用方法

AnimationUtility.GetCurveBindings(animationClip)
,如果您处于编辑器模式,这对解决问题很有帮助。一种用法是:

public void ScaleAnimationClip(AnimationClip clip, float scale)
{
    var curveData = AnimationUtility.GetCurveBindings(clip);
    foreach (var data in curveData)
    {
        if (data.propertyName.StartsWith("m_LocalPosition"))
        {
            var curve = AnimationUtility.GetEditorCurve(clip, data);
            curve.keys = curve.keys.Select(k => new Keyframe(k.time, k.value * scale, k.inTangent, k.outTangent, k.inWeight, k.outWeight)).ToArray();
            AnimationUtility.SetEditorCurve(clip, data, curve);
            EditorUtility.SetDirty(clip);
        }
    }
    AssetDatabase.SaveAssetIfDirty(clip);
}

用于在更改 sprite

pixel per unit
属性后修复 2D 动画。

© www.soinside.com 2019 - 2024. All rights reserved.