|  | 
 
| 本帖最后由 夜行的猫仔 于 2014-1-15 11:40 编辑 
 C#脚本
 JS脚本复制代码using UnityEngine;
using System.Collections;
public class EnemyAnimation : MonoBehaviour
{
        public float deadZone = 5f;             // 不受Mecanim动画系统控制的旋转角度.
                
        private Transform player;               // player矩阵变量.
        private EnemySight enemySight;          // EnemySight脚本变量.
        private NavMeshAgent nav;               // 寻路脚本变量.
        private Animator anim;                  // Animator变量.
        private HashIDs hash;                   // HashIDs 脚本变量.
        private AnimatorSetup animSetup;        // 动作设置辅助类变量.
        
        
        void Awake ()
        {
                // 初始化
                player = GameObject.FindGameObjectWithTag(Tags.player).transform;
                enemySight = GetComponent<EnemySight>();
                nav = GetComponent<NavMeshAgent>();
                anim = GetComponent<Animator>();
                hash = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent<HashIDs>();
                
                // 是否被Mecanim动画系统控制标志位.
                nav.updateRotation = false;
                
                // 创建AnimatorSetup变量
                animSetup = new AnimatorSetup(anim, hash);
                
                // 设置shooting和gun动画层的权重1.
                anim.SetLayerWeight(1, 1f);
                anim.SetLayerWeight(2, 1f);
                
                // 我们需要将度转化为弧度.
                // Mathf.Deg2Rad是一个从角度转化为弧度的常量:deadZone = deadZone*Mathf.Deg2Rad;
                deadZone *= Mathf.Deg2Rad;
        }
        
        
        void Update () 
        {
                // 通过自动寻路系统驱动角色动画.
                NavAnimSetup();
        }
        
        
        void OnAnimatorMove ()
        {
                // 根据动画中移动的位置来设定寻路的速度
                nav.velocity = anim.deltaPosition / Time.deltaTime;
                
                // 通过动画旋转值设定角色旋转角度
                transform.rotation = anim.rootRotation;
        }
        
        
        void NavAnimSetup ()
        {
                // 创建两个变量,用于AnimatorSetup设置
                float speed;
                float angle;
                
                // 如果玩家暴露在敌人的视野里...
                if(enemySight.playerInSight)
                {
                        // ... 敌人角色就会停止移动...
                        speed = 0f;
                        
                        // ... 并且会将正面转向正对玩家
                        angle = FindAngle(transform.forward, player.position - transform.position, transform.up);
                }
                else
                {
                        // 否则速度就等于 自动寻路中设定的寻路速度在forward方向上的分量..
                        // Vector3.Project一个向量向另外一个向量的投影
                        speed = Vector3.Project(nav.desiredVelocity, transform.forward).magnitude;
                        
                        // ... 角度是朝向和期望运动间的夹角.
                        angle = FindAngle(transform.forward, nav.desiredVelocity, transform.up);
                        
                        // 如果夹角在deadZone之间...
                        if(Mathf.Abs(angle) < deadZone)
                        {
                                // ... set the direction to be along the desired direction and set the angle to be zero.
                                // transform.LookAt函数将物体的z轴指向目标。
                                transform.LookAt(transform.position + nav.desiredVelocity);
                                angle = 0f;
                        }
                }
                
                // 通过上面的计算所得到的值设置动作.
                animSetup.Setup(speed, angle);
        }
        
        
        float FindAngle (Vector3 fromVector, Vector3 toVector, Vector3 upVector)
        {
                //  如果toVector是 0...
                if(toVector == Vector3.zero)
                        // ... 他们之间的角度是 0.
                        return 0f;
                
                // Create a float to store the angle between the facing of the enemy and the direction it's travelling.
                // 创建一个浮点数记录从fromVector到toVector之间的夹角。(这个夹角是敌人面朝的方向和移动的方向之间的)
                float angle = Vector3.Angle(fromVector, toVector);
                
                // Find the cross product of the two vectors (this will point up if the velocity is to the right of forward).
                // 求得两个向量的叉乘(求fromVector和toVector两个向量的法线)
                Vector3 normal = Vector3.Cross(fromVector, toVector);
                
                // The dot product of the normal with the upVector will be positive if they point in the same direction.
                // 与upVector点乘的结果来判断他们是否指向同一方向。
                angle *= Mathf.Sign(Vector3.Dot(normal, upVector));
                
                // 角度转化为弧度
                angle *= Mathf.Deg2Rad;
                
                return angle;
        }
}
相关知识:复制代码#pragma strict
public var deadZone : float = 5f;           // The number of degrees for which the rotation isn't controlled by Mecanim.
private var player : Transform;             // Reference to the player's transform.
private var enemySight : EnemySight;        // Reference to the EnemySight script.
private var nav : NavMeshAgent;             // Reference to the nav mesh agent.
private var anim : Animator;                // Reference to the Animator.
private var hash : HashIDs;                 // Reference to the HashIDs script.
private var animSetup : AnimatorSetup;      // An instance of the AnimatorSetup helper class.
function Awake ()
{
    // Setting up the references.
    player = GameObject.FindGameObjectWithTag(Tags.player).transform;
    enemySight = GetComponent(EnemySight);
    nav = GetComponent(NavMeshAgent);
    anim = GetComponent(Animator);
    hash = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent(HashIDs);
    
    // Making sure the rotation is controlled by Mecanim.
    nav.updateRotation = false;
    
    // Creating an instance of the AnimatorSetup class and calling it's constructor.
    animSetup = new AnimatorSetup(anim, hash);
    
    // Set the weights for the shooting and gun layers to 1.
    anim.SetLayerWeight(1, 1f);
    anim.SetLayerWeight(2, 1f);
    
    // We need to convert the angle for the deadzone from degrees to radians.
    deadZone *= Mathf.Deg2Rad;
}
function Update () 
{
    // Calculate the parameters that need to be passed to the animator component.
    NavAnimSetup();
}
function OnAnimatorMove ()
{
    // Set the NavMeshAgent's velocity to the change in position since the last frame, by the time it took for the last frame.
    nav.velocity = anim.deltaPosition / Time.deltaTime;
    
    // The gameobject's rotation is driven by the animation's rotation.
    transform.rotation = anim.rootRotation;
}
function NavAnimSetup ()
{
    // Create the parameters to pass to the helper function.
    var speed : float;
    var angle : float;
    
    // If the player is in sight...
    if(enemySight.playerInSight)
    {
        // ... the enemy should stop...
        speed = 0f;
        
        // ... and the angle to turn through is towards the player.
        angle = FindAngle(transform.forward, player.position - transform.position, transform.up);
    }
    else
    {
        // Otherwise the speed is a projection of desired velocity on to the forward vector...
        speed = Vector3.Project(nav.desiredVelocity, transform.forward).magnitude;
        
        // ... and the angle is the angle between forward and the desired velocity.
        angle = FindAngle(transform.forward, nav.desiredVelocity, transform.up);
        
        // If the angle is within the deadZone...
        if(Mathf.Abs(angle) < deadZone)
        {
            // ... set the direction to be along the desired direction and set the angle to be zero.
            transform.LookAt(transform.position + nav.desiredVelocity);
            angle = 0f;
        }
    }
    
    // Call the Setup function of the helper class with the given parameters.
    animSetup.Setup(speed, angle);
}
function FindAngle (fromVector : Vector3, toVector : Vector3, upVector : Vector3) : float
{
    // If the vector the angle is being calculated to is 0...
    if(toVector == Vector3.zero)
        // ... the angle between them is 0.
        return 0f;
    
    // Create a float to store the angle between the facing of the enemy and the direction it's travelling.
    var angle : float = Vector3.Angle(fromVector, toVector);
    
    // Find the cross product of the two vectors (this will point up if the velocity is to the right of forward).
    var normal : Vector3 = Vector3.Cross(fromVector, toVector);
    
    // The dot product of the normal with the upVector will be positive if they point in the same direction.
    angle *= Mathf.Sign(Vector3.Dot(normal, upVector));
    
    // We need to convert the angle we've found from degrees to radians.
    angle *= Mathf.Deg2Rad;
    return angle;
}
NavMeshAgent 自动寻路控制组件
 
 
 | 
 |