< Summary

Class:DCL.Tutorial.TutorialController
Assembly:Onboarding
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Tutorial/Scripts/TutorialController.cs
Covered lines:107
Uncovered lines:127
Coverable lines:234
Total lines:665
Line coverage:45.7% (107 of 234)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
TutorialController()0%110100%
Awake()0%110100%
Start()0%3.333066.67%
OnDestroy()0%3.043083.33%
SetTutorialEnabled(...)0%2100%
SetTutorialEnabledForUsersThatAlreadyDidTheTutorial(...)0%6200%
SetBuilderInWorldTutorialEnabled()0%2100%
SetupTutorial(...)0%90900%
SetTutorialDisabled()0%7.897073.68%
StartTutorialFromStep()0%23.2116069.57%
ShowTeacher3DModel(...)0%110100%
SetTeacherPosition(...)0%3.333066.67%
PlayTeacherAnimation(...)0%110100%
SetTeacherCanvasSortingOrder(...)0%2100%
SkipTutorial()0%8.147071.43%
SetEagleEyeCameraActive(...)0%20400%
OnRenderingStateChanged(...)0%30500%
ExecuteSteps()0%29.7527084.44%
SetUserTutorialStepAsCompleted(...)0%110100%
MoveTeacher()0%30500%
IsTaskbarHUDInitialized_OnChange(...)0%64050%
MoreMenu_OnRestartTutorial()0%2100%
IsPlayerInsideGenesisPlaza()0%30500%
SendStepStartedSegmentStats(...)0%2100%
SendStepCompletedSegmentStats(...)0%2100%
SendSkipTutorialSegmentStats(...)0%2100%
EagleEyeCameraRotation()0%12300%
BlockPlayerCameraUntilBlendingIsFinished()0%2401500%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Tutorial/Scripts/TutorialController.cs

#LineLine coverage
 1using DCL.Controllers;
 2using DCL.Interface;
 3using System;
 4using System.Collections;
 5using System.Collections.Generic;
 6using UnityEngine;
 7using UnityEngine.UI;
 8using Cinemachine;
 9using DCL.Helpers;
 10
 11namespace DCL.Tutorial
 12{
 13    /// <summary>
 14    /// Controller that handles all the flow related to the onboarding tutorial.
 15    /// </summary>
 16    public class TutorialController : MonoBehaviour
 17    {
 18        [System.Serializable]
 19        public class TutorialInitializationMessage
 20        {
 21            public string fromDeepLink;
 22            public string enableNewTutorialCamera;
 23        }
 24
 25        [Flags]
 26        public enum TutorialFinishStep
 27        {
 28            None = 0,
 29            OldTutorialValue = 99, // NOTE: old tutorial set tutorialStep to 99 when finished
 30            EmailRequested = 128, // NOTE: old email prompt set tutorialStep to 128 when finished
 31            NewTutorialFinished = 256
 32        }
 33
 34        public enum TutorialType
 35        {
 36            Initial,
 37            BuilderInWorld
 38        }
 39
 40        internal enum TutorialPath
 41        {
 42            FromGenesisPlaza,
 43            FromDeepLink,
 44            FromResetTutorial,
 45            FromBuilderInWorld,
 46            FromUserThatAlreadyDidTheTutorial
 47        }
 48
 049        public static TutorialController i { get; private set; }
 50
 051        public HUDController hudController { get => HUDController.i; }
 52
 053        public int currentStepIndex { get; private set; }
 54        public event Action OnTutorialEnabled;
 55        public event Action OnTutorialDisabled;
 56
 57        private const string PLAYER_PREFS_VOICE_CHAT_FEATURE_SHOWED = "VoiceChatFeatureShowed";
 58
 59        [Header("General Configuration")]
 60        [SerializeField]
 1161        internal int tutorialVersion = 1;
 62
 63        [SerializeField]
 1164        internal float timeBetweenSteps = 0.5f;
 65
 66        [SerializeField]
 1167        internal bool sendStats = true;
 68
 69        [Header("Tutorial Steps on Genesis Plaza")]
 70        [SerializeField]
 1171        internal List<TutorialStep> stepsOnGenesisPlaza = new List<TutorialStep>();
 72
 73        [Header("Tutorial Steps from Deep Link")]
 74        [SerializeField]
 1175        internal List<TutorialStep> stepsFromDeepLink = new List<TutorialStep>();
 76
 77        [Header("Tutorial Steps from Reset Tutorial")]
 78        [SerializeField]
 1179        internal List<TutorialStep> stepsFromReset = new List<TutorialStep>();
 80
 81        [Header("Tutorial Steps from Builder In World")]
 82        [SerializeField]
 1183        internal List<TutorialStep> stepsFromBuilderInWorld = new List<TutorialStep>();
 84
 85        [Header("Tutorial Steps from User That Already Did The Tutorial")]
 86        [SerializeField]
 1187        internal List<TutorialStep> stepsFromUserThatAlreadyDidTheTutorial = new List<TutorialStep>();
 88
 89        [Header("3D Model Teacher")]
 90        [SerializeField]
 91        internal Camera teacherCamera;
 92
 93        [SerializeField]
 94        internal RawImage teacherRawImage;
 95
 96        [SerializeField]
 97        internal TutorialTeacher teacher;
 98
 99        [SerializeField]
 11100        internal float teacherMovementSpeed = 4f;
 101
 102        [SerializeField]
 103        internal AnimationCurve teacherMovementCurve;
 104
 105        [SerializeField]
 106        internal Canvas teacherCanvas;
 107
 108        [Header("Eagle Eye Camera")]
 109        [SerializeField]
 110        internal CinemachineVirtualCamera eagleEyeCamera;
 111
 112        [SerializeField]
 11113        internal Vector3 eagleCamInitPosition = new Vector3(30, 30, -50);
 114
 115        [SerializeField]
 11116        internal Vector3 eagleCamInitLookAtPoint = new Vector3(0, 0, 0);
 117
 118        [SerializeField]
 11119        internal bool eagleCamRotationActived = true;
 120
 121        [SerializeField]
 11122        internal float eagleCamRotationSpeed = 1f;
 123
 124        [Header("Debugging")]
 125        [SerializeField]
 126        internal bool debugRunTutorial = false;
 127
 128        [SerializeField]
 129        internal int debugStartingStepIndex;
 130
 131        [SerializeField]
 132        internal bool debugOpenedFromDeepLink = false;
 133
 134        internal bool isRunning = false;
 135        internal bool openedFromDeepLink = false;
 136        internal bool playerIsInGenesisPlaza = false;
 137        internal TutorialStep runningStep = null;
 138        internal bool tutorialReset = false;
 139        internal float elapsedTimeInCurrentStep = 0f;
 140        internal TutorialPath currentPath;
 141        internal int currentStepNumber;
 142        internal TutorialType tutorialType = TutorialType.Initial;
 143
 144        private Coroutine executeStepsCoroutine;
 145        private Coroutine teacherMovementCoroutine;
 146        private Coroutine eagleEyeRotationCoroutine;
 147
 0148        internal bool userAlreadyDidTheTutorial { get; set; }
 149
 150        private void Awake()
 151        {
 10152            i = this;
 10153            ShowTeacher3DModel(false);
 10154        }
 155
 156        private void Start()
 157        {
 4158            if (CommonScriptableObjects.isTaskbarHUDInitialized.Get())
 4159                IsTaskbarHUDInitialized_OnChange(true, false);
 160            else
 0161                CommonScriptableObjects.isTaskbarHUDInitialized.OnChange += IsTaskbarHUDInitialized_OnChange;
 162
 4163            if (debugRunTutorial)
 164            {
 0165                SetTutorialEnabled(JsonUtility.ToJson(new TutorialInitializationMessage
 166                {
 167                    fromDeepLink = debugOpenedFromDeepLink.ToString(),
 168                    enableNewTutorialCamera = false.ToString()
 169                }));
 170            }
 4171        }
 172
 173        private void OnDestroy()
 174        {
 10175            SetTutorialDisabled();
 176
 10177            CommonScriptableObjects.isTaskbarHUDInitialized.OnChange -= IsTaskbarHUDInitialized_OnChange;
 178
 10179            if (hudController != null &&
 180                hudController.taskbarHud != null)
 181            {
 0182                hudController.taskbarHud.moreMenu.OnRestartTutorial -= MoreMenu_OnRestartTutorial;
 183            }
 184
 10185            NotificationsController.disableWelcomeNotification = false;
 10186        }
 187
 188        public void SetTutorialEnabled(string json)
 189        {
 0190            TutorialInitializationMessage msg = JsonUtility.FromJson<TutorialInitializationMessage>(json);
 0191            SetupTutorial(msg.fromDeepLink, msg.enableNewTutorialCamera, TutorialType.Initial);
 0192        }
 193
 194        public void SetTutorialEnabledForUsersThatAlreadyDidTheTutorial(string json)
 195        {
 0196            TutorialInitializationMessage msg = JsonUtility.FromJson<TutorialInitializationMessage>(json);
 197
 198            // TODO (Santi): This a TEMPORAL fix. It will be removed when we refactorize the tutorial system in order to
 0199            if (PlayerPrefsUtils.GetInt(PLAYER_PREFS_VOICE_CHAT_FEATURE_SHOWED) == 1)
 0200                return;
 201
 0202            SetupTutorial(false.ToString(), msg.enableNewTutorialCamera, TutorialType.Initial, true);
 0203        }
 204
 0205        public void SetBuilderInWorldTutorialEnabled() { SetupTutorial(false.ToString(), false.ToString(), TutorialType.
 206
 207        /// <summary>
 208        /// Enables the tutorial controller and waits for the RenderingState is enabled to start to execute the correspo
 209        /// </summary>
 210        void SetupTutorial(string fromDeepLink, string enableNewTutorialCamera, TutorialType tutorialType, bool userAlre
 211        {
 0212            if (isRunning)
 0213                return;
 214
 0215            if (Convert.ToBoolean(enableNewTutorialCamera))
 216            {
 0217                eagleCamInitPosition = new Vector3(15, 115, -30);
 0218                eagleCamInitLookAtPoint = new Vector3(16, 105, 6);
 0219                eagleCamRotationActived = false;
 220            }
 221
 0222            isRunning = true;
 0223            this.userAlreadyDidTheTutorial = userAlreadyDidTheTutorial;
 0224            CommonScriptableObjects.allUIHidden.Set(false);
 0225            CommonScriptableObjects.tutorialActive.Set(true);
 0226            openedFromDeepLink = Convert.ToBoolean(fromDeepLink);
 0227            this.tutorialType = tutorialType;
 228
 0229            hudController?.taskbarHud?.ShowTutorialOption(false);
 0230            hudController?.profileHud?.HideProfileMenu();
 231
 0232            NotificationsController.disableWelcomeNotification = true;
 233
 0234            WebInterface.SetDelightedSurveyEnabled(false);
 235
 0236            if (!CommonScriptableObjects.rendererState.Get())
 0237                CommonScriptableObjects.rendererState.OnChange += OnRenderingStateChanged;
 238            else
 0239                OnRenderingStateChanged(true, false);
 240
 0241            OnTutorialEnabled?.Invoke();
 0242        }
 243
 244        /// <summary>
 245        /// Stop and disables the tutorial controller.
 246        /// </summary>
 247        public void SetTutorialDisabled()
 248        {
 18249            CommonScriptableObjects.featureKeyTriggersBlocked.Set(false);
 250
 18251            if (executeStepsCoroutine != null)
 252            {
 0253                StopCoroutine(executeStepsCoroutine);
 0254                executeStepsCoroutine = null;
 255            }
 256
 18257            if (runningStep != null)
 258            {
 0259                Destroy(runningStep.gameObject);
 0260                runningStep = null;
 261            }
 262
 18263            tutorialReset = false;
 18264            isRunning = false;
 18265            ShowTeacher3DModel(false);
 18266            WebInterface.SetDelightedSurveyEnabled(true);
 267
 18268            if (Environment.i != null)
 269            {
 18270                WebInterface.SendSceneExternalActionEvent(Environment.i.world.state.currentSceneId, "tutorial", "end");
 271            }
 272
 18273            NotificationsController.disableWelcomeNotification = false;
 274
 18275            hudController?.taskbarHud?.ShowTutorialOption(true);
 276
 18277            CommonScriptableObjects.tutorialActive.Set(false);
 278
 18279            CommonScriptableObjects.rendererState.OnChange -= OnRenderingStateChanged;
 280
 18281            OnTutorialDisabled?.Invoke();
 0282        }
 283
 284        /// <summary>
 285        /// Starts to execute the tutorial from a specific step (It is needed to call SetTutorialEnabled() before).
 286        /// </summary>
 287        /// <param name="stepIndex">First step to be executed.</param>
 288        public IEnumerator StartTutorialFromStep(int stepIndex)
 289        {
 8290            if (!isRunning)
 0291                yield break;
 292
 8293            if (runningStep != null)
 294            {
 0295                runningStep.OnStepFinished();
 0296                Destroy(runningStep.gameObject);
 0297                runningStep = null;
 298            }
 299
 8300            switch (tutorialType)
 301            {
 302                case TutorialType.Initial:
 8303                    if (userAlreadyDidTheTutorial)
 304                    {
 2305                        yield return ExecuteSteps(TutorialPath.FromUserThatAlreadyDidTheTutorial, stepIndex);
 1306                    }
 6307                    else if (playerIsInGenesisPlaza || tutorialReset)
 308                    {
 4309                        if (tutorialReset)
 310                        {
 2311                            yield return ExecuteSteps(TutorialPath.FromResetTutorial, stepIndex);
 1312                        }
 313                        else
 314                        {
 2315                            yield return ExecuteSteps(TutorialPath.FromGenesisPlaza, stepIndex);
 316                        }
 1317                    }
 2318                    else if (openedFromDeepLink)
 319                    {
 2320                        yield return ExecuteSteps(TutorialPath.FromDeepLink, stepIndex);
 1321                    }
 322                    else
 323                    {
 0324                        SetTutorialDisabled();
 0325                        yield break;
 326                    }
 327
 328                    break;
 329                case TutorialType.BuilderInWorld:
 0330                    yield return ExecuteSteps(TutorialPath.FromBuilderInWorld, stepIndex);
 331                    break;
 332            }
 4333        }
 334
 335        /// <summary>
 336        /// Shows the teacher that will be guiding along the tutorial.
 337        /// </summary>
 338        /// <param name="active">True for show the teacher.</param>
 339        public void ShowTeacher3DModel(bool active)
 340        {
 30341            teacherCamera.enabled = active;
 30342            teacherRawImage.gameObject.SetActive(active);
 30343        }
 344
 345        /// <summary>
 346        /// Move the tutorial teacher to a specific position.
 347        /// </summary>
 348        /// <param name="position">Target position.</param>
 349        /// <param name="animated">True for apply a smooth movement.</param>
 350        public void SetTeacherPosition(Vector2 position, bool animated = true)
 351        {
 2352            if (teacherMovementCoroutine != null)
 0353                StopCoroutine(teacherMovementCoroutine);
 354
 2355            if (animated)
 0356                teacherMovementCoroutine = StartCoroutine(MoveTeacher(teacherRawImage.rectTransform.position, position))
 357            else
 2358                teacherRawImage.rectTransform.position = position;
 2359        }
 360
 361        /// <summary>
 362        /// Plays a specific animation on the tutorial teacher.
 363        /// </summary>
 364        /// <param name="animation">Animation to apply.</param>
 40365        public void PlayTeacherAnimation(TutorialTeacher.TeacherAnimation animation) { teacher.PlayAnimation(animation);
 366
 367        /// <summary>
 368        /// Set sort order for canvas containing teacher RawImage
 369        /// </summary>
 370        /// <param name="sortOrder"></param>
 0371        public void SetTeacherCanvasSortingOrder(int sortOrder) { teacherCanvas.sortingOrder = sortOrder; }
 372
 373        /// <summary>
 374        /// Finishes the current running step, skips all the next ones and completes the tutorial.
 375        /// </summary>
 376        public void SkipTutorial()
 377        {
 4378            if (!debugRunTutorial && sendStats)
 379            {
 0380                SendSkipTutorialSegmentStats(
 381                    tutorialVersion,
 382                    runningStep.name.Replace("(Clone)", "").Replace("TutorialStep_", ""));
 383            }
 384
 4385            int skipIndex = stepsOnGenesisPlaza.Count +
 386                            stepsFromDeepLink.Count +
 387                            stepsFromReset.Count +
 388                            stepsFromBuilderInWorld.Count +
 389                            stepsFromUserThatAlreadyDidTheTutorial.Count;
 390
 4391            StartCoroutine(StartTutorialFromStep(skipIndex));
 392
 4393            hudController?.taskbarHud?.SetVisibility(true);
 4394            hudController?.profileHud?.SetBackpackButtonVisibility(true);
 0395        }
 396
 397        /// <summary>
 398        /// Activate/deactivate the eagle eye camera.
 399        /// </summary>
 400        /// <param name="isActive">True for activate the eagle eye camera.</param>
 401        public void SetEagleEyeCameraActive(bool isActive)
 402        {
 0403            eagleEyeCamera.gameObject.SetActive(isActive);
 0404            StartCoroutine(BlockPlayerCameraUntilBlendingIsFinished(isActive));
 405
 0406            if (isActive)
 407            {
 0408                eagleEyeCamera.transform.position = eagleCamInitPosition;
 0409                eagleEyeCamera.transform.LookAt(eagleCamInitLookAtPoint);
 410
 0411                if (eagleCamRotationActived)
 0412                    eagleEyeRotationCoroutine = StartCoroutine(EagleEyeCameraRotation(eagleCamRotationSpeed));
 0413            }
 0414            else if (eagleEyeRotationCoroutine != null)
 415            {
 0416                StopCoroutine(eagleEyeRotationCoroutine);
 417            }
 0418        }
 419
 420        private void OnRenderingStateChanged(bool renderingEnabled, bool prevState)
 421        {
 0422            if (!renderingEnabled)
 0423                return;
 424
 0425            CommonScriptableObjects.rendererState.OnChange -= OnRenderingStateChanged;
 426
 0427            playerIsInGenesisPlaza = IsPlayerInsideGenesisPlaza();
 428
 0429            if (debugRunTutorial)
 0430                currentStepIndex = debugStartingStepIndex >= 0 ? debugStartingStepIndex : 0;
 431            else
 0432                currentStepIndex = 0;
 433
 0434            PlayTeacherAnimation(TutorialTeacher.TeacherAnimation.Reset);
 0435            executeStepsCoroutine = StartCoroutine(StartTutorialFromStep(currentStepIndex));
 0436        }
 437
 438        private IEnumerator ExecuteSteps(TutorialPath tutorialPath, int startingStepIndex)
 439        {
 8440            List<TutorialStep> steps = new List<TutorialStep>();
 441
 442            switch (tutorialPath)
 443            {
 444                case TutorialPath.FromGenesisPlaza:
 2445                    steps = stepsOnGenesisPlaza;
 2446                    break;
 447                case TutorialPath.FromDeepLink:
 2448                    steps = stepsFromDeepLink;
 2449                    break;
 450                case TutorialPath.FromResetTutorial:
 2451                    steps = stepsFromReset;
 2452                    break;
 453                case TutorialPath.FromBuilderInWorld:
 0454                    steps = stepsFromBuilderInWorld;
 0455                    break;
 456                case TutorialPath.FromUserThatAlreadyDidTheTutorial:
 2457                    steps = stepsFromUserThatAlreadyDidTheTutorial;
 458                    break;
 459            }
 460
 8461            currentPath = tutorialPath;
 462
 8463            elapsedTimeInCurrentStep = 0f;
 56464            for (int i = startingStepIndex; i < steps.Count; i++)
 465            {
 20466                var stepPrefab = steps[i];
 467
 468                // TODO (Santi): This a TEMPORAL fix. It will be removed when we refactorize the tutorial system in orde
 20469                if (stepPrefab is TutorialStep_Tooltip_UsersAround &&
 470                    CommonScriptableObjects.voiceChatDisabled.Get())
 471                    continue;
 472
 20473                if (stepPrefab.letInstantiation)
 0474                    runningStep = Instantiate(stepPrefab, this.transform).GetComponent<TutorialStep>();
 475                else
 20476                    runningStep = steps[i];
 477
 20478                currentStepIndex = i;
 479
 20480                elapsedTimeInCurrentStep = Time.realtimeSinceStartup;
 20481                currentStepNumber = i + 1;
 482
 20483                if (!debugRunTutorial && sendStats)
 484                {
 0485                    SendStepStartedSegmentStats(
 486                        tutorialVersion,
 487                        tutorialPath,
 488                        i + 1,
 489                        runningStep.name.Replace("(Clone)", "").Replace("TutorialStep_", ""));
 490                }
 491
 20492                if (tutorialPath == TutorialPath.FromUserThatAlreadyDidTheTutorial &&
 493                    runningStep is TutorialStep_Tooltip)
 494                {
 0495                    ((TutorialStep_Tooltip) runningStep).OverrideSetMaxTimeToHide(true);
 496                }
 497
 20498                runningStep.OnStepStart();
 20499                yield return runningStep.OnStepExecute();
 20500                if (i < steps.Count - 1)
 16501                    PlayTeacherAnimation(TutorialTeacher.TeacherAnimation.StepCompleted);
 502                else
 4503                    PlayTeacherAnimation(TutorialTeacher.TeacherAnimation.QuickGoodbye);
 504
 20505                yield return runningStep.OnStepPlayHideAnimation();
 20506                runningStep.OnStepFinished();
 20507                elapsedTimeInCurrentStep = Time.realtimeSinceStartup - elapsedTimeInCurrentStep;
 508
 20509                if (!debugRunTutorial &&
 510                    sendStats &&
 511                    tutorialPath != TutorialPath.FromUserThatAlreadyDidTheTutorial)
 512                {
 0513                    SendStepCompletedSegmentStats(
 514                        tutorialVersion,
 515                        tutorialPath,
 516                        i + 1,
 517                        runningStep.name.Replace("(Clone)", "").Replace("TutorialStep_", ""),
 518                        elapsedTimeInCurrentStep);
 519                }
 520
 20521                Destroy(runningStep.gameObject);
 522
 20523                if (i < steps.Count - 1 && timeBetweenSteps > 0)
 0524                    yield return new WaitForSeconds(timeBetweenSteps);
 525            }
 526
 8527            if (!debugRunTutorial &&
 528                tutorialPath != TutorialPath.FromBuilderInWorld &&
 529                tutorialPath != TutorialPath.FromUserThatAlreadyDidTheTutorial)
 530            {
 6531                SetUserTutorialStepAsCompleted(TutorialFinishStep.NewTutorialFinished);
 532            }
 533
 8534            runningStep = null;
 535
 8536            SetTutorialDisabled();
 8537        }
 538
 12539        private void SetUserTutorialStepAsCompleted(TutorialFinishStep finishStepType) { WebInterface.SaveUserTutorialSt
 540
 541        private IEnumerator MoveTeacher(Vector2 fromPosition, Vector2 toPosition)
 542        {
 0543            float t = 0f;
 544
 0545            while (Vector2.Distance(teacherRawImage.rectTransform.position, toPosition) > 0)
 546            {
 0547                t += teacherMovementSpeed * Time.deltaTime;
 0548                if (t <= 1.0f)
 0549                    teacherRawImage.rectTransform.position = Vector2.Lerp(fromPosition, toPosition, teacherMovementCurve
 550                else
 0551                    teacherRawImage.rectTransform.position = toPosition;
 552
 0553                yield return null;
 554            }
 0555        }
 556
 557        private void IsTaskbarHUDInitialized_OnChange(bool current, bool previous)
 558        {
 4559            if (current &&
 560                hudController != null &&
 561                hudController.taskbarHud != null)
 562            {
 0563                hudController.taskbarHud.moreMenu.OnRestartTutorial -= MoreMenu_OnRestartTutorial;
 0564                hudController.taskbarHud.moreMenu.OnRestartTutorial += MoreMenu_OnRestartTutorial;
 565            }
 4566        }
 567
 568        private void MoreMenu_OnRestartTutorial()
 569        {
 0570            SetTutorialDisabled();
 0571            tutorialReset = true;
 0572            SetTutorialEnabled(JsonUtility.ToJson(new TutorialInitializationMessage
 573            {
 574                fromDeepLink = false.ToString(),
 575                enableNewTutorialCamera = false.ToString()
 576            }));
 0577        }
 578
 579        private bool IsPlayerInsideGenesisPlaza()
 580        {
 0581            IWorldState worldState = Environment.i.world.state;
 582
 0583            if (worldState == null || worldState.currentSceneId == null)
 0584                return false;
 585
 0586            Vector2Int genesisPlazaBaseCoords = new Vector2Int(-9, -9);
 587
 0588            IParcelScene currentScene = worldState.loadedScenes[worldState.currentSceneId];
 589
 0590            if (currentScene != null && currentScene.IsInsideSceneBoundaries(genesisPlazaBaseCoords))
 0591                return true;
 592
 0593            return false;
 594        }
 595
 596        private void SendStepStartedSegmentStats(int version, TutorialPath tutorialPath, int stepNumber, string stepName
 597        {
 0598            WebInterface.AnalyticsPayload.Property[] properties = new WebInterface.AnalyticsPayload.Property[]
 599            {
 600                new WebInterface.AnalyticsPayload.Property("version", version.ToString()),
 601                new WebInterface.AnalyticsPayload.Property("path", tutorialPath.ToString()),
 602                new WebInterface.AnalyticsPayload.Property("step number", stepNumber.ToString()),
 603                new WebInterface.AnalyticsPayload.Property("step name", stepName)
 604            };
 0605            WebInterface.ReportAnalyticsEvent("tutorial step started", properties);
 0606        }
 607
 608        private void SendStepCompletedSegmentStats(int version, TutorialPath tutorialPath, int stepNumber, string stepNa
 609        {
 0610            WebInterface.AnalyticsPayload.Property[] properties = new WebInterface.AnalyticsPayload.Property[]
 611            {
 612                new WebInterface.AnalyticsPayload.Property("version", version.ToString()),
 613                new WebInterface.AnalyticsPayload.Property("path", tutorialPath.ToString()),
 614                new WebInterface.AnalyticsPayload.Property("step number", stepNumber.ToString()),
 615                new WebInterface.AnalyticsPayload.Property("step name", stepName),
 616                new WebInterface.AnalyticsPayload.Property("elapsed time", elapsedTime.ToString("0.00"))
 617            };
 0618            WebInterface.ReportAnalyticsEvent("tutorial step completed", properties);
 0619        }
 620
 621        private void SendSkipTutorialSegmentStats(int version, string stepName)
 622        {
 0623            WebInterface.AnalyticsPayload.Property[] properties = new WebInterface.AnalyticsPayload.Property[]
 624            {
 625                new WebInterface.AnalyticsPayload.Property("version", version.ToString()),
 626                new WebInterface.AnalyticsPayload.Property("path", currentPath.ToString()),
 627                new WebInterface.AnalyticsPayload.Property("step number", currentStepNumber.ToString()),
 628                new WebInterface.AnalyticsPayload.Property("step name", stepName),
 629                new WebInterface.AnalyticsPayload.Property("elapsed time", (Time.realtimeSinceStartup - elapsedTimeInCur
 630            };
 0631            WebInterface.ReportAnalyticsEvent("tutorial skipped", properties);
 0632        }
 633
 634        private IEnumerator EagleEyeCameraRotation(float rotationSpeed)
 635        {
 0636            while (true)
 637            {
 0638                eagleEyeCamera.transform.Rotate(Vector3.up * Time.deltaTime * rotationSpeed, Space.World);
 0639                yield return null;
 640            }
 641        }
 642
 643        private IEnumerator BlockPlayerCameraUntilBlendingIsFinished(bool hideUIs)
 644        {
 0645            if (hideUIs)
 646            {
 0647                hudController?.minimapHud?.SetVisibility(false);
 0648                hudController?.profileHud?.SetVisibility(false);
 649            }
 650
 0651            CommonScriptableObjects.cameraBlocked.Set(true);
 652
 0653            yield return null;
 0654            yield return new WaitUntil(() => !CommonScriptableObjects.cameraIsBlending.Get());
 655
 0656            CommonScriptableObjects.cameraBlocked.Set(false);
 657
 0658            if (!hideUIs)
 659            {
 0660                hudController?.minimapHud?.SetVisibility(true);
 0661                hudController?.profileHud?.SetVisibility(true);
 662            }
 0663        }
 664    }
 665}