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