2017-04-07 93 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); 
     } 
    } 
}