2017-01-24 3 views
0

Позвольте мне сначала задать вопрос :)Проверка сценария Animator on Unity работает только на первом объекте

У меня есть герой и враг. Это боевая игра. И герой, и враг имеют простаивающие, блокирующие, удары и анимации getHit и состояния в Animation Controller. У героя и врага есть прикрепленные к ним сценарии. Герой контролируется игроком, а затем врагом является контроллер 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

Я думаю, что ваша проблема заключается в использовании триггеров tEnemyIsPunching и tIsPunching. Триггеры сбрасываются всякий раз, когда они приводят к возникновению перехода

(см .: 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 

Итак, Герой никогда не видит удар, потому что bIsEnemyPunching получил сброс до того, как у Героя произошли изменения, чтобы проверить его.

Именно поэтому порядок добавления скриптов имеет значение. Независимо от того, какие обновления скриптов в первую очередь могут ударить, потому что второй скрипт увидит триггер до его сброса. Тем не менее, второй скрипт для обновления никогда не сможет ударить, потому что триггер будет сброшен, прежде чем другие скрипты получат возможность обновления.

Одним из решений является проверка имени состояния анимации вместо значения триггера.

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

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

В качестве альтернативы, каждый раз, когда срабатывает пуансон, вызывается функция только на том, какой символ получает перфорация. Поэтому, когда противник ударяет героя, функция Punch(...) на враге должна вызывать TakePunch(...) на героя (или как вы хотите назвать эти функции). Затем герой проверяет свое состояние, чтобы определить, блокирует ли он.

Дополнительное примечание

Вы должны избегать, используя следующий код в функции обновления:

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

Эти функции являются очень медленно, потому что Unity должны искать все объекты для одного называется theDude, а затем искать все это компоненты для поиска аниматора. Сделайте это один раз и сохраните результат.