| 
 | 
 
 本帖最后由 夜行的猫仔 于 2014-1-15 11:40 编辑  
 
C#脚本- 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;
 
 -         }
 
 - }
 
  复制代码 JS脚本- #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 自动寻路控制组件 
 
 |   
 
 
 
 |