public void SetupSession(TrainingSessionData sessionData)
    {
        shotSession          = (ShotSessionData)sessionData;
        shootInterval        = shotSession.shootInterval;
        shotTasks            = shotSession.shotTaskList.ToArray();
        currentShotTaskIndex = 0;
        previousShotTask     = null;
        currentShotTask      = shotTasks[currentShotTaskIndex];
        nextShotTask         = currentShotTaskIndex + 1 < shotTasks.Length ? shotTasks[currentShotTaskIndex + 1] : null;

        shotSession.MaximumScore = GetMaxScore(shotSession);

        queuedBalls = Utility.CreateMonoBehaviourPool <TennisBall>(ballPrefab, numberPooledBalls, trainingBallsParent);

        ballMachine.MoveTo(currentShotTask.BallMachineShot.StartPosition);
        ballMachine.AimAt(currentShotTask.BallMachineShot.TargetPosition);
        shotZoneHighlighter.ScaleAndPositionZone(currentShotTask.TaskCourtZone);
        shotZoneHighlighter.ColourZone(currentShotTask.TaskShotType);
        shotSessionEventRelay.ChangeTask(currentShotTask);
        shotSessionEventRelay.ChangeProgress(0);
        shotSessionEventRelay.ChangeScore(0);
        shotSessionEventRelay.ChangeCombo(0);

        gameObject.SetActive(true);
    }
    public void CleanupSession()
    {
        shotSession          = null;
        shootInterval        = 0;
        shotTasks            = null;
        currentShotTaskIndex = 0;
        previousShotTask     = null;
        currentShotTask      = null;
        nextShotTask         = null;
        currentScore         = 0;
        currentCombo         = 0;
        bestCombo            = 0;

        currentPlayBall = null;
        foreach (TennisBall ball in queuedBalls)
        {
            Destroy(ball.gameObject);
        }

        queuedBalls.Clear();

        gameObject.SetActive(false);
    }