unity官方demo学习之Stealth(二十二)敌人动画控制

首先先声明一点,unity是基于左手坐标系的(查找纠结了半天,最后才发现法向量左右手的规则是基于坐标系是左右手的)

接下来继续为敌人添加脚本DoneEnemyAnimation

using UnityEngine;
using System.Collections;

public class DoneEnemyAnimation : MonoBehaviour
{
	public float deadZone = 5f;					// The number of degrees for which the rotation isn't controlled by Mecanim.
	
	
	private Transform player;					// Reference to the player's transform.
	private DoneEnemySight enemySight;			// Reference to the EnemySight script.
	private NavMeshAgent nav;					// Reference to the nav mesh agent.
	private Animator anim;						// Reference to the Animator.
	private DoneHashIDs hash;					// Reference to the HashIDs script.
	private DoneAnimatorSetup animSetup;		// An instance of the AnimatorSetup helper class.


	void Awake ()
	{
		// Setting up the references.
		player = GameObject.FindGameObjectWithTag(DoneTags.player).transform;
		enemySight = GetComponent<DoneEnemySight>();
		nav = GetComponent<NavMeshAgent>();
		anim = GetComponent<Animator>();
		hash = GameObject.FindGameObjectWithTag(DoneTags.gameController).GetComponent<DoneHashIDs>();
		
		// 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 DoneAnimatorSetup(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;
	}
	
	
	void Update () 
	{
		// Calculate the parameters that need to be passed to the animator component.
		NavAnimSetup();
	}
	
	
	void 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;
    }
	
	
	void NavAnimSetup ()
	{
		// Create the parameters to pass to the helper function.
		float speed;
		float angle;
		
		// 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);
	}
	
	
	float FindAngle (Vector3 fromVector, Vector3 toVector, Vector3 upVector)
	{
		// 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.
		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).
		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.
		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;
	}
}


参数(公有)

当角度小于这个变量时 转向将不再使用动画系统控制(如果没有这个变量,敌人在转弯后走向下一个点时会由于转弯(实际速度向期望速度偏移,之前设置了转弯缓冲时间,所以转到正确角度不会立即停止,转过头之后再从反方向向正确方向转动,这样转来转去就成曲线运动了)过度走曲线而非直线)

(私有)

引用玩家Transform  

引用EnemySight脚本

引用nav mesh agent组件

引用Animator组件

引用HashIDs脚本

AnimatorSetup辅助类的实例


函数

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值