void Update() { if (currentGoal == null) { GameObject tmpObj = gManager.GetGoalAtFirstIndex(); if (tmpObj != null) { currentGoal = tmpObj.transform; targetPos = currentGoal.position; currentState = CarState.Goal; } else { stopTimer = true; collectionComplete = true; ranOutOfTime = false; currentState = CarState.Idle; } } if (!stopTimer) { if (restrictTime) //If true the time limit will be forced and the AI might fail the test if it runs out of time { timerTitleText.text = "Remaining Time:"; if (Time.time - timer >= maxTime) { timerText.text = "0"; collectionComplete = false; ranOutOfTime = true; currentState = CarState.Idle; } else { timerText.text = (maxTime - (Time.time - timer)).ToString("F2"); } } else // Else the time it takes to complete the run is recorded { timerTitleText.text = "Time Taken:"; currentTime += Time.deltaTime; timerText.text = currentTime.ToString("F2"); } } switch (currentState) { case CarState.Goal: stateText.text = "Moving to goal"; // Get collision free path from the cars proximity sensor pathPos = proxSensor.GetOptimalPathToPosition(transform.position, targetPos); // DEBUG CODE: Set the visualizer for the current arbitrary path followBall.position = pathPos; distToGoal = Vector3.Distance(transform.position, targetPos); angleToGoal = Vector3.Angle(pathPos - transform.position, transform.forward); if (pastPosition != Vector3.zero) { totalDistanceTravelled += Vector3.Distance(transform.position, pastPosition); pastPosition = transform.position; } else { pastPosition = transform.position; } if (wiggleCount < wiggleTarget) { if (carMotor.IsAboveBrakeVelocity() && proxSensor.HasObjectInFront(transform)) { lastInput = LastInputType.brake; carMotor.Brake(); } else { // If the AI is not stuck in a local minima, then proceed with regular movement logic if (angleToGoal > angleTreshold) { steerPos = transform.InverseTransformPoint(pathPos); if (steerPos.z > 0) { if (steerPos.x > 0.2f) { // Steer Right CheckForWiggles(LastInputType.right); lastInput = LastInputType.right; carMotor.TurnRight(); } else if (steerPos.x < -0.2f) { // Steer Left CheckForWiggles(LastInputType.left); lastInput = LastInputType.left; carMotor.TurnLeft(); } else { // Go Forward CheckForWiggles(LastInputType.forward); lastInput = LastInputType.forward; carMotor.GoForward(); } } else { if (steerPos.x >= 0f) { CheckForWiggles(LastInputType.right); lastInput = LastInputType.right; carMotor.TurnRight(); } else { CheckForWiggles(LastInputType.left); lastInput = LastInputType.left; carMotor.TurnLeft(); } } } else { // Go Forward CheckForWiggles(LastInputType.forward); lastInput = LastInputType.forward; carMotor.GoForward(); } } } else //If the AI is stuck in a local minima, record the local minima location { localMinimas++; if (recordLocalMinima) { proxSensor.RecordLocalMinimaAtPosition(transform.position); } wiggleCount = 0; } break; case CarState.Idle: if (collectionComplete) { if (!printedResults) { if (restrictTime) { Debug.Log("Points: " + points + " - Collisions: " + collisions + " - Local Minima: " + localMinimas); } else { Debug.Log("Time taken(s): " + currentTime + " - Total Distance Travelled(u): " + totalDistanceTravelled + " - Points: " + points + " - Collisions: " + collisions + " - Local Minima: " + localMinimas); } printedResults = true; } stateText.text = "Collected all known objects!"; } else if (ranOutOfTime) { stateText.text = "Ran out of time!"; } else { stateText.text = "AI is in Idle mode"; } break; } }