Wednesday, 6 November 2013

AI_Patrol script

This script is what we were taught in todays lesson. Alister our coding teacher taught us with placeholder teddy bears how to have it so that they could patrol around the scene, by going to different waypoints. The teddy bears can travel to these waypoints in chronological order if one so wished, or they could be randomized - entirely depends on what is wanted for the game. This will be good for our game because of our Aliens, they will be able to patrol different areas of the map and the player will have to avoid them.

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