C# 混合到统一动画-帧中的跳跃

C# 混合到统一动画-帧中的跳跃,c#,unity3d,animation,blender,unity3d-mecanim,C#,Unity3d,Animation,Blender,Unity3d Mecanim,我决定尝试将FBX中带有动画的混合器模型导出到Unity。此模型的顶部门有两个动画“打开”和“关闭”。事情是这样的-当模型启动时,我的模型似乎喜欢跳入两个动画的原点,即,如果我导入模型并且门打开,并且我决定触发关闭它,它将正确关闭-但是,当我尝试打开它时,它决定它首先需要保持在与关闭门动画相同的原点,然后它打开-基本上导致门在模型外移动太远 我还特意尝试在Mecaim animator控件中使用一个动画,但似乎当它在相反方向移动时返回到门的正确位置时,它并没有以相同的速度移动,而是不稳定地移动。

我决定尝试将FBX中带有动画的混合器模型导出到Unity。此模型的顶部门有两个动画“打开”和“关闭”。事情是这样的-当模型启动时,我的模型似乎喜欢跳入两个动画的原点,即,如果我导入模型并且门打开,并且我决定触发关闭它,它将正确关闭-但是,当我尝试打开它时,它决定它首先需要保持在与关闭门动画相同的原点,然后它打开-基本上导致门在模型外移动太远

我还特意尝试在Mecaim animator控件中使用一个动画,但似乎当它在相反方向移动时返回到门的正确位置时,它并没有以相同的速度移动,而是不稳定地移动。最后,当我尝试将一个门动画转换为速度相反的同一个门动画时(即门关闭到门关闭,一个速度为1,一个速度为-1),它仍然会不稳定地跳跃

这是我最后一次尝试的Mecaim animator设置:

这是试图在另一个状态下使用相同的动画,但速度为负而不是正。它不像你期望的那样工作

在下面的代码中,我使用状态触发器在这些状态之间转换:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;

public class TriggerAnimation : MonoBehaviour {

    public Transform cockPit;
    // Use this for initialization
    void Start () {


    }

    // Update is called once per frame
    void Update () {
        if (Input.GetKeyDown("t"))
        {
            //AnimationPlayableUtilities.PlayClip("CockPit_ExtDoor|Open");
            Debug.Log("I'm being pressed");
            //GetComponent<Animator>().SetTrigger("ExtDoorOpen");
            GetComponent<Animator>().SetTrigger("IntDoorOpen");
            //GetComponent<Animator>().SetTrigger("CockPit_Door|Open");

        }
        if (Input.GetKeyDown("u"))
        {
            //PlayableGraph graph = new PlayableGraph();
            //AnimationPlayableUtilities.PlayAnimatorController(GetComponent<Animator>(), GetComponent<RuntimeAnimatorController>(), out graph);
            Debug.Log("I'm being pressed");
            //GetComponent<Animator>().SetTrigger("ExtDoorClose");
            GetComponent<Animator>().SetTrigger("IntDoorClose");
            //GetComponent<Animator>().SetTrigger("CockPit_Door|Close");

        }
        if (Input.GetKeyDown("x"))
        {
            GetComponent<Animation>().Play("CockPit_IntDoor|Open");
        }
        if (Input.GetKeyDown("z"))
        {
            GetComponent<Animation>().Play("CockPit_IntDoor|Close");
        }
    }
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
使用UnityEngine.Playbables;
公共类触发:单行为{
公共转换座舱;
//用于初始化
无效开始(){
}
//每帧调用一次更新
无效更新(){
if(Input.GetKeyDown(“t”))
{
//PlayClip(“驾驶舱外门打开”);
Log(“我被按下”);
//GetComponent().SetTrigger(“ExtDoorOpen”);
GetComponent().SetTrigger(“IntDoorOpen”);
//GetComponent().SetTrigger(“驾驶舱舱门打开”);
}
if(Input.GetKeyDown(“u”))
{
//PlayableGraph=新的PlayableGraph();
//PlayAnimatorController(GetComponent(),GetComponent(),out graph);
Log(“我被按下”);
//GetComponent().SetTrigger(“ExtDoorClose”);
GetComponent().SetTrigger(“IntDoorClose”);
//GetComponent().SetTrigger(“驾驶舱门关闭”);
}
if(Input.GetKeyDown(“x”))
{
GetComponent().Play(“驾驶舱门打开”);
}
if(Input.GetKeyDown(“z”))
{
GetComponent().Play(“驾驶舱门关闭”);
}
}
}

有没有人能告诉我是否有更好的方法来解决这个问题,以及如何解决?我尝试过在这方面的几篇文章之间切换,包括他们网站上关于Mecanim for Unity的演示教程-无骰子…

我在将blender中的动画引入Unity时遇到了很多困难。有很多陷阱。这里有几件事我想试试。如果这些对你有用,请告诉我

  • 在输入源代码时,确保它们在blender中处于相同的位置
在blender中设置模型动画时,模型的原点通常会 意外移动或不在两个动画之间的完全相同位置 当它被导入到unity中时,它就有一种干扰动画的方式。 因此,只需在动画之间进行双重检查,并确保原点不存在 在两个动画之间切换
  • 确保未在unity animator中应用RootMotion


用于应用根运动的文档

基本上,它所做的,如果启用是为任何运动发生在你的身体 动画它将动画中发生的任何运动添加到其当前位置 因此,如果门的根对象在打开时向左移动了2个单位,并且 应用根运动时,对象将比所需位置左2个单位 期待。它会继续堆积,越来越左。
  • 确保删除动画片段中的所有transform.position关键点
我假设你不想让门的位置移动,但是 相反,只需让动画使其显示为门正在移动。如果是那样的话 假设对象设置正确。在我看来,如果是滑动门,它会 有这样一个对象树:根对象>框架>门。只有这样 应该有任何动画关键点的对象应该是门对象。另一位家长 物体应该是静止的。
  • 小建议。我会用枪炮而不是扳机。这样就更容易跟踪门的状态。(即,将动画基于“isClosed”bool)

这些只是我在过去发现的一些有用的故障排除技巧

我在将动画从blender带入unity方面遇到了很多困难。有很多陷阱。这里有几件事我想试试。如果这些对你有用,请告诉我

  • 在输入源代码时,确保它们在blender中处于相同的位置
在blender中设置模型动画时,模型的原点通常会 意外移动或不在两个动画之间的完全相同位置 当它被导入到unity中时,它就有一种干扰动画的方式。 因此,只需在动画之间进行双重检查,并确保原点不存在 在两个动画之间切换
  • 确保未在unity animator中应用RootMotion


用于应用根运动的文档

基本上,它所做的,如果启用是为任何运动发生在你的身体 动画它添加任何运动 When animating a model in blender it often happens that the origin of your model has accidentally been moved or is not in the exact same place between your two animations and when that gets imported into unity it has a way of messing with your animations. So just double check between your animations and make sure that the origin has not shifted between the two animations basically what it does if enabled is for any movement that takes place in your animation it adds whatever movement transpired in the animation to its current position Therefore if the root object of the door moved left by 2units when it opens and your are applying root motion the object would then be 2 units left of where you would expect. And it would just continue to stack getting further and further left. I am assuming that you do not want to actually have the position of the door move but instead just have the animation make it appear as if the door is moving. If so in that case Assuming that your object is setup right. Which in my mind if it was a sliding door it would have an object tree like this RootObject>Frame>Door. With that being the case the only object that should have any animation keys on it should be the door object. the other parent objects should be stationary.
if (Input.GetKeyDown("x"))
{
    GetComponent<Animation>().Play("CockPit_IntDoor|Open");
}

if (Input.GetKeyDown("z"))
{
    GetComponent<Animation>().Play("CockPit_IntDoor|Close");
}
// Store the component frerence instead of getting it everytime again
private Animator _animator;

private void Awake()
{
    _animator = GetComponent<Animator>();
}

private void Update()
{
    if (Input.GetKeyDown("t"))
    {
        Debug.Log("t is being pressed");
        _animator.SetBool("IsOpen", true);
    }
    // use if-else in order to process only one of the buttons at a time
    else if (Input.GetKeyDown("u"))
    {
        Debug.Log("u is being pressed");
        _animator.SetBool("IsOpen", false);
    }
    // you still can keep those for jumping to a state directly without the transition
    else if (Input.GetKeyDown("x"))
    {
        _animator.Play("Opened");
    }
    else if (Input.GetKeyDown("z"))
    {
        _animator.Play("Closed");
    }
}