2017-04-07 16 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 
     } 
    } 

} 

I遷移は攻撃するために、セットアップおよび損傷アニメーション彼らはすべての方法を果たしなるように、「終了時間を持っている」しますスルー。他のトランジションにはこれがありませんので、すぐに「ヒット」が発生したときに中断することができます。

剣の衝​​突スクリプトがヒットを登録し、「ヒット」ブール値を「真」(ダメージアニメーションを開始する)に設定すると、チェーススクリプトは直ちにそれをキャンセルしてヒットしない場所。 (すなわち、anim.SetBool( "Hit"、false);)

しかし、私がその行をコメントアウトすると、ダメージアニメーションが実行されますが、明らかに、私はシャットダウンするものがないのでループに詰まってしまいますそれをオフにします。

攻撃のアニメーションがほぼ同じように設定されているため、これで私の髪の毛が引っ張られていました。しかし、アニメーションが実際に始まるまで、boolean "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); 
     } 
    } 
} 
関連する問題