【问题标题】:Unity3d - How to get Animator's Layer -->Sub-State --> State namehash?Unity3d - 如何获取 Animator 的图层 --> 子状态 --> 状态名称哈希?
【发布时间】:2016-04-16 16:29:32
【问题描述】:

我正在使用以下结构:

(层)“基础层”--> (子状态)“Jump_Fall_Roll”--> (状态)“滚动”

static int rollState = Animator.StringToHash("What to put here??");

private Animator anim;
private AnimatorStateInfo currentBaseState;

void Start ()
{
    anim = GetComponent<Animator>();
}

void FixedUpdate ()
{
    currentBaseState = anim.GetCurrentAnimatorStateInfo(0);

    if (currentBaseState.nameHash == rollState) {
        Debug.Log ("ROLL nameHash worked"); //Not working
    }
    if (currentBaseState.IsName("Roll")) {
        Debug.Log ("ROLL IsName worked"); //Working.......
    }
}

我尝试了 nameHash 的父母/状态的所有可能组合,但它从未奏效......

名称应采用 Layer.Name 形式,例如“Base.Idle”。

AnimatorStateInfo.IsName doc from Unity

那么,为什么我的第一个案例不起作用?第二种情况如何运作?

我真的很困惑。

编辑

我的 Animator 视图的屏幕截图

我确实尝试过static int rollState = Animator.StringToHash("Base Layer.Roll");

然后Debug.Log (currentBaseState.nameHash + ", " + rollState);

会输出

1094782407,-1476868190

当我处于滚动状态时。 rollState NEVER = currentBaseState.nameHash.

我确实在空闲状态下对此进行了测试,效果非常好:

static int rollState = Animator.StringToHash("Base Layer.Idle");

我看不到子状态的结构,真令人沮丧。

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    在撰写本文时的最新版本 5.3.4 中,该问题可以部分回答如下。

    首先,没有nameHash。最接近它的变量是shortNameHash。建议使用fullPathHash 代替,稍后将进行解释。 shortNameHash 就像 OS 中的裸文件名,而 fullPathHash 顾名思义,在状态名称之前包含层名称作为路径。这是一个使用它们来识别当前状态的示例:

    int baseState = Animator.StringToHash("Base Layer.Idle");
    int short_baseState = Animator.StringToHash("Idle");
    int subState = Animator.StringToHash("Base Layer.Jump_Fall_Roll.Roll");
    int short_subState = Animator.StringToHash("Roll");
    
    ...
    
    AnimatorStateInfo s = myAnimator.GetCurrentAnimatorStateInfo(0);
    Debug.Log(s.fullPathHash + ", " + baseState);   //they are equal at Idle state in base layer
    Debug.Log(s.shortNameHash + ", " + short_baseState);   //they are equal at Idle state in base layer
    Debug.Log(s.fullPathHash + ", " + subState);   //they are equal at Roll state in sub-state machine
    Debug.Log(s.shortNameHash + ", " + short_subState);   //they are equal at Roll state in sub-state machine
    

    从上面的例子中我们可以看出shortNameHash适用于裸状态名称,无论状态是基础层中的常规状态,还是子状态机中的状态。但是fullPathHash 仅在层路径正确地位于状态名称之前的前缀时才有效。如果我们确定在不同的状态机中没有重复的状态名称,shortNameHash 很好,因为它很短,但是这个假设并不总是适用于大型复杂的动画控制器,所以我建议使用fullPathHash all时间。

    我将此答案称为“部分”,因为我们必须确保传递给 GetCurrentAnimatorStateInfo 的层 id 为 0,即“当前工作层”(如 linux 中的 pwd 命令)应该是基础层。如果我们将 1 传递给上面的路径名约定,它就会失败。我没有时间猜测第 1 层中的路径名称应该是什么。欢迎对此进行任何补充。

    【讨论】:

      【解决方案2】:

      我真的不知道我的项目发生了什么变化,但我尝试了

      static int rollState = Animator.StringToHash ("Jump_Fall_Roll.Roll");
      

      再次(在发布此问题之前我已经对其进行了测试,并花了几个小时试图解决它)并且它成功了............

      因此,对于子状态,请勿在哈希中包含层名称,仅包含您的状态的父子状态。

      我没有测试嵌套的子状态。

      感谢那些试图帮助我的人

      【讨论】:

        【解决方案3】:

        要传入Animator.StringToHash 的字符串应包含图层名称和状态名称

        所以要正确生成哈希应该是:

        int rollState = Animator.StringToHash("Base Layer.Roll");
        

        【讨论】:

        • Debug.Log (currentBaseState.nameHash + ", " + rollState);输出:1094782407,-1476868190 在滚动期间,它不起作用,我将用更多信息更新我的问题
        猜你喜欢
        • 1970-01-01
        • 2019-06-05
        • 1970-01-01
        • 1970-01-01
        • 2022-10-08
        • 2023-03-03
        • 2016-12-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多