【问题标题】:Unity 3D: Transition of AnimationUnity 3D:动画过渡
【发布时间】:2017-04-09 01:48:18
【问题描述】:

我是 Unity3D 的新手,我正在学习以下教程:

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
        }
    }

}

我将攻击和伤害动画的过渡设置为“有退出时间”,这样它们就可以一直播放。其他转换没有此功能,因此可以在“命中”发生时立即中断。

问题似乎是在剑碰撞脚本注册命中并将“命中”布尔值设置为“真”(以启动伤害动画)后,追逐脚本立即取消它,因此命中永远不会发生. (即 anim.SetBool ("Hit", false);)

但是,如果我注释掉该行,那么伤害动画确实会发生,但显然它会卡在一个循环中,因为现在我没有什么可以关闭它了。

这导致我拔掉头发,因为攻击动画的设置几乎相同。但我认为一个正常工作的原因是因为布尔值“isAttacking”在追逐脚本中不断设置为“true”,直到动画真正开始。因为伤害动画是从不同的脚本开始的,所以在允许追逐脚本更改“命中”的布尔值之前,我似乎没有一种简单的方法来确保动画开始。

有没有办法做到这一点?像延迟或保证动画改变状态的东西。或者可能是一种在更改布尔值之前检查“损坏”动画何时完成的方法?

【问题讨论】:

    标签: animation unity3d state-machine


    【解决方案1】:

    这是我最终想出的解决方案。在我看来有点hacky。我仍然觉得我没有以最好的方式做到这一点。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-27
      • 1970-01-01
      • 2017-07-17
      • 1970-01-01
      • 2019-11-28
      相关资源
      最近更新 更多