2017-04-07 106 views
0

的轉變我是新來Unity3D和我正在下面的教程:團結3D:動畫

https://www.youtube.com/watch?v=gXpi1czz5NA

這一切都工作得很好。

我想增加一些功能,如果骷髏用他的劍擊中了某物,他會真正回到他受傷的狀態。一個窮人的劍的方式與物體碰撞。

但我發現它無法正常工作。我似乎要麼選擇導致'命中'將其置於無限循環中,要麼一起忽略命中。這裏是我的代碼:

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

public class chase : MonoBehaviour { 

    public Transform player; 
    static Animator anim; 

    // Use this for initialization 
    void Start() { 
     anim = GetComponent<Animator>(); 
    } 

    // Update is called once per frame 
    void Update() { 
     //Debug.Log (anim.ToString()); 
     //Debug.Log ("Start Update"); 
     Vector3 direction = player.position - this.transform.position; 
     //Debug.Log ("Distance: " + direction.magnitude.ToString()); 
     float angle = Vector3.Angle (direction, this.transform.forward); 
     //Debug.Log ("Angle: " + angle.ToString()); 
     //Debug.Log(anim.GetCurrentAnimatorStateInfo(0).IsName("Damage")); 

     // Get top animation currently running 
     AnimatorStateInfo stateInfo = anim.GetCurrentAnimatorStateInfo(0); 

     if (Vector3.Distance (player.position, this.transform.position) < 10 && angle < 120 && !stateInfo.IsName ("Attack") && !anim.GetBool("Hit")) { 

      direction.y = 0; 
      this.transform.rotation = Quaternion.Slerp (this.transform.rotation, Quaternion.LookRotation (direction), 0.1f); 

      anim.SetBool ("isIdle", false); 
      if (direction.magnitude > 2) { 
       this.transform.Translate (0, 0, 0.03f); 
       anim.SetBool ("isWalking", true); 
       anim.SetBool ("isAttacking", false); 
       anim.SetBool ("Hit", false); 
      } else { 
       anim.SetBool ("isAttacking", true); 
       anim.SetBool ("isWalking", false); 
       anim.SetBool ("Hit", false); 
      } 
     } 
     else{ 
      anim.SetBool ("isIdle", true); 
      anim.SetBool ("isWalking", false); 
      anim.SetBool ("isAttacking", false); 
      anim.SetBool ("Hit", false); 
     } 
    } 
} 

,這裏是刀劍碰撞腳本:

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

public class SwordCollision : MonoBehaviour { 
    private Animator anim; 

    // We just collided with an object 
    private void OnTriggerEnter(Collider collider) { 
     int layer = collider.gameObject.layer; 
     anim = this.GetComponentInParent<Animator>(); 
     //Debug.Log (anim.ToString()); 
     if (layer != LayerMask.NameToLayer ("Floor") && layer != LayerMask.NameToLayer ("Monster")) { 
      Debug.Log ("Sword Hit something:" + collider.name.ToString()); 
      Debug.Log (LayerMask.LayerToName(layer)); 

      anim.SetBool ("isIdle", false); 
      anim.SetBool ("isWalking", false); 
      anim.SetBool ("isAttacking", false); 
      anim.SetBool ("Hit", true); // kicks off damage state 
     } 
    } 

} 

我設置的過渡攻擊和破壞動畫「已經退出時間」,使他們一路玩通過。其他轉換沒有這個,所以在發生'命中'時可以立即中斷它們。

這個問題似乎是,在劍衝突腳本註冊一個命中並將「命中」布爾值設置爲「true」(啓動損壞動畫)後,追逐腳本立即取消它,所以命中從未取得地點。 (即anim.SetBool(「命中」,假);)

然而,如果我註釋掉那條線,然後損壞動畫確實發生,但顯然它被卡在一個循環,因爲現在我沒有什麼可以關閉它關了。

這讓我把頭髮拉出來,因爲攻擊動畫幾乎完全相同。但我認爲一個人正確工作的原因是因爲布爾「isAttacking」在追逐腳本中不斷被設置爲'true',直到動畫真正開始。由於損壞動畫是從另一個腳本中啓動的,因此在允許追逐腳本更改「命中」的布爾值之前,確保動畫開始似乎並不容易。

有沒有辦法做到這一點?像延遲或確保動畫更改狀態的內容。或者,也許有辦法檢查更改布爾值之前「損壞」動畫何時完成?

回答

0

這是我終於想出的解決方案。有點哈克在我看來。我仍然覺得我沒有以最好的方式去做這件事。

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

public class chase : MonoBehaviour { 

    public Transform player; 
    static Animator anim; 

    // Use this for initialization 
    void Start() { 
     anim = GetComponent<Animator>(); 
    } 

    // Update is called once per frame 
    void Update() { 
     //Debug.Log (anim.ToString()); 
     //Debug.Log ("Start Update"); 
     Vector3 direction = player.position - this.transform.position; 
     //Debug.Log ("Distance: " + direction.magnitude.ToString()); 
     float angle = Vector3.Angle (direction, this.transform.forward); 
     //Debug.Log ("Angle: " + angle.ToString()); 
     //Debug.Log(anim.GetCurrentAnimatorStateInfo(0).IsName("Damage")); 

     // Get top animation currently running 
     AnimatorStateInfo stateInfo = anim.GetCurrentAnimatorStateInfo(0); 

     if (anim.GetBool("Hit") && !stateInfo.IsName ("Damage")) { 
      print ("keep going"); 
      anim.SetBool ("isIdle", false); 
      anim.SetBool ("isWalking", false); 
      anim.SetBool ("isAttacking", false); 
      anim.SetBool ("Hit", true); 
     } 
     else if (Vector3.Distance (player.position, this.transform.position) < 10 && angle < 120 && !stateInfo.IsName ("Attack") && !stateInfo.IsName ("Damage")) { 

      direction.y = 0; 
      this.transform.rotation = Quaternion.Slerp (this.transform.rotation, Quaternion.LookRotation (direction), 0.1f); 

      anim.SetBool ("isIdle", false); 
      if (direction.magnitude > 2) { 
       print ("Following"); 
       //this.transform.Translate (0, 0, 0.03f); 
       anim.SetBool ("isWalking", true); 
       anim.SetBool ("isAttacking", false); 
       anim.SetBool ("Hit", false); 
      } else { 
       print ("Attacking"); 
       anim.SetBool ("isAttacking", true); 
       anim.SetBool ("isWalking", false); 
       anim.SetBool ("Hit", false); 
      } 
     } 
     else { 
      print("Back to Idle"); 
      anim.SetBool ("isIdle", true); 
      anim.SetBool ("isWalking", false); 
      anim.SetBool ("isAttacking", false); 
      anim.SetBool ("Hit", false); 
     } 
    } 
}