|
本帖最后由 夜行的猫仔 于 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 自动寻路控制组件
|
|