0

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

我有一个英雄和一个敌人。这是一款格斗游戏。英雄和敌人在动画控制器中都有空闲、阻挡、出拳和 getHit 动画和状态。英雄和敌人都附有脚本。英雄由玩家控制,敌人由AI控制。

现在我先将脚本附加到英雄,然后再附加到敌人。现在,当敌人出拳并且英雄没有防守时,英雄就会受到打击。但是如果敌人没有阻挡并且英雄击中敌人则不会受到打击。这是因为脚本首先附加到 hero

现在,如果我从两者中删除脚本并首先将敌人脚本附加到敌人,然后将英雄脚本附加到英雄。明智的做法是正确的。在敌人身上会记录命中,而在英雄身上不会记录命中。

我不确定为什么会发生这种情况,我尝试了不同的方法,但问题仍然存在。

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

谢谢 :)

下面是检查敌人是否可以被击中的敌人脚本

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");

        }
    }
 }

我以前没有获取对象,而是拥有一个公共游戏对象,并将英雄和敌人附加到各自的类中。但它没有任何区别。

4

1 回答 1

1

我认为您的问题在于您使用触发器tEnemyIsPunchingtIsPunching. 触发器在导致转换发生时被重置

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

在您的情况下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 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在Hero进行更改检查之前就被重置了。

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

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

static int punchStateHash = Animator.StringToHash("Punch");  
AnimatorStateInfo enemyState = eAnim.GetCurrentAnimatorStateInfo(0);

 if (enemyState.nameHash == punchStateHash){
      //The enemy is punching!
 }

或者,每当触发一拳时,只需在被拳打的任何角色上调用一个函数。因此,当敌人打英雄时,敌人Punch(...)上的函数应该调用TakePunch(...)hero(或任何你想调用的函数)。英雄然后检查他自己的状态以确定他是否正在阻止。

附加说明

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

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

这些函数非常慢,因为 Unity 必须搜索所有对象以找到被调用的对象theDude,然后搜索其所有组件以找到动画师。这样做一次并保存结果。

于 2017-01-24T18:57:30.660 回答