/// <summary> /// Aims at player's interpolated position in 60 frames and shoots if facing it /// </summary> private void attackPlayer() { Vector2 prediction = interpolation(60); float Angle = -transform.eulerAngles.z + Mathf.Atan2(transform.position.y - prediction.y, transform.position.x - prediction.x) * Mathf.Rad2Deg + 90; if (Angle >= 0 || Angle <= -180) { rotate(1); } else { rotate(-1); } if (Mathf.Abs(Angle) <= 1) { fire(); stateTimer = Time.time; IAState = SWIAState.DODGE_ATTACKS; } if (Time.time - stateTimer > stateChangeTimer) { stateTimer = Time.time; IAState = SWIAState.DODGE_ATTACKS; } }
/************************************************************************************************* * Public functions & standard Unity callbacks * *************************************************************************************************/ // Use this for initialization void Start() { if (p != null && p.id == 1) { kalman = new Kalman(new Vector4(player.transform.position.x, 0, player.transform.position.y, 0), 1, 1); } else { kalman = new Kalman(new Vector4(player.transform.position.x, 0, player.transform.position.y, 0), 0.1, 0.1); } posHistory = new Vector2[60]; posHistoryIterator = 0; stateTimer = Time.time; IAState = (p != null && p.id == 0) ? SWIAState.RANDOM : SWIAState.DODGE_ATTACKS; actionNumber = 0; //#if UNITY_EDITOR //#else target.SetActive(false); noisedPosition.SetActive(false); imprecision.SetActive(false); //#endif }
/// <summary> /// Tries pretty badly to adjust the trajectory to dodge projectiles as well as the center spiral /// </summary> /// <returns>True if there's nothing to dodge, false otherwise</returns> private bool dodgeAttacks() { bool spirale = dodgeSpirale(); bool self = dodgeSelfProjectile(); bool player = dodgePlayerProjectile(); if (Time.time - stateTimer > stateChangeTimer / 2) { stateTimer = Time.time; IAState = SWIAState.MOVE_TOWARDS_PLAYER; } return(self && player && spirale); }
/// <summary> /// Determine an action and executes it to move towards the player, regardless of any obstacles /// </summary> private void moveTowardsPlayer() { float Angle = -transform.eulerAngles.z + Mathf.Atan2(transform.position.y - player.transform.position.y, transform.position.x - player.transform.position.x) * Mathf.Rad2Deg + 90; if (Angle >= 0 || Angle <= -180) { rotate(1); goForward(); } else { rotate(-1); goForward(); } if (distance(player) <= 3) { stateTimer = Time.time; IAState = SWIAState.ATTACK_PLAYER; } }
/// <summary> /// Resets the AI to be ready for a new round /// </summary> public override void onRestart() { base.onRestart(); if (p != null && p.id == 1) { kalman = new Kalman(new Vector4(player.transform.position.x, 0, player.transform.position.y, 0), 1, 1); } else { kalman = new Kalman(new Vector4(player.transform.position.x, 0, player.transform.position.y, 0), 0.1, 0.1); } posHistory = new Vector2[60]; posHistoryIterator = 0; stateTimer = Time.time; IAState = (p != null && p.id == 0) ? SWIAState.RANDOM : SWIAState.DODGE_ATTACKS; IAAction = (p != null && p.id == 0) ? SWIAAction.MOVE_TURN_LEFT : SWIAAction.MOVE_FORWARD; actionNumber = 0; }
/************************************************************************************************* * Private IA action functions * *************************************************************************************************/ /// <summary> /// Change the State when parameter is set to Random /// </summary> private void changeRandomState() { int i = Random.Range(1, 4); switch (i) { case 1: { IAState = SWIAState.RANDOM; } break; case 2: { IAState = SWIAState.MOVE_RANDOMLY; } break; case 3: { IAState = SWIAState.ATTACK_RANDOMLY; } break; } }
// Update is called once per frame protected override void Update() { base.Update(); if (p != null && p.id != 0) { kalman.addObservation(new Vector4(player.transform.position.x, 0, player.transform.position.y, 0)); } addInterpretedPosition(kalman.PosInterp); if (isEnd) { if (Time.time - initEndTimer >= 2) { isEnd = false; EventManager <bool, int> .Raise(EnumEvent.SPACESHIPDESTROYED, false, 5 *scoreMult); } } #if UNITY_EDITOR /* DEBUG : Moving points around */ //target.transform.position = kalman.interpolation(60); //target.transform.position = kalman.PosInterp; target.transform.position = interpolation(60); noisedPosition.transform.position = kalman.PosBruit; imprecision.transform.position = kalman.PosImprecise; #endif if (p == null) { return; } // IA State management switch (p.id) { case 0: // IA Aléatoire { if (Time.time - stateTimer > stateChangeTimer) { stateTimer = Time.time; actionNumber = 0; changeRandomState(); } switch (IAState) { case SWIAState.RANDOM: { moveRandomly(); attackRandomly(); } break; case SWIAState.MOVE_RANDOMLY: { moveRandomly(); } break; case SWIAState.ATTACK_RANDOMLY: { attackRandomly(); } break; case SWIAState.DODGE_ATTACKS: { IAState = SWIAState.RANDOM; moveRandomly(); attackRandomly(); } break; } } break; case 1: case 2: { switch (IAState) { case SWIAState.MOVE_TOWARDS_PLAYER: { if (dodgeAttacks()) { moveTowardsPlayer(); } } break; case SWIAState.ATTACK_PLAYER: { attackPlayer(); } break; case SWIAState.DODGE_ATTACKS: { if (dodgeAttacks()) { moveIntelligently(); } } break; } } break; } }