Newer
Older
public DecisionTree root; //root of the decision tree which is searched for the AI to function
public GameObject bananaPrefab;
private Rigidbody2D Enemy;
private Animator myAnimator;
//Variables for keeping track of the Enemies health
public float enemyHealth; //current health
public float original; //health he spawned with
//Variables for keeping track of the Players health
public float playerHealth; //current health
public float playerHealthOriginal; //players health they entered the arena with
public static bool LookRight = true; //check which way the enemy is facing
private float speed = 2; //movement speed of enemy
private float attackSpeed; //attack speed
private float randomSpeed; //random speed which the atttack speed takes
float spaceBarCounter = 0; //check for how aggresive the player is being
private float coolDown = 0; //coolDown for Enemy attack
private bool actionDelay = false; //sets a delay for the search of the tree during an enemy action
private float searchDelay = 0.2f;
private float searchCoolDown = 0;
public static bool isEnemyKicking = false; //check for the player
public static bool isEnemyPushing = false; //check for the player
public static bool isEnemyDead = false; //check for the player
private float kickCoolDown = 0; //cooldown on enemy kicks
private float kickTimer; //hold the max time between enemy kicks
private float aggressiveTimer; //time which countdowns, if player spams spacebar before it end, they will be seen as "Aggressive"
private bool aggressiveCheck = false; //checks if the player is aggressive
private bool isPlayerAttacking = false; //Check for AI
private bool isPlayerBlocking = false; //Check for AI
private bool isPlayerKicking = false; //Check for AI
private bool isPlayerPushing = false; //Check for AI
private float playerPushingTimer; //Timer which makes AI jump after being pushed 'x' times
private float throwCoolDown = 0; //timer to slow amount the AI can throw
private bool canJump = false; //check to see if the AI can jump, to avoid clipping
private int playerPushingCounter = 0; //check for how many times the AI has been pushed by the player
private float randomActionCoolDown = 0; //cooldown for random actions
private float randomAction; //holds the randomActionSpeed
private float randomAcioionSpeed; //random speed set for random actions
public int enemyMax;
public int enemyMin;
throwTimer = 2;
throwCoolDown = 1;
playerHealth = PlayerStats.getHealth();
target = GameObject.FindGameObjectWithTag("Player").transform; //look at the player
Player = GameObject.FindGameObjectWithTag("Player").GetComponent<Rigidbody2D>();
myAnimator = GetComponent<Animator>(); //required for animation *******
Enemy = GetComponent<Rigidbody2D>();
//calls the all functions which need to be checked every frame
BlockCheck();
AttackCheck();
KickCheck();
throwCoolDown -= Time.deltaTime;
coolDown -= Time.deltaTime; //for attacking
//If the player can jump this will allow him to do so without getting stuck in the player
if (canJump == true) {
playerPushingTimer -= Time.deltaTime;
if (playerPushingTimer <= 0) {
JumpPlayer();
playerPushingTimer = 1.5f;
if (dash == true) {
dashCoolDown -= Time.deltaTime;
if (dashCoolDown <= 0) {
//sets a delay to the search of the tree so actions can not be spammed out by the AI
if (actionDelay == true) {
searchCoolDown -= Time.deltaTime;
if (searchCoolDown <= 0) {
searchCoolDown = searchDelay;
root.search(); //search the decision tree
root.search(); //search the decision tree
public void setEnemyHp() {
if (ArenaCombatControl.winCount <= 2) {
enemyHealth = enemyHealth = Random.Range(20, 40);
enemyHealth = enemyHealth = Random.Range(15 * (int)(ArenaCombatControl.winCount / 1.1f + 1), 20 * (int)(ArenaCombatControl.winCount / 1.1f + 1));
original = enemyHealth;
/*
* getPushed()
* Takes Input from the user and checks whether or not the enemy is being pushed
* Checks which direction the enemy is facing and applies the relative force
* If the enemy has been pushed too many times he will then jump over the player and switch up the combat
*/
if (Vector3.Distance(transform.position, target.position) < 2.5f && isPlayerPushing == true) {
myAnimator.SetBool("knockBack", true);
myAnimator.SetBool("kick", false);
myAnimator.SetBool("attack", false);
myAnimator.SetBool("block", false);
Invoke("StopKnockAnimation", 0.5f);
if (LookRight == true) {
Enemy.AddForce(new Vector2(-500, 0));
}
else {
Enemy.AddForce(new Vector2(500, 0));
}
if (playerPushingCounter >= 2) {
//fixes infinate loop of knockBack animation
public void StopKnockAnimation() {
myAnimator.SetBool("knockBack", false);
}
//forces to the Enemy to jump over the player without getting stuck
//relative forces are applied by checking the direction the enemy is facing
if (Vector3.Distance(transform.position, target.position) < 6f) {
/*
* AggreiveCoolDown()
* Takes input from the player and checks how much the spacebar is being pressed
* if the spacebar is spammed, the enemy will push the player away
*/
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;
}
}
//Check from user imput for AI, if the player is blocking or not
public void BlockCheck() {
isPlayerBlocking = ArenaCombatControl.block;
//Debug.Log(isPlayerBlocking + "Enemy");
if (isPlayerBlocking == false) {
myAnimator.SetBool("kick", false);
}
//Check from user imput for AI, if the player is atacking or not
public void AttackCheck() {
isPlayerAttacking = ArenaCombatControl.attack;
}
//Check from user imput for AI, if the player is kicking or not
public void KickCheck() {
isPlayerKicking = ArenaCombatControl.kick;
}
//Check from player stats for AI, keeps track of the players HP
public void HpCheck() {
playerHealth = PlayerStats.curHealth;
}
//Check from user imput for AI, if the player is pushing or not
public void PushCheck() {
isPlayerPushing = ArenaCombatControl.push;
}
/*
* Damage dealt against the enemy from the player
isEnemyDead = true;
myAnimator.SetBool("death", true);
Enemy.velocity = Vector2.zero;
Invoke("EnemyDeath", 2.5f);
//destory the enemy when hes dead
public void EnemyDeath() {
Destroy(gameObject);
}
//exit the arena after the enemy had died
public void ExitArena() {
/*
* Damage dealt to the player from the enemy
enemyMax = 8 + (int)(ArenaCombatControl.winCount * 1.25f); //BALANCE THIS
enemyMin = 1 + (int)(ArenaCombatControl.winCount * 1.1f);
int final = Random.Range(enemyMin, enemyMax);
// calculate here! remember player defense is factored in later
//Decision for the Decision Tree
//is the player attacking?
if (isPlayerAttacking == true) {
return true;
}
public bool d_isPlayerKicking() {
if (isPlayerKicking == true) {
//is the enemy able to attack?
//if yes he will attack
//if no he will move towards the player
if (Vector3.Distance(transform.position, target.position) < 1.5f && Vector3.Distance(transform.position, target.position) > 1f) {
// myAnimator.SetBool("knockBack", false);
myAnimator.SetBool("push", false);
//is the player too close?
//if no the enemy moves towards
//if yes the enemy moves backwards
if (Vector3.Distance(transform.position, target.position) < 1f) {
//if the player too far
//if yes the enemy throws object to taunt you
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;
}
}
//is the player aggressive, checks to see if the user is spamming attack
if (spaceBarCounter > 7 && aggressiveTimer > 0) {
if (isPlayerBlocking == true) {
return true;
//checks the Players HP
//if players HP reaches below a certain threshold AI descions will be altered
if ((playerHealthOriginal * 0.2f) > playerHealth) {
//checks the Enemies HP
//if Enemis HP reaches below a certain threshold AI descions will be altered
enemyHealth += (int)(original * 0.5);
if (enemyHealth > original) {
enemyHealth = original;
}
Ryan Hoppe (rmh898)
committed
//makes a random decision with a 75% true return and a 25% false return
Ryan Hoppe (rmh898)
committed
int x = Random.Range(1, 4);
Ryan Hoppe (rmh898)
committed
return false;
}
Ryan Hoppe (rmh898)
committed
}
//Actions for the end of the Decision Tree
//Enemies attack, with cooldown so he can spam and kill you too fast
myAnimator.SetBool("attack", true);
Enemy.velocity = Vector2.zero;
}
else {
myAnimator.SetBool("attack", false);
}
public void a_jumpOverPlayer() {
actionDelay = true;
if (LookRight == true) {
public void a_push() {
actionDelay = true;
aggressiveTimer = 5;
spaceBarCounter = 0;
myAnimator.SetBool("push", true);
Invoke("enemyPushing", 0.1f);
}
//Check for the Player, if the enemy is pushing then the player gets knocked back
public void enemyPushing() {
//Rouge attack, if the players HP gets really low the enemy goes insane and gets super aggressive
public void a_superAttack() {
myAnimator.SetFloat("speed", 0f);
//Jump back away from combat, dodging attacks
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));
}
//Block, will defend off the player reducing hits
myAnimator.SetBool("attack", false);
myAnimator.SetBool("block", true);
Enemy.velocity = Vector2.zero;
}
//Kick, kick will disarm the player if they are blocking
public void a_kick() {
actionDelay = true;
if (kickCoolDown <= 0) {
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;
myAnimator.SetBool("throw", true);
Invoke("bananaToss", 0.2f);
}
else {
myAnimator.SetBool("throw", false);
//Spawns the object which is thrown at the player
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);
//change up the movement so its not so predictable
public void a_walkOrDash() {
if (dash == false) {
a_dashToPlayer();
dash = true;
}
else {
a_moveToPlayer();
}
}
//Will allow the enemy it either attack the player or preform a random action
//50% chance of either happening
public void a_AttackOrRandom() {
float x = Random.Range(0, 2);
actionDelay = true;
if (x == 1) {
a_attack();
}
a_randomAction();
}
}
//Random Actions too keep the Enemy always moving
//Each action is given a differnt activation %
//Push 5%
//Jump Back 15%
//Jump Over Player 20%
//Attack 40%
//Kick 20%
float x = Random.Range(0, 500);
if (x > 225 && x <= 300) {
a_jumpBack();
}
if (x >= 125 && x <= 225) {
a_attack();
}
a_kick();
}
if (x > 400) {
a_attack();
}
//Random Block so the enemy doesnt just hold his shield every time
//each block is given a certain % activation
float x = Random.Range(0, 350);
actionDelay = true;
if (randomActionCoolDown <= 0) {
//Debug.Log(x);
randomActionCoolDown = randomAction;
if (x < 125) {
}
if (x >= 125 && x <= 200) {
a_jumpBack();
}
if (x > 200 && x < 250) {
a_push();
}
if (x > 250) {
a_block();
//Random Attack
//Enemy will still use basic attack more often then any action
//this random action gives variety
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();
}
//Chance to Kick the shield down off the player if they are blocking
public void a_disarmSheild() {
actionDelay = true;
float x = Random.Range(0, 3);
if (x == 1) {
a_kick();
}
else {
a_randomAttack();
}
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 a_dashToPlayer() {
// Debug.Log("moving");
//rotate to look at the player
//transform.LookAt(target.position);
myAnimator.SetFloat("speed", 1); // This should probbaly reflect the actual speed
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
Enemy.AddForce(new Vector2(-350, Player.velocity.y * 5));
}
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 }
Enemy.AddForce(new Vector2(350, Player.velocity.y * 5));
}
}
//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 * 2) * 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 }
}
/*
* BuildDecisionTree()
* each action and decision above are used in this function to create the DecisionTree
*/
DecisionTree Dash = new DecisionTree();
Dash.setAction(a_dashToPlayer);
DecisionTree RandomWalk = new DecisionTree();
RandomWalk.setAction(a_walkOrDash);
DecisionTree RandomAction = new DecisionTree();
RandomAction.setAction(a_randomAction);
DecisionTree RandomBlock = new DecisionTree();
RandomBlock.setAction(a_randomBlock);
DecisionTree RandomAttack = new DecisionTree();
RandomAttack.setAction(a_randomAction);
DecisionTree AttackOrRandom = new DecisionTree();
DecisionTree Push = new DecisionTree();
Push.setAction(a_push);
DecisionTree Rouge = new DecisionTree();
Rouge.setAction(a_superAttack);
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 MoveAway = new DecisionTree();
MoveAway.setAction(a_moveFromPlayer);
DecisionTree JumpOverPlayer = new DecisionTree();
JumpOverPlayer.setAction(a_jumpOverPlayer);
DecisionTree Throw = new DecisionTree();
Throw.setAction(a_throw);
DecisionTree isPlayerBlocking = new DecisionTree();
isPlayerBlocking.setDecision(d_isPlayerBlocking);
DecisionTree isPlayerBlocking2 = new DecisionTree();
isPlayerBlocking2.setDecision(d_isPlayerBlocking);
isPlayerBlocking2.setLeft(DisarmShield);
isPlayerBlocking2.setRight(AttackOrRandom);
DecisionTree JumpPlayer = new DecisionTree();
JumpPlayer.setDecision(d_jumpOverPlayer);
JumpPlayer.setLeft(JumpOverPlayer);
JumpPlayer.setRight(RandomAction);
DecisionTree PlayerHP2 = new DecisionTree();
PlayerHP2.setDecision(d_isPlayerHpLow);
PlayerHP2.setRight(isPlayerBlocking2);
DecisionTree PlayerHP3 = new DecisionTree();
PlayerHP3.setDecision(d_isPlayerHpLow);
PlayerHP3.setLeft(Rouge);
PlayerHP3.setRight(isPlayerBlocking2);
DecisionTree EnemyHP = new DecisionTree();
EnemyHP.setDecision(d_isHpLow);
EnemyHP.setLeft(PlayerHP2);
DecisionTree GettingAttacked = new DecisionTree();
GettingAttacked.setDecision(d_isPlayerAttacking);
GettingAttacked.setLeft(RandomBlock);
GettingAttacked.setRight(EnemyHP);
DecisionTree PlayerHP = new DecisionTree();
PlayerHP.setDecision(d_isPlayerHpLow);
PlayerHP.setLeft(Attack);
PlayerHP.setRight(isPlayerBlocking);
DecisionTree JumpPlayer2 = new DecisionTree();
JumpPlayer2.setDecision(d_jumpOverPlayer);
JumpPlayer2.setLeft(JumpOverPlayer);
JumpPlayer2.setRight(EnemyHP);
DecisionTree GettingAttacked2 = new DecisionTree();
GettingAttacked2.setDecision(d_isPlayerAttacking);
GettingAttacked2.setLeft(RandomBlock);
//Random Action Trees
DecisionTree Random01 = new DecisionTree();
Random01.setDecision(d_randomDecision75);
Random01.setLeft(PlayerHP);
//Random Action Trees
DecisionTree Random02 = new DecisionTree();
Random02.setDecision(d_randomDecision75);
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(RandomWalk);
DecisionTree IsPlayerTooClose = new DecisionTree();
IsPlayerTooClose.setDecision(d_isPlayerTooClose);
IsPlayerTooClose.setLeft(IsPlayerTooFar);