Skip to content

Instantly share code, notes, and snippets.

@EnriqueSoria
Last active August 29, 2015 14:07
Show Gist options
  • Save EnriqueSoria/c9e167aed75cd1b529e2 to your computer and use it in GitHub Desktop.
Save EnriqueSoria/c9e167aed75cd1b529e2 to your computer and use it in GitHub Desktop.
EnemyBehaviour.cs
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