【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 1981|回复: 0

7-4 Enemy Animation 敌人的动画

[复制链接]
发表于 2013-10-17 13:13:32 | 显示全部楼层 |阅读模式
本帖最后由 夜行的猫仔 于 2014-1-15 11:40 编辑

C#脚本
  1. using UnityEngine;
  2. using System.Collections;

  3. public class EnemyAnimation : MonoBehaviour
  4. {
  5.         public float deadZone = 5f;             // 不受Mecanim动画系统控制的旋转角度.
  6.                
  7.         private Transform player;               // player矩阵变量.
  8.         private EnemySight enemySight;          // EnemySight脚本变量.
  9.         private NavMeshAgent nav;               // 寻路脚本变量.
  10.         private Animator anim;                  // Animator变量.
  11.         private HashIDs hash;                   // HashIDs 脚本变量.
  12.         private AnimatorSetup animSetup;        // 动作设置辅助类变量.
  13.        
  14.        
  15.         void Awake ()
  16.         {
  17.                 // 初始化
  18.                 player = GameObject.FindGameObjectWithTag(Tags.player).transform;
  19.                 enemySight = GetComponent<EnemySight>();
  20.                 nav = GetComponent<NavMeshAgent>();
  21.                 anim = GetComponent<Animator>();
  22.                 hash = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent<HashIDs>();
  23.                
  24.                 // 是否被Mecanim动画系统控制标志位.
  25.                 nav.updateRotation = false;
  26.                
  27.                 // 创建AnimatorSetup变量
  28.                 animSetup = new AnimatorSetup(anim, hash);
  29.                
  30.                 // 设置shooting和gun动画层的权重1.
  31.                 anim.SetLayerWeight(1, 1f);
  32.                 anim.SetLayerWeight(2, 1f);
  33.                
  34.                 // 我们需要将度转化为弧度.
  35.                 // Mathf.Deg2Rad是一个从角度转化为弧度的常量:deadZone = deadZone*Mathf.Deg2Rad;
  36.                 deadZone *= Mathf.Deg2Rad;
  37.         }
  38.        
  39.        
  40.         void Update ()
  41.         {
  42.                 // 通过自动寻路系统驱动角色动画.
  43.                 NavAnimSetup();
  44.         }
  45.        
  46.        
  47.         void OnAnimatorMove ()
  48.         {
  49.                 // 根据动画中移动的位置来设定寻路的速度
  50.                 nav.velocity = anim.deltaPosition / Time.deltaTime;
  51.                
  52.                 // 通过动画旋转值设定角色旋转角度
  53.                 transform.rotation = anim.rootRotation;
  54.         }
  55.        
  56.        
  57.         void NavAnimSetup ()
  58.         {
  59.                 // 创建两个变量,用于AnimatorSetup设置
  60.                 float speed;
  61.                 float angle;
  62.                
  63.                 // 如果玩家暴露在敌人的视野里...
  64.                 if(enemySight.playerInSight)
  65.                 {
  66.                         // ... 敌人角色就会停止移动...
  67.                         speed = 0f;
  68.                        
  69.                         // ... 并且会将正面转向正对玩家
  70.                         angle = FindAngle(transform.forward, player.position - transform.position, transform.up);
  71.                 }
  72.                 else
  73.                 {
  74.                         // 否则速度就等于 自动寻路中设定的寻路速度在forward方向上的分量..
  75.                         // Vector3.Project一个向量向另外一个向量的投影
  76.                         speed = Vector3.Project(nav.desiredVelocity, transform.forward).magnitude;
  77.                        
  78.                         // ... 角度是朝向和期望运动间的夹角.
  79.                         angle = FindAngle(transform.forward, nav.desiredVelocity, transform.up);
  80.                        
  81.                         // 如果夹角在deadZone之间...
  82.                         if(Mathf.Abs(angle) < deadZone)
  83.                         {
  84.                                 // ... set the direction to be along the desired direction and set the angle to be zero.
  85.                                 // transform.LookAt函数将物体的z轴指向目标。
  86.                                 transform.LookAt(transform.position + nav.desiredVelocity);
  87.                                 angle = 0f;
  88.                         }
  89.                 }
  90.                
  91.                 // 通过上面的计算所得到的值设置动作.
  92.                 animSetup.Setup(speed, angle);
  93.         }
  94.        
  95.        
  96.         float FindAngle (Vector3 fromVector, Vector3 toVector, Vector3 upVector)
  97.         {
  98.                 //  如果toVector是 0...
  99.                 if(toVector == Vector3.zero)
  100.                         // ... 他们之间的角度是 0.
  101.                         return 0f;
  102.                
  103.                 // Create a float to store the angle between the facing of the enemy and the direction it's travelling.
  104.                 // 创建一个浮点数记录从fromVector到toVector之间的夹角。(这个夹角是敌人面朝的方向和移动的方向之间的)
  105.                 float angle = Vector3.Angle(fromVector, toVector);
  106.                
  107.                 // Find the cross product of the two vectors (this will point up if the velocity is to the right of forward).
  108.                 // 求得两个向量的叉乘(求fromVector和toVector两个向量的法线)
  109.                 Vector3 normal = Vector3.Cross(fromVector, toVector);
  110.                
  111.                 // The dot product of the normal with the upVector will be positive if they point in the same direction.
  112.                 // 与upVector点乘的结果来判断他们是否指向同一方向。
  113.                 angle *= Mathf.Sign(Vector3.Dot(normal, upVector));
  114.                
  115.                 // 角度转化为弧度
  116.                 angle *= Mathf.Deg2Rad;
  117.                
  118.                 return angle;
  119.         }
  120. }
复制代码
JS脚本
  1. #pragma strict

  2. public var deadZone : float = 5f;           // The number of degrees for which the rotation isn't controlled by Mecanim.


  3. private var player : Transform;             // Reference to the player's transform.
  4. private var enemySight : EnemySight;        // Reference to the EnemySight script.
  5. private var nav : NavMeshAgent;             // Reference to the nav mesh agent.
  6. private var anim : Animator;                // Reference to the Animator.
  7. private var hash : HashIDs;                 // Reference to the HashIDs script.
  8. private var animSetup : AnimatorSetup;      // An instance of the AnimatorSetup helper class.


  9. function Awake ()
  10. {
  11.     // Setting up the references.
  12.     player = GameObject.FindGameObjectWithTag(Tags.player).transform;
  13.     enemySight = GetComponent(EnemySight);
  14.     nav = GetComponent(NavMeshAgent);
  15.     anim = GetComponent(Animator);
  16.     hash = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent(HashIDs);
  17.    
  18.     // Making sure the rotation is controlled by Mecanim.
  19.     nav.updateRotation = false;
  20.    
  21.     // Creating an instance of the AnimatorSetup class and calling it's constructor.
  22.     animSetup = new AnimatorSetup(anim, hash);
  23.    
  24.     // Set the weights for the shooting and gun layers to 1.
  25.     anim.SetLayerWeight(1, 1f);
  26.     anim.SetLayerWeight(2, 1f);
  27.    
  28.     // We need to convert the angle for the deadzone from degrees to radians.
  29.     deadZone *= Mathf.Deg2Rad;
  30. }


  31. function Update ()
  32. {
  33.     // Calculate the parameters that need to be passed to the animator component.
  34.     NavAnimSetup();
  35. }


  36. function OnAnimatorMove ()
  37. {
  38.     // Set the NavMeshAgent's velocity to the change in position since the last frame, by the time it took for the last frame.
  39.     nav.velocity = anim.deltaPosition / Time.deltaTime;
  40.    
  41.     // The gameobject's rotation is driven by the animation's rotation.
  42.     transform.rotation = anim.rootRotation;
  43. }


  44. function NavAnimSetup ()
  45. {
  46.     // Create the parameters to pass to the helper function.
  47.     var speed : float;
  48.     var angle : float;
  49.    
  50.     // If the player is in sight...
  51.     if(enemySight.playerInSight)
  52.     {
  53.         // ... the enemy should stop...
  54.         speed = 0f;
  55.         
  56.         // ... and the angle to turn through is towards the player.
  57.         angle = FindAngle(transform.forward, player.position - transform.position, transform.up);
  58.     }
  59.     else
  60.     {
  61.         // Otherwise the speed is a projection of desired velocity on to the forward vector...
  62.         speed = Vector3.Project(nav.desiredVelocity, transform.forward).magnitude;
  63.         
  64.         // ... and the angle is the angle between forward and the desired velocity.
  65.         angle = FindAngle(transform.forward, nav.desiredVelocity, transform.up);
  66.         
  67.         // If the angle is within the deadZone...
  68.         if(Mathf.Abs(angle) < deadZone)
  69.         {
  70.             // ... set the direction to be along the desired direction and set the angle to be zero.
  71.             transform.LookAt(transform.position + nav.desiredVelocity);
  72.             angle = 0f;
  73.         }
  74.     }
  75.    
  76.     // Call the Setup function of the helper class with the given parameters.
  77.     animSetup.Setup(speed, angle);
  78. }


  79. function FindAngle (fromVector : Vector3, toVector : Vector3, upVector : Vector3) : float
  80. {
  81.     // If the vector the angle is being calculated to is 0...
  82.     if(toVector == Vector3.zero)
  83.         // ... the angle between them is 0.
  84.         return 0f;
  85.    
  86.     // Create a float to store the angle between the facing of the enemy and the direction it's travelling.
  87.     var angle : float = Vector3.Angle(fromVector, toVector);
  88.    
  89.     // Find the cross product of the two vectors (this will point up if the velocity is to the right of forward).
  90.     var normal : Vector3 = Vector3.Cross(fromVector, toVector);
  91.    
  92.     // The dot product of the normal with the upVector will be positive if they point in the same direction.
  93.     angle *= Mathf.Sign(Vector3.Dot(normal, upVector));
  94.    
  95.     // We need to convert the angle we've found from degrees to radians.
  96.     angle *= Mathf.Deg2Rad;

  97.     return angle;
  98. }
复制代码
相关知识:
NavMeshAgent 自动寻路控制组件

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2024-5-6 17:02

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表