using UnityEngine; using System.Collections; public class EnemyAI : MonoBehaviour { public DecisionTree root; public GameObject bananaPrefab; private Transform target; private Rigidbody2D Player; private Rigidbody2D Enemy; private Animator myAnimator; public float enemyHealth, original; public float playerHealth; public float playerHealthOriginal; // ***Maybe use playerstats maxhealth? public static bool LookRight = true; private bool set; private float speed = 1; private float attackSpeed; private float randomSpeed; float spaceBarCounter = 0; //check for how aggresive the player is being private float coolDown = 0; private bool actionDelay = false; private float searchDelay = 0.2f; private float searchCoolDown = 0; public static bool isEnemyKicking = false; public static bool isEnemyPushing = false; private float kickCoolDown = 0; private float kickTimer; private float aggressiveTimer; private bool aggressiveCheck = false; private bool isAggressive = false; private bool isPlayerAttacking = false; private bool isPlayerBlocking = false; private bool isPlayerKicking = false; private bool isPlayerPushing = false; private float playerPushingTimer; private float throwCoolDown = 0; private float throwTimer; private bool canJump = false; private int playerPushingCounter = 0; private float randomActionCoolDown = 0; private float randomAction; private float randomAcioionSpeed; void Start() { throwTimer = 2; throwCoolDown = 1; playerPushingTimer = 2; aggressiveTimer = 3; kickTimer = 5; randomSpeed = Random.Range(0, 1f); attackSpeed = randomSpeed; randomAcioionSpeed = Random.Range(0, 2f); randomAction = randomAcioionSpeed; enemyHealth = Random.Range(50, 500); original = enemyHealth; playerHealth = PlayerStats.getHealth(); playerHealthOriginal = playerHealth; root = new DecisionTree(); // Debug.Log("start"); target = GameObject.FindGameObjectWithTag("Player").transform; //look at the player Player = GameObject.FindGameObjectWithTag("Player").GetComponent<Rigidbody2D>(); myAnimator = GetComponent<Animator>(); //required for animation ******* Enemy = GetComponent<Rigidbody2D>(); BuildDecisionTree(); } void Update() { AggressiveCoolDown(); BlockCheck(); AttackCheck(); KickCheck(); PushCheck(); getPushed(); throwCoolDown -= Time.deltaTime; coolDown -= Time.deltaTime; kickCoolDown -= Time.deltaTime; randomActionCoolDown -= Time.deltaTime; if (canJump == true) { playerPushingTimer -= Time.deltaTime; if (playerPushingTimer <= 0) { JumpPlayer(); playerPushingTimer = 2; canJump = false; } } if (actionDelay == true) { searchCoolDown -= Time.deltaTime; if (searchCoolDown <= 0) { searchCoolDown = searchDelay; root.search(); } } else { root.search(); actionDelay = false; } } public void getPushed() { if (Vector3.Distance(transform.position, target.position) < 2f && isPlayerPushing == true) { myAnimator.SetBool("knockBack", true); myAnimator.SetBool("kick", false); myAnimator.SetBool("attack", false); myAnimator.SetBool("block", false); playerPushingCounter++; if (LookRight == true) { Enemy.AddForce(new Vector2(-500, 0)); } else { Enemy.AddForce(new Vector2(500, 0)); } if (playerPushingCounter >= 2) { playerPushingCounter = 0; canJump = true; } } } public void JumpPlayer() { if (Vector3.Distance(transform.position, target.position) < 6f) { if (LookRight == true) { Enemy.AddForce(new Vector2(200, 1000)); } else { Enemy.AddForce(new Vector2(-200, 1000)); } } } public void AggressiveCoolDown() { if (Input.GetKeyDown(KeyCode.Space)) { spaceBarCounter++; // Debug.Log(spaceBarCounter); aggressiveCheck = true; } if (aggressiveCheck == true) { aggressiveTimer -= Time.deltaTime; // Debug.Log(agressiveTimer); } if (aggressiveTimer <= 0) { aggressiveCheck = false; spaceBarCounter = 0; aggressiveTimer = 5; } } public void BlockCheck() { isPlayerBlocking = ArenaCombatControl.block; Debug.Log(isPlayerBlocking + "Enemy"); if (isPlayerBlocking == false) { myAnimator.SetBool("kick", false); } } public void AttackCheck() { isPlayerAttacking = ArenaCombatControl.attack; } public void KickCheck() { isPlayerKicking = ArenaCombatControl.kick; } public void HpCheck() { playerHealth = PlayerStats.curHealth; } public void PushCheck() { isPlayerPushing = ArenaCombatControl.push; } public void ChangeHealthBare(int damage) { GameObject healthbar = GameObject.Find("healthbarFulle"); float newsize = healthbar.transform.localScale.x - ((damage / original) * 0.3f); healthbar.transform.localScale = new Vector3(newsize, 0.3f, 1f); if (enemyHealth <= 0) { healthbar.GetComponent<SpriteRenderer>().enabled = false; } } public void ApplyDamageE(int damage) { enemyHealth -= damage; if (enemyHealth <= 0) { Destroy(gameObject); } } public bool d_isPlayerAttacking() { if (isPlayerAttacking == true) { return true; } Debug.Log("Player Not Attacking"); return false; } public bool d_isPlayerKicking() { if (isPlayerKicking == true) { return true; } return false; } public bool d_inAttackRange() { isEnemyKicking = false; isEnemyPushing = false; if (Vector3.Distance(transform.position, target.position) < 2f && Vector3.Distance(transform.position, target.position) > 1f) { myAnimator.SetBool("speed", false); return true; } else if (isAggressive == true) { myAnimator.SetBool("block", true); return true; } else { myAnimator.SetBool("kick", false); myAnimator.SetBool("attack", false); myAnimator.SetBool("block", false); myAnimator.SetBool("knockBack", false); // Debug.Log("In Zone- not"); return false; } } public bool d_isPlayerTooClose() { if (Vector3.Distance(transform.position, target.position) < 1f) { myAnimator.SetBool("speed", true); return false; } else { return true; } } public bool d_isPlayerTooFar() { if (Vector3.Distance(transform.position, target.position) > 7.5f && Vector3.Distance(transform.position, target.position) < 12f) { return true; } else { return false; } } public bool d_isPlayerAggresive() { if (spaceBarCounter > 5 && aggressiveTimer > 0) { isAggressive = true; Debug.Log("Aggressive"); return true; } else { isAggressive = false; Debug.Log("Not Aggresive"); return false; } } public bool d_isPlayerBlocking() { if (isPlayerBlocking == true) { return true; } return false; } public bool d_isPlayerHpLow() { if ((playerHealthOriginal / 2) > playerHealth) { Debug.Log("Player Half Health"); return true; } Debug.Log("Player Full Health"); return false; } public bool d_isHpLow() { if ((original / 2) > enemyHealth) { Debug.Log("Enemy Half Health"); return true; } Debug.Log("Enemy Full Health"); return false; } //makes a random decision with a 75% true return and a 25% false return public bool d_randomDecision75() { int x = Random.Range(1, 4); // Debug.Log(x); if (x == 1) { return false; } else return true; } public bool d_jumpOverPlayer() { Debug.Log("Jumped"); if (Vector3.Distance(transform.position, target.position) > 3f && Vector3.Distance(transform.position, target.position) < 8f && playerPushingCounter >= 2) { Debug.Log("Jumped"); playerPushingCounter = 0; return true; } return false; } // Actions public void a_attack() { actionDelay = true; myAnimator.SetFloat("speed", 0f); if (coolDown <= 0) { coolDown = attackSpeed; Debug.Log("attacking"); myAnimator.SetBool("attack", true); Enemy.velocity = Vector2.zero; } else { myAnimator.SetBool("attack", false); } } public void a_jumpOverPlayer() { actionDelay = true; if (LookRight == true) { Debug.Log("Over Yo HEAD"); Enemy.AddForce(new Vector2(100, 1000)); } else { Debug.Log("Over Yo HEAD"); Enemy.AddForce(new Vector2(-100, 1000)); } } public void a_push() { actionDelay = true; Debug.Log("Pushing"); isEnemyPushing = true; } public void a_superAttack() { myAnimator.SetFloat("speed", 0f); Debug.Log("attacking"); myAnimator.SetBool("attack", true); } public void a_jumpBack() { actionDelay = true; if (LookRight == true) { Enemy.AddForce(new Vector2(-250, 500)); } else { Enemy.AddForce(new Vector2(250, 500)); } } public void a_jump() { actionDelay = true; Enemy.AddForce(new Vector2(0, 500)); } public void a_block() { Debug.Log("Block"); actionDelay = true; myAnimator.SetBool("attack", false); myAnimator.SetBool("block", true); Enemy.velocity = Vector2.zero; } public void a_kick() { actionDelay = true; if (kickCoolDown <= 0) { isEnemyKicking = true; kickCoolDown = kickTimer; Debug.Log("kicking"); myAnimator.SetBool("kick", true); Enemy.velocity = Vector2.zero; } else { myAnimator.SetBool("kick", false); myAnimator.SetBool("attack", true); } } public void a_throw() { actionDelay = true; myAnimator.SetFloat("speed", 0f); if (throwCoolDown <= 0) { throwCoolDown = throwTimer; Debug.Log("throwing"); myAnimator.SetBool("throw", true); Invoke("bananaToss", 0.2f); } else { myAnimator.SetBool("throw", false); } } public void bananaToss() { Vector3 offset = transform.rotation * new Vector3(0.5f, 0.5f, 0); //fire from the front of the player Instantiate(bananaPrefab, transform.position + offset, transform.rotation); } public void a_randomAction() { Debug.Log("Action"); float x = Random.Range(0, 250); actionDelay = true; if (randomActionCoolDown <= 0) { //Debug.Log(x); randomActionCoolDown = randomAction; if (x < 125) { a_block(); } if (x > 225) { a_jumpBack(); } if (x >= 125 && x <= 225) { a_attack(); } } } public void a_randomBlock() { float x = Random.Range(0, 250); actionDelay = true; if (randomActionCoolDown <= 0) { //Debug.Log(x); randomActionCoolDown = randomAction; if (x < 125) { a_block(); } if (x >= 125 && x <= 200) { a_jumpBack(); } if (x > 200) { a_jumpOverPlayer(); } } } public void a_randomAttack() { float x = Random.Range(0, 250); actionDelay = true; if (randomActionCoolDown <= 0) { //Debug.Log(x); randomActionCoolDown = randomAction; if (x < 125) { a_attack(); } if (x >= 125 && x <= 200) { a_kick(); } if (x > 200) { a_push(); } } } public void a_disarmSheild() { actionDelay = true; float x = Random.Range(0, 3); if (x == 1) { a_kick(); } else { a_randomAttack(); } } //template for a 'poison' special attack. Will slowly and gradually drain players health over time. public void poison() { Debug.Log("Performing Poison Attack"); } public void a_moveToPlayer() { Debug.Log("moving"); //rotate to look at the player //transform.LookAt(target.position); myAnimator.SetFloat("speed", 1); // This should probbaly reflect the actual speed transform.position = Vector2.MoveTowards(transform.position, target.position, speed * Time.deltaTime); if (target.transform.position.x <= transform.position.x) //players spot in world space as opposed to enemy "self" spot { LookRight = false; transform.rotation = new Quaternion(0, 180, 0, 0); // flips enemy around to face the player on x axis only } else if (target.transform.position.x >= transform.position.x) //players spot in world space as opposed to enemy "self" spot { LookRight = true; transform.rotation = new Quaternion(0, 0, 0, 0); // flips enemy around to face the player on x axis only } } } public void a_moveFromPlayer() { Debug.Log("movingAWAY"); //rotate to look at the player //transform.LookAt(target.position); myAnimator.SetFloat("speed", 1); // This should probbaly reflect the actual speed transform.position = Vector2.MoveTowards(transform.position, target.position, -speed * Time.deltaTime); if (target.transform.position.x <= transform.position.x) //players spot in world space as opposed to enemy "self" spot { transform.rotation = new Quaternion(0, 180, 0, 0); // flips enemy around to face the player on x axis only } else if (target.transform.position.x >= transform.position.x) //players spot in world space as opposed to enemy "self" spot { transform.rotation = new Quaternion(0, 0, 0, 0); // flips enemy around to face the player on x axis only } } } public void BuildDecisionTree() { //Actions DecisionTree RandomAction = new DecisionTree(); RandomAction.setAction(a_randomAction); DecisionTree RandomBlock = new DecisionTree(); RandomBlock.setAction(a_randomBlock); DecisionTree Push = new DecisionTree(); Push.setAction(a_push); DecisionTree Kick = new DecisionTree(); Kick.setAction(a_kick); DecisionTree DisarmShield = new DecisionTree(); DisarmShield.setAction(a_disarmSheild); DecisionTree JumpBack = new DecisionTree(); JumpBack.setAction(a_jumpBack); DecisionTree Block = new DecisionTree(); Block.setAction(a_block); DecisionTree MoveToPlayer = new DecisionTree(); MoveToPlayer.setAction(a_moveToPlayer); DecisionTree Attack = new DecisionTree(); Attack.setAction(a_attack); DecisionTree MoveAway = new DecisionTree(); MoveAway.setAction(a_moveFromPlayer); DecisionTree JumpOverPlayer = new DecisionTree(); JumpOverPlayer.setAction(a_jumpOverPlayer); DecisionTree Throw = new DecisionTree(); Throw.setAction(a_throw); // Decisions DecisionTree isPlayerBlocking = new DecisionTree(); isPlayerBlocking.setDecision(d_isPlayerBlocking); isPlayerBlocking.setLeft(DisarmShield); isPlayerBlocking.setRight(Attack); DecisionTree JumpPlayer = new DecisionTree(); JumpPlayer.setDecision(d_jumpOverPlayer); JumpPlayer.setLeft(JumpOverPlayer); JumpPlayer.setRight(RandomAction); DecisionTree GettingAttacked = new DecisionTree(); GettingAttacked.setDecision(d_isPlayerAttacking); GettingAttacked.setLeft(RandomBlock); GettingAttacked.setRight(JumpPlayer); DecisionTree PlayerHP = new DecisionTree(); PlayerHP.setDecision(d_isPlayerHpLow); PlayerHP.setLeft(Attack); PlayerHP.setRight(GettingAttacked); DecisionTree PlayerHP2 = new DecisionTree(); PlayerHP2.setDecision(d_isPlayerHpLow); PlayerHP2.setLeft(Attack); PlayerHP2.setRight(MoveAway); DecisionTree PlayerHP3 = new DecisionTree(); PlayerHP3.setDecision(d_isPlayerHpLow); PlayerHP3.setLeft(Attack); PlayerHP3.setRight(isPlayerBlocking); DecisionTree EnemyHP = new DecisionTree(); EnemyHP.setDecision(d_isHpLow); EnemyHP.setLeft(PlayerHP2); EnemyHP.setRight(PlayerHP3); DecisionTree JumpPlayer2 = new DecisionTree(); JumpPlayer2.setDecision(d_jumpOverPlayer); JumpPlayer2.setLeft(JumpOverPlayer); JumpPlayer2.setRight(EnemyHP); DecisionTree GettingAttacked2 = new DecisionTree(); GettingAttacked2.setDecision(d_isPlayerAttacking); GettingAttacked2.setLeft(RandomAction); GettingAttacked2.setRight(JumpPlayer2); //Random Action Trees DecisionTree Random01 = new DecisionTree(); Random01.setDecision(d_randomDecision75); Random01.setLeft(PlayerHP); Random01.setRight(RandomAction); //Random Action Trees DecisionTree Random02 = new DecisionTree(); Random02.setDecision(d_randomDecision75); Random02.setLeft(GettingAttacked2); Random02.setRight(RandomAction); DecisionTree Aggressiveness = new DecisionTree(); Aggressiveness.setDecision(d_isPlayerAggresive); Aggressiveness.setLeft(Random01); Aggressiveness.setRight(Random02); DecisionTree IsPlayerTooFar = new DecisionTree(); IsPlayerTooFar.setDecision(d_isPlayerTooFar); IsPlayerTooFar.setLeft(Throw); IsPlayerTooFar.setRight(MoveToPlayer); DecisionTree IsPlayerTooClose = new DecisionTree(); IsPlayerTooClose.setDecision(d_isPlayerTooClose); IsPlayerTooClose.setLeft(IsPlayerTooFar); IsPlayerTooClose.setRight(MoveAway); root.setDecision(d_inAttackRange); root.setLeft(Aggressiveness); root.setRight(IsPlayerTooClose); } }