unity3d 在Unity中以编程方式创建动画?

nbysray5  于 2023-02-13  发布在  其他
关注(0)|答案(2)|浏览(182)

在我的游戏中,我有一个很大的装备目录:盔甲、武器和盾牌。这些的组合可以是非常巨大的。

除此之外,玩家可以选择在游戏中切换到不同的盔甲武器组合。最后为了解决这个问题,我使用了下面的对象结构。

每当我切换武器时,我会激活/取消激活必要的游戏对象。动画设置如下:

现在,问题是如何创建动画。我最初考虑过通过编程方式预先渲染所有的组合,但我的目录太大了,它会创建100个,如果不是1000个动画的话。所以我选择了一个不同的解决方案。在游戏时间创建动画,一旦我知道玩家会选择什么装备。为此,我创建了一个脚本来处理这个问题。问题是我一直在使用UnityEditor的API,现在我意识到构建将无法工作。特别是因为2个不同的类:EditorCurveBindingObjectReferenceKeyframe
这是我在创建动画时如何使用该类的一些片段:

static EditorCurveBinding GetEditorCurveBinding(string path = "")
{
    EditorCurveBinding spriteBinding = new EditorCurveBinding();
    spriteBinding.type = typeof(SpriteRenderer);
    spriteBinding.path = path;
    spriteBinding.propertyName = "m_Sprite";

    return spriteBinding;
}
static ObjectReferenceKeyframe GetKeyframe(float time, Sprite sprite)
{
    ObjectReferenceKeyframe keyframe = new ObjectReferenceKeyframe();
    keyframe.time = time / FRAMERATE;
    keyframe.value = sprite;
    return keyframe;
}

现在,关于Curve的问题,我想我已经解决了,用下面的代码替换它,用AnimationCurve替换EditorCurveBinding

AnimationClip clip = ...
AnimationCurve curve = new AnimationCurve();
clip.SetCurve(path, typeof(SpriteRenderer), "m_Sprite", curve);

但是我不知道如何设置每个动画的精灵,我以为使用curve.AddKey会有帮助,但是我没有看到有办法在那里添加精灵。
我该如何重写代码以避免使用UnityEditor呢?
Full code

yhxst69z

yhxst69z1#

就我个人而言,我会完全避免内置的Animator和Animations,因为这个工具是非常狭窄的目的,动画一个单一的对象在一个预定义的方式(例如:对于过场动画)。

离题-性能

除此之外,玩家可以选择在游戏中切换到不同的盔甲武器组合。最后为了解决这个问题,我使用了下面的对象结构。
正如您可能知道的那样,这是非常低效的内存方式,并且会降低性能(禁用的对象仍然有边际CPU开销),还会增加新对象的加载时间和示例化时间。

我可以使用Animator或Animation吗?

因为Animator没有API来访问它的内部结构和动画类型,总的来说,除了告诉它播放或停止之外,你什么都不能做。因为我知道你的动画是"基于精灵"而不是"基于变换"的,任何理智的想法都是低效的!
我发誓反对的最佳解决方案如下:

  • 创建"触发点",您将"激活"
  • 基于触发点-更改子画面
public class AnimationController : MonoBehaviour
    {
        public int AnimationIndex;
        public Sprite[] AnimationSprites;
        public SpriteRenderer SpriteRenderer;
        
        private void Update()
        {
            SpriteRenderer.sprite = AnimationSprites[AnimationIndex];
        }
    }

更好的解决方案?

由于我们已经需要定制结构来管理我们的精灵,我们可能想优化整个东西,因为我们没有使用几乎任何的动画功能,我们可以写定制控制器,将取代动画在这种情况下。这应该会大大提高性能,因为动画是非常沉重的!

// MonoBehaviour is optional here
    public class SpriteRendererAnimationHandler
    {
        // More fields that would control the animation timing
        
        public Sprite[] AnimationSprites;
        public SpriteRenderer SpriteRenderer;
        
        public void OnAnimationUpdate(int index)
        {
            var resolvedIndex = ResolveIndex(index);
            SpriteRenderer.sprite = AnimationSprites[resolvedIndex];
        }

        private int ResolveIndex(int index)
        {
            // Resolve animation index to sprite array index
        }
    }

    // One controller per character - or global per game that synchronize all animations to locked FPS 12.
    public class AnimationController : MonoBehaviour
    {
        private List<SpriteRendererAnimationHandler> Handlers = new List<SpriteRendererAnimationHandler>();

        public void FixedUpdate()
        {
            foreach (var handler in Handlers)
            {
                // Calculate animation index
                int calculatedAnimationIndex = ...;
                handler.OnAnimationUpdate(calculatedAnimationIndex);
            }
        }
    }
gcmastyq

gcmastyq2#

添加一个名为animationindex的公共字段到Tomasz最后一个例子,然后创建动画在animator中,就像你通常做的动画片,然后动画化该动画索引字段。简单的if(currentAnimationyion!= lastAnimationIndex)检查是否需要发送到处理程序和你摇摆

相关问题