void Awake() { allyBehave = GetComponent <AllyBehave>(); hero = GameObject.FindWithTag("Player"); CUR_STATE = AllayState.STANDBY; debugTime = 1f; startRecord = Time.time; lastPos = transform.position; }
void FixedUpdate() { // debug if the ally is at the same position for 2 seconds if (Time.time > startRecord + debugTime) { startRecord = Time.time; if (Mathf.Abs(transform.position.x - lastPos.x) < 0.02f) { CUR_STATE = AllayState.STANDBY; return; } else { lastPos = transform.position; } } // instantiate enemy and lastAttackEnmemy if (hero.GetComponent <PlayerController>().IsOnGround()) { enemy = allyBehave.FindClosestEnemy(hero); } // if ally is having a bug, restart it if (allyBehave.IsRestarted()) { CUR_STATE = AllayState.STANDBY; transform.position = Vector3.MoveTowards(transform.position, allyBehave.TransferPostion(hero), Mathf.Infinity); return; } // check if the allly is in the the camera view // if not, transfer it to player position, swithch state to following if (!IsInView(transform.position)) { // if the player is alive, transfer its to the player's position transform.position = Vector3.MoveTowards(transform.position, allyBehave.TransferPostion(hero), Mathf.Infinity); if (lastAttackEnemy != null && lastAttackEnemy.GetComponent <EnemyHealth>().IsAlive()) { lastAttackEnemy.GetComponent <EnemyHealth>().AllyLeft(); } CUR_STATE = AllayState.STANDBY; } // state machine switch (CUR_STATE) { case AllayState.STANDBY: allyBehave.WaitForPlayer(); if (IsPlayerClosed() && hero.activeSelf) { allyBehave.SwitchTarget(hero, true); CUR_STATE = AllayState.FOLLOW; } else if (!hero.activeSelf) { enemy.GetComponent <EnemyHealth>().AllyLeft(); } break; case AllayState.FOLLOW: // if the ally is already finished the swtichTarget process, move towards player; else, continue if (allyBehave.IsOnNextPoint()) { allyBehave.MoveToTarget(hero, true); } else { allyBehave.MoveToNextPoint(); } // if the enemy is closed and the enemy is in the camera range, attack towards it if (enemy != null && IsEnemyClosed() && IsInView(enemy.transform.position) && !allyBehave.IsAllyJumping()) { allyBehave.SwitchTarget(enemy, false); CUR_STATE = AllayState.TOWARDENEMY; } break; case AllayState.TOWARDENEMY: // check if the current targeting enemy is the same as last time if (enemy != null && lastAttackEnemy != null && enemy.name != lastAttackEnemy.name) { lastAttackEnemy.GetComponent <EnemyHealth>().AllyLeft(); lastAttackEnemy = enemy; allyBehave.SwitchTarget(enemy, false); } // if the player has gone far away or the attacking enemy is dead, move towards player if (!allyBehave.IsAllyJumping() && (CheckIfPlayerLongGone() || lastAttackEnemy == null)) { if (CheckIfPlayerLongGone()) { enemy.GetComponent <EnemyHealth>().AllyLeft(); } lastAttackEnemy = enemy; allyBehave.SwitchTarget(hero, true); CUR_STATE = AllayState.FOLLOW; break; } if (!hero.activeSelf) { CUR_STATE = AllayState.STANDBY; break; } // if the ally is already finished the swtichTarget process, move towards enemy; else, continue if (allyBehave.IsOnNextPoint()) { allyBehave.MoveToTarget(enemy, false); } else { allyBehave.MoveToNextPoint(); } break; } }