检查Unity脚本上的Animator仅适用于第一个Object

时间:2017-01-24 02:30:15

标签: c# unity3d animator

让我先解释一下这个问题:)

我有英雄和敌人。这是一场格斗游戏。英雄和敌人在动画控制器中都有空闲,阻止,打击和getHit动画和状态。英雄和敌人附有脚本。英雄由玩家控制,然后敌人由AI控制。

现在我首先将剧本附加到英雄,然后是敌人。现在当敌人拳打脚踢,如果英雄没有捍卫英雄就会受到打击。但是如果敌人没有阻挡并且英雄击中敌人则不会受到攻击。 这是因为脚本首先附加到英雄

现在,如果我从两者中删除脚本并且首先将敌人脚本附加到敌人,然后将英雄脚本附加到英雄。明智的是真实的。在敌人中,命中将被登记,而在英雄上的命中将不会被登记。

我不确定为什么会这样,我尝试了不同的事情,但问题仍然存在。

我也尝试在网上寻找解决方案,但没有一个能解决我的问题。

谢谢:)

下面是检查敌人可以采取命中的敌人脚本

void Update () {

    myTick++;
    currentTick = myTick;


    GameObject player = GameObject.Find("theDude");
    Animator pAnim = player.GetComponent<Animator>();

    //Getting Hit
    if (pAnim.GetBool("tIsPunching"))
    {
        if (anim.GetBool("bEnemyIsDefending") == false)
        {

            Debug.Log("enemy got hit");
            anim.SetTrigger("tEnemyGotHit");
            anim.SetBool("bEnemyIsDefending", true);
        }
    }
}

这是英雄剧本,用于检查英雄是否可以击中。

void Update () {

    totalTime += Time.deltaTime;

    GameObject enemy = GameObject.Find("Enemy");
    Animator eAnim = enemy.GetComponent<Animator>();

    //Getting Hit
    if (eAnim.GetBool("tEnemyIsPunching"))
    {
        if (anim.GetBool("bIsDefending") == false)
        {

            Debug.Log("player got hit");
            anim.SetTrigger("tGotHit");

        }
    }
 }

而不是获取对象,我曾经有一个公共GameObject,并在相应的类中附加了英雄和敌人。但它没有任何区别。

1 个答案:

答案 0 :(得分:1)

我认为您的问题在于使用触发器java.lang.ClassCastException: org.apache.avro.mapred.AvroKey cannot be cast to my.package.containing.MyCustomClass tEnemyIsPunching。只要触发器发生转换,触发器就会重置

(见:https://docs.unity3d.com/Manual/AnimationParameters.html)。

在您的情况下,tIsPunching或(tIsEnemyPunching)会在设置的同一帧中重置。下面是一个例子,说明如果首先添加英雄脚本,游戏中的更新循环可能会是什么样子:

tIsPunching

在下一次更新中,让我们看一下英雄更新中发生的事情:

Hero Update()
    Check if enemy is punching
    He is not, so don't do anything

Enemy Update()
    Punch! Set 'bIsEnemyPunching' = true

Animation Update()
    bIsEnemyPunching is true so transition to the punching animation
    reset bIsEnemyPunching = false

所以Hero从来没有看过拳头因为Hero Update() Check bIsEnemyPunching bIsEnemyPunching was reset in the previous frame, so it is false Since the enemy isn't punching don't do anything 在Hero改变检查之前被重置了。

这就是添加脚本的顺序很重要的原因。无论哪个脚本首先更新都能够打卡,因为第二个脚本会在重置之前看到触发器。但是,要更新的第二个脚本永远无法打卡,因为在其他脚本有机会更新之前触发器会重置。

一种解决方案是检查动画状态的名称而不是触发器值。

bIsEnemyPunching

或者,无论何时触发拳击,只需在任何角色被打孔时调用一个函数。因此,当敌人击打英雄时,敌人的static int punchStateHash = Animator.StringToHash("Punch"); AnimatorStateInfo enemyState = eAnim.GetCurrentAnimatorStateInfo(0); if (enemyState.nameHash == punchStateHash){ //The enemy is punching! } 功能应该在英雄上召唤Punch(...)(或者你想要称之为那些功能的任何东西)。然后英雄检查他自己的状态,以确定他是否阻止。

附加说明

您应该避免在更新功能中使用以下代码:

TakePunch(...)

这些函数非常慢,因为Unity必须在所有对象中搜索名为GameObject player = GameObject.Find("theDude"); Animator pAnim = player.GetComponent<Animator>(); 的对象,然后搜索它的所有组件以找到动画师。这样做一次并保存结果。