Wednesday, 5 March 2014

05/03/14 - Stealth Project Tutorial

Today I have been watching the Unity Stealth Project tutorials about the enemy AI again, still trying to figure out how to incoportate how they have coded the Enemy Sight part of the tutorial and how I can then implement this in the existing code I have from a Tutorial Alister gave the class earlier in the year (I will copy and paste the code below rather than print screen it, because it is too long to print screen, and I shall apologize now for how long this post will be because of this!!). So far we have teddy bears (acting as the alien enemy) moving around to waypoints, and then when they come to in to contact with one another, the 'throw' animation plays. What we want to have is, the enemy chases the player when they come in to the enemys field of vision, once/ if/ when they have caught up to the player, the 'throw' animation will play, and the player will die. I am going to start working on a player health script this week as well.

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;

 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