/// <summary> /// Init the robot to its starting state /// </summary> public void Init(ushort index, Vector3 position, float speed) { Index = index; transform.position = position; transform.rotation = Quaternion.identity; health = MAX_HEALTH; searchTimer = 0; attackTimer = 0; agent.speed = speed; currentState = RobotState.Moving; currentAttackState = RobotAttackState.Charging; Target = GameManager.Instance.player; gameObject.SetActive(true); hitboxObj.SetActive(false); }
// Update is called once per frame void Update() { if (GameManager.Instance.CurrentState != GameState.Playing) { if (!agent.isStopped) { agent.isStopped = true; } return; } if (agent.isStopped) { agent.isStopped = false; } switch (currentState) { case RobotState.Moving: searchTimer += Time.deltaTime; attackTimer += Time.deltaTime; //Search for a nearby tower if (searchTimer > SEARCH_TIMER_MAX) { searchTimer -= SEARCH_TIMER_MAX; Targetable newTarget = FindTarget(); if (newTarget != null) { Target = newTarget; agent.destination = Target.transform.position; } } //Find a new target because this one died if (Target == null) { //If still null, assign to player if ((Target = FindTarget()) == null) { Target = GameManager.Instance.player; } agent.destination = Target.transform.position; } //The target is moveable, so continuously update the position else if (Target.IsMoveable) { agent.destination = Target.transform.position; } //Activate attack if we can if (attackTimer > ATTACK_TIMER_MAX && Vector3.SqrMagnitude(transform.position - Target.transform.position) <= ATTACK_RANGE) { attackTimer = 0; currentState = RobotState.Attacking; currentAttackState = RobotAttackState.Charging; agent.isStopped = true; } break; case RobotState.Attacking: switch (currentAttackState) { //Charge up the attack case RobotAttackState.Charging: attackTimer += Time.deltaTime; //Find a new target because this one died if (Target == null) { //If still null, assign to player if ((Target = FindTarget()) == null) { Target = GameManager.Instance.player; } agent.destination = Target.transform.position; } //Rotate towards target Vector3 direction = (Target.transform.position - transform.position).normalized; Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z)); transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * CHARGE_ROTATION_SPEED); if (attackTimer > CHARGE_TIMER_MAX) { attackDirection = transform.forward; attackTimer = 0; hitboxObj.SetActive(true); currentAttackState = RobotAttackState.Performing; } break; //Perform the actual attack case RobotAttackState.Performing: attackTimer += Time.deltaTime; //Move in attack direction agent.velocity = attackDirection * PERFORM_MOVE_SPEED; if (attackTimer > PERFORM_TIMER_MAX) { attackTimer = 0; hitboxObj.SetActive(false); currentAttackState = RobotAttackState.Recovery; } break; //Recover from the attack case RobotAttackState.Recovery: attackTimer += Time.deltaTime; if (attackTimer > RECOVERY_TIMER_MAX) { attackTimer = 0; currentState = RobotState.Moving; agent.isStopped = false; } break; default: break; } break; //TODO: death animations? case RobotState.Dying: break; default: break; } }