Last active
August 29, 2015 14:07
-
-
Save EnriqueSoria/c9e167aed75cd1b529e2 to your computer and use it in GitHub Desktop.
EnemyBehaviour.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
public class EnemyBehaviour : MonoBehaviour { | |
/* PUBLIC variables */ | |
public const int maxHealth = 100; | |
public const int maxDamage = 20; | |
LineRenderer line; | |
GUIText text; | |
bool coroutine; | |
/* PRIVATE variables*/ | |
// Programming stuff | |
private NavMeshAgent agent; | |
private Transform target; | |
// Patrolling | |
private bool patrolling; | |
private int destination; | |
private Transform[] patrolPoints; | |
// Object info | |
private int health; | |
/* Public methods */ | |
public void ApplyDammage(int TheDamage) { | |
health -= TheDamage; | |
if (health <= 0){ | |
Die(); | |
} | |
} | |
public void Die(){ | |
Destroy(gameObject); | |
} | |
/** | |
* Start function | |
*/ | |
void Start () { | |
coroutine = false; | |
line = (LineRenderer) this.gameObject.AddComponent("LineRenderer"); | |
patrolling = true; | |
health = maxHealth; | |
// Patrolling stuff | |
patrolPoints = FindTransformWithTag("Point"); | |
agent = (NavMeshAgent) this.GetComponent("NavMeshAgent"); | |
destination = GetDestination( -1 ); | |
Vector3 dst = patrolPoints[ destination ].position; | |
agent.SetDestination ( dst ); | |
} | |
/** | |
* Update function | |
* Called once per frame | |
*/ | |
void Update () { | |
if ( patrolling ) { | |
if ( !agent.hasPath || agent.remainingDistance < 0.5f ) { | |
SetNewRandomDestination(); | |
} | |
} else { | |
if ( target != null ) { | |
// Find a place to cover | |
// Shoot | |
if ( !coroutine ) { | |
StartCoroutine("ShootAndHide"); | |
coroutine = true; | |
} | |
} else { | |
patrolling = true; | |
} | |
} | |
} | |
IEnumerator ShootAndHide() { | |
// Get covered | |
Transform[] covers = FindTransformWithTag("Cover"); | |
Vector3 closest = FindClosestPosition( this.transform.position, covers ); | |
this.agent.SetDestination( closest ); | |
while ( agent.pathStatus == NavMeshPathStatus.PathComplete /*|| agent.remainingDistance > 0.5f */) | |
yield return null; | |
for ( bool shootOrHide = true ; ; shootOrHide = !shootOrHide) { | |
if ( shootOrHide ) { | |
// Shoot | |
if ( !isVisible(target) ) { | |
agent.SetDestination(target.position); | |
} else { | |
agent.SetDestination(this.transform.position); // Stop moving | |
this.transform.LookAt(target); | |
// now shoot | |
} | |
yield return new WaitForSeconds( Random.Range( 2.0f, 3.0f ) ); | |
} else { | |
// Hide | |
covers = FindTransformWithTag("Cover"); | |
closest = FindClosestPosition( this.transform.position, covers ); | |
this.agent.SetDestination( closest ); | |
yield return new WaitForSeconds ( Random.Range( 2.0f, 4.0f ) ); | |
} | |
} | |
} | |
void OnTriggerEnter(Collider other){ | |
if ( other.CompareTag("Player") ) { | |
if ( isVisible(other.transform) ) { | |
patrolling = false; | |
target = other.transform; | |
} | |
} | |
} | |
void OnTriggerExit(Collider other){ | |
if ( other.CompareTag("Player") ) { | |
patrolling = true; | |
target = null; | |
if ( coroutine ) { | |
StopCoroutine("ShootAndHide"); | |
coroutine = false; | |
} | |
} | |
} | |
private bool isVisible( Transform obj ) { | |
//Vector3 wasLookingAt = this.transform.forward; | |
this.transform.LookAt(obj); | |
RaycastHit hitInfo; | |
// Ray | |
Vector3 from, direction; | |
from = transform.position; | |
direction = obj.position - from; | |
if ( Physics.Raycast( from, direction, out hitInfo ) ) { | |
if ( hitInfo.collider.tag == obj.tag ) { | |
//this.transform.forward = wasLookingAt; | |
return true; | |
} | |
} | |
//this.transform.forward = wasLookingAt; | |
return false; | |
} | |
private bool Shoot(){ | |
RaycastHit hitInfo; | |
// Ray | |
Vector3 from, direction; | |
from = transform.position; | |
direction = Vector3.forward; | |
if ( Physics.Raycast( from, direction, out hitInfo ) ) { | |
if ( hitInfo.collider.tag == "Player" ) { | |
hitInfo.transform.SendMessage("ApplyDammage", maxDamage , SendMessageOptions.DontRequireReceiver); | |
return true; | |
} | |
} | |
return false; | |
} | |
private int GetDestination( int from ) { | |
int len = patrolPoints.Length; | |
int to = Random.Range( 0, len); | |
int count = 0; | |
while ( from == to ) { | |
to = Random.Range( 0, len); | |
if ( count > 100 ) { | |
print("Out"); | |
break; | |
} | |
count++; | |
} | |
return to; | |
} | |
private void SetNewRandomDestination(){ | |
destination = GetDestination( -1 ); | |
Vector3 dst = patrolPoints[ destination ].position; | |
agent.SetDestination ( dst ); | |
} | |
private Vector3 FindClosestPosition( Vector3 from, Transform[] destinations ){ | |
// Save state | |
Vector3 originalDestination = agent.destination; | |
float minCost = 1000000000.0f; // Big float | |
Vector3 minPos = destinations[0].position; // Initialization | |
foreach ( Transform transform in destinations ) { | |
Vector3 vec = transform.position; | |
agent.SetDestination(vec); | |
float actCost = agent.remainingDistance; | |
if ( actCost < minCost ) { | |
minCost = actCost; | |
minPos = vec; | |
} | |
} | |
// Restore state | |
agent.SetDestination(originalDestination); | |
return minPos; | |
} | |
private Transform[] FindTransformWithTag( string tag ){ | |
GameObject[] gObjects = GameObject.FindGameObjectsWithTag(tag); | |
Transform[] points = new Transform[gObjects.Length]; | |
for ( int i = 0; i < gObjects.Length; i++) { | |
points[i] = gObjects[i].transform; | |
} | |
return points; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment