Wednesday, 6 November 2013

AI_Patrol script

using UnityEngine;
using System.Collections;
public class AI_Patrol : MonoBehaviour
{
 //-----------------------------------------------------------------------------
 #region public_vars
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------

 public enum AIState { none, idle, walking, run }

 public float patrolSpeed = 2F;       // The nav mesh agent's speed when patrolling.
 public float patrolWaitTime = 1F;      // The amount of time to wait when the patrol way point is reached.

 public float patrolSpeedDamper = 5F;     // Patrol at 1/5th of animation speed

 public AIState currentAIState = AIState.none;

 public float speed = 0.5f;

 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 #endregion
 //-----------------------------------------------------------------------------

 //-----------------------------------------------------------------------------
 #region private_vars
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // constants

 private const float MIN_NAVAGENT_SPEED = 0.1F;
 private const float MAX_NAVAGENT_SPEED = 1.25F;
 private const float m_SpeedDampTime = .25f;
 private const float m_DirectionDampTime = .25f;

 private int   m_WayPointIndex = 0;

 private int maxWaypointIndex = 0;

 private NavMeshAgent nmaAI = null;
 private Animator animatorAI = null;

 private const float MIN_IDLE_TIME = 2;
 private const float MAX_IDLE_TIME = 8;


 private int currentWaypointIndex = 0;

 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 #endregion
 //-----------------------------------------------------------------------------

 //-----------------------------------------------------------------------------
 #region public_methods
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 #endregion
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 #region private_methods
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------

 void Awake()
 {
  nmaAI = GetComponent<NavMeshAgent>();
 }

 //-----------------------------------------------------------------------------
 // Use this for initialization
 void Start ()
 {
  animatorAI = GetComponent<Animator>();

  StartCoroutine( Idle() );

 }

 void OnTriggerEnter( Collider hit)
 {
  Debug.Log("AI_Patrol: OnTriggerStay hit: "+hit.gameObject.tag);

  if( hit.gameObject.tag == "Enemy" )
  {
   Throw ( hit.gameObject );
  }
 }


 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 IEnumerator Idle()
 {
  currentAIState = AIState.idle;

  float randomIdleTime = Random.Range( MIN_IDLE_TIME, MAX_IDLE_TIME ) + Time.time;

  while( randomIdleTime > Time.time )
  {
   animatorAI.SetFloat("Speed",0 );
   nmaAI.speed = 0 ;
 
   yield return null;
  }
  
  StartCoroutine( Patrolling() );
 }

 //-----------------------------------------------------------------------------
 IEnumerator Patrolling ()
 {
  currentAIState = AIState.walking;

  // Set an appropriate speed for the NavMeshAgent.
  nmaAI.speed = Mathf.Clamp( animatorAI.GetFloat( "Speed" ) / patrolSpeedDamper, MIN_NAVAGENT_SPEED, MAX_NAVAGENT_SPEED );

  // Set the destination to a random patrolWayPoint.
  //nmaAI.destination = Waypoints.GetRandomWaypoint();

  nmaAI.destination = Waypoints.GetWaypoint(currentWaypointIndex);
  currentWaypointIndex++;

  bool endPatrol = false;
  
  // While not near the next waypoint or while there is a destination...
  while( !endPatrol )
  {
   if( Vector3.Distance( nmaAI.destination, animatorAI.rootPosition ) > nmaAI.stoppingDistance )
   {
    animatorAI.SetFloat( "Speed", MAX_NAVAGENT_SPEED,m_SpeedDampTime, Time.deltaTime );
  
    Vector3 curentDir = animatorAI.rootRotation * Vector3.forward;
    Vector3 wantedDir = ( nmaAI.destination - animatorAI.rootPosition ).normalized;

    if( Vector3.Dot( curentDir, wantedDir ) > 0 )
    {
     animatorAI.SetFloat( "Direction", Vector3.Cross(curentDir, wantedDir ).y, m_DirectionDampTime, Time.deltaTime );
    }
    else
    {
              animatorAI.SetFloat( "Direction", Vector3.Cross(curentDir, wantedDir ).y > 0 ? 1 : -1, m_DirectionDampTime, Time.deltaTime);
    }
    nmaAI.speed = Mathf.Clamp( animatorAI.GetFloat( "Speed" ) / patrolSpeedDamper, MIN_NAVAGENT_SPEED, MAX_NAVAGENT_SPEED );
   }
   else
   {
     endPatrol = true;
   }
 
 
   yield return null;
  }

  StartCoroutine( Idle() );
 }
 //-----------------------------------------------------------------------------
private bool throwing = false;

 public void Throw( GameObject hitObject )
 {
  if( !throwing )
  {
   StartCoroutine( AnimateThrow( hitObject ) );
  }
 }

 public float rotationDelta;

 IEnumerator AnimateThrow( GameObject hitObject )
 {
  if( !throwing )
  {
   throwing = true;
 
   animatorAI.SetBool( "Throw", true);
   yield return new WaitForEndOfFrame();
 
   AnimatorStateInfo stateInfo = animatorAI.GetCurrentAnimatorStateInfo( 0 );
 
   animatorAI.SetBool( "Throw", false);
    
      // transform.LookAt( hitObject.transform.position );
   bool rotating = true;
 
   float endOfThrowTime = stateInfo.length + Time.time;
   float step = speed * Time.deltaTime;
 
   while( rotating)
   {
  
    Vector3 targetDir = hitObject.transform.position - transform.position;
  
    Vector3 newDir = Vector3.RotateTowards(transform.forward, targetDir, step, 0.0F);
  
    Debug.DrawRay(transform.position, newDir, Color.red);
  
    transform.rotation = Quaternion.LookRotation(newDir);
    
   
//    if(Mathf.Abs( (int) rotationDelta ) > 179 )
    if( endOfThrowTime < Time.time )
    {
     rotating = false;
    }
  
    yield return null;
  
   }
  
   transform.LookAt( hitObject.transform.position );
 
//   yield return new WaitForSeconds( stateInfo.length );
 
   throwing = false;
  }
 }


 //-----------------------------------------------------------------------------
 #endregion
 //-----------------------------------------------------------------------------




}

No comments:

Post a Comment