< Summary

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

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
TutorialController(...)0%2100%
CreateTutorialView()0%2100%
SetConfiguration(...)0%12300%
Dispose()0%20400%
SetTutorialEnabled(...)0%2100%
SetTutorialEnabledForUsersThatAlreadyDidTheTutorial(...)0%6200%
SetupTutorial(...)0%1101000%
SetTutorialDisabled()0%90900%
StartTutorialFromStep()0%56700%
ExecuteRespectiveTutorialStep()0%1101000%
ShowTeacher3DModel(...)0%12300%
SetTeacherPosition(...)0%20400%
PlayTeacherAnimation(...)0%6200%
SetTeacherCanvasSortingOrder(...)0%6200%
SkipTutorial(...)0%30500%
GoToSpecificStep(...)0%42600%
SetNextSkippedSteps(...)0%2100%
SetEagleEyeCameraActive(...)0%20400%
OnRenderingStateChanged(...)0%20400%
ExecuteSteps()0%1101000%
IterateSteps()0%1101000%
RunStep()0%1101000%
NeedToSendStats()0%6200%
SetUserTutorialStepAsCompleted(...)0%2100%
MoveTeacher()0%56700%
IsSettingsHUDInitialized_OnChange(...)0%20400%
OnRestartTutorial()0%2100%
IsPlayerInScene()0%6200%
IsPlayerInsideGenesisPlaza()0%20400%
SendStepStartedSegmentStats(...)0%2100%
SendStepCompletedSegmentStats(...)0%2100%
SendSkipTutorialSegmentStats(...)0%2100%
StepNameForStatsMessage(...)0%2100%
EagleEyeCameraRotation()0%12300%
BlockPlayerCameraUntilBlendingIsFinished()0%56700%

File(s)

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

#LineLine coverage
 1using DCL.Controllers;
 2using DCL.Helpers;
 3using DCL.Interface;
 4using System;
 5using System.Collections;
 6using System.Collections.Generic;
 7using UnityEngine;
 8using Object = UnityEngine.Object;
 9
 10namespace DCL.Tutorial
 11{
 12    /// <summary>
 13    /// Controller that handles all the flow related to the onboarding tutorial.
 14    /// </summary>
 15    public class TutorialController : IPlugin
 16    {
 17        [Serializable]
 18        public class TutorialInitializationMessage
 19        {
 20            public string fromDeepLink;
 21            public string enableNewTutorialCamera;
 22        }
 23
 24        [Flags]
 25        public enum TutorialFinishStep
 26        {
 27            None = 0,
 28            OldTutorialValue = 99, // NOTE: old tutorial set tutorialStep to 99 when finished
 29            EmailRequested = 128, // NOTE: old email prompt set tutorialStep to 128 when finished
 30            NewTutorialFinished = 256,
 31        }
 32
 33        internal enum TutorialPath
 34        {
 35            FromGenesisPlaza,
 36            FromDeepLink,
 37            FromResetTutorial,
 38            FromUserThatAlreadyDidTheTutorial,
 39        }
 40
 041        public static TutorialController i { get; private set; }
 42
 043        public HUDController hudController => HUDController.i;
 44
 045        public int currentStepIndex { get; internal set; }
 46        public event Action OnTutorialEnabled;
 47        public event Action OnTutorialDisabled;
 48
 49        private const string PLAYER_PREFS_START_MENU_SHOWED = "StartMenuFeatureShowed";
 50
 51        private readonly DataStore_Common commonDataStore;
 52        private readonly DataStore_Settings settingsDataStore;
 53        private readonly DataStore_ExploreV2 exploreV2DataStore;
 54
 55        internal readonly TutorialView tutorialView;
 56
 57        internal TutorialSettings configuration;
 58
 59        internal bool openedFromDeepLink;
 60        internal bool playerIsInGenesisPlaza;
 61        internal TutorialStep runningStep;
 62        internal bool tutorialReset;
 63        private float elapsedTimeInCurrentStep;
 64        internal TutorialPath currentPath;
 65        private int currentStepNumber;
 66        private int nextStepsToSkip;
 67
 68        private Coroutine executeStepsCoroutine;
 69        private Coroutine teacherMovementCoroutine;
 70        private Coroutine eagleEyeRotationCoroutine;
 71
 072        internal bool userAlreadyDidTheTutorial { get; set; }
 73
 074        public TutorialController(DataStore_Common commonDataStore, DataStore_Settings settingsDataStore, DataStore_Expl
 75        {
 076            this.commonDataStore = commonDataStore;
 077            this.settingsDataStore = settingsDataStore;
 078            this.exploreV2DataStore = exploreV2DataStore;
 79
 080            i = this;
 81
 082            tutorialView = CreateTutorialView();
 083            SetConfiguration(tutorialView.configuration);
 084        }
 85
 86        private TutorialView CreateTutorialView()
 87        {
 088            GameObject tutorialObject = Object.Instantiate(Resources.Load<GameObject>("TutorialView"));
 089            tutorialObject.name = "TutorialController";
 90
 091            TutorialView view = tutorialObject.GetComponent<TutorialView>();
 092            view.ConfigureView(this);
 93
 094            return view;
 95        }
 96
 97        public void SetConfiguration(TutorialSettings config)
 98        {
 099            configuration = config;
 100
 0101            ShowTeacher3DModel(false);
 102
 0103            if (settingsDataStore.isInitialized.Get())
 0104                IsSettingsHUDInitialized_OnChange(true, false);
 105            else
 0106                settingsDataStore.isInitialized.OnChange += IsSettingsHUDInitialized_OnChange;
 107
 0108            if (config.debugRunTutorial)
 0109                SetTutorialEnabled(JsonUtility.ToJson(new TutorialInitializationMessage
 110                {
 111                    fromDeepLink = config.debugOpenedFromDeepLink.ToString(),
 112                    enableNewTutorialCamera = false.ToString(),
 113                }));
 0114        }
 115
 116        public void Dispose()
 117        {
 0118            SetTutorialDisabled();
 119
 0120            settingsDataStore.isInitialized.OnChange -= IsSettingsHUDInitialized_OnChange;
 121
 0122            if (hudController is { settingsPanelHud: { } })
 0123                hudController.settingsPanelHud.OnRestartTutorial -= OnRestartTutorial;
 124
 0125            NotificationsController.disableWelcomeNotification = false;
 126
 0127            if (tutorialView != null)
 0128                Object.Destroy(tutorialView.gameObject);
 0129        }
 130
 131        public void SetTutorialEnabled(string json)
 132        {
 0133            TutorialInitializationMessage msg = JsonUtility.FromJson<TutorialInitializationMessage>(json);
 0134            SetupTutorial(msg.fromDeepLink, msg.enableNewTutorialCamera);
 0135        }
 136
 137        public void SetTutorialEnabledForUsersThatAlreadyDidTheTutorial(string json)
 138        {
 0139            TutorialInitializationMessage msg = JsonUtility.FromJson<TutorialInitializationMessage>(json);
 140
 141            // TODO (Santi): This a TEMPORAL fix. It will be removed when we refactor the tutorial system in order to ma
 0142            if (PlayerPrefsUtils.GetInt(PLAYER_PREFS_START_MENU_SHOWED) == 1)
 0143                return;
 144
 0145            SetupTutorial(false.ToString(), msg.enableNewTutorialCamera, true);
 0146        }
 147
 148        /// <summary>
 149        /// Enables the tutorial controller and waits for the RenderingState is enabled to start to execute the correspo
 150        /// </summary>
 151        internal void SetupTutorial(string fromDeepLink, string enableNewTutorialCamera, bool userAlreadyDidTheTutorial 
 152        {
 0153            if (commonDataStore.isWorld.Get() || commonDataStore.isTutorialRunning.Get())
 0154                return;
 155
 0156            if (Convert.ToBoolean(enableNewTutorialCamera))
 157            {
 0158                configuration.eagleCamInitPosition = new Vector3(15, 115, -30);
 0159                configuration.eagleCamInitLookAtPoint = new Vector3(16, 105, 6);
 0160                configuration.eagleCamRotationActived = false;
 161            }
 162
 0163            commonDataStore.isTutorialRunning.Set(true);
 0164            this.userAlreadyDidTheTutorial = userAlreadyDidTheTutorial;
 0165            CommonScriptableObjects.allUIHidden.Set(false);
 0166            CommonScriptableObjects.tutorialActive.Set(true);
 0167            openedFromDeepLink = Convert.ToBoolean(fromDeepLink);
 168
 0169            hudController?.settingsPanelHud?.SetTutorialButtonEnabled(false);
 0170            hudController?.profileHud?.HideProfileMenu();
 171
 0172            NotificationsController.disableWelcomeNotification = true;
 173
 0174            WebInterface.SetDelightedSurveyEnabled(false);
 175
 0176            if (!CommonScriptableObjects.rendererState.Get())
 0177                CommonScriptableObjects.rendererState.OnChange += OnRenderingStateChanged;
 178            else
 0179                OnRenderingStateChanged(true, false);
 180
 0181            OnTutorialEnabled?.Invoke();
 0182        }
 183
 184        /// <summary>
 185        /// Stop and disables the tutorial controller.
 186        /// </summary>
 187        public void SetTutorialDisabled()
 188        {
 0189            CommonScriptableObjects.featureKeyTriggersBlocked.Set(false);
 190
 0191            if (executeStepsCoroutine != null)
 192            {
 0193                CoroutineStarter.Stop(executeStepsCoroutine);
 0194                executeStepsCoroutine = null;
 195            }
 196
 0197            if (runningStep != null)
 198            {
 0199                Object.Destroy(runningStep.gameObject);
 0200                runningStep = null;
 201            }
 202
 0203            if (teacherMovementCoroutine != null)
 204            {
 0205                CoroutineStarter.Stop(teacherMovementCoroutine);
 0206                teacherMovementCoroutine = null;
 207            }
 208
 0209            tutorialReset = false;
 0210            commonDataStore.isTutorialRunning.Set(false);
 0211            tutorialView.tutorialMusicHandler.StopTutorialMusic();
 0212            ShowTeacher3DModel(false);
 0213            WebInterface.SetDelightedSurveyEnabled(true);
 214
 0215            if (Environment.i is { world: { } })
 0216                WebInterface.SendSceneExternalActionEvent(Environment.i.world.state.GetCurrentSceneNumber(), "tutorial",
 217
 0218            NotificationsController.disableWelcomeNotification = false;
 219
 0220            hudController?.settingsPanelHud?.SetTutorialButtonEnabled(true);
 221
 0222            CommonScriptableObjects.tutorialActive.Set(false);
 223
 0224            CommonScriptableObjects.rendererState.OnChange -= OnRenderingStateChanged;
 225
 0226            OnTutorialDisabled?.Invoke();
 0227        }
 228
 229        /// <summary>
 230        /// Starts to execute the tutorial from a specific step (It is needed to call SetTutorialEnabled() before).
 231        /// </summary>
 232        /// <param name="stepIndex">First step to be executed.</param>
 233        internal IEnumerator StartTutorialFromStep(int stepIndex)
 234        {
 0235            if (!commonDataStore.isTutorialRunning.Get())
 0236                yield break;
 237
 0238            if (runningStep != null)
 239            {
 0240                runningStep.OnStepFinished();
 0241                Object.Destroy(runningStep.gameObject);
 0242                runningStep = null;
 243            }
 244
 0245            yield return new WaitUntil(IsPlayerInScene);
 246
 0247            playerIsInGenesisPlaza = IsPlayerInsideGenesisPlaza();
 248
 0249            if (playerIsInGenesisPlaza)
 0250                tutorialView.tutorialMusicHandler.TryPlayingMusic();
 251
 0252            yield return ExecuteRespectiveTutorialStep(stepIndex);
 0253        }
 254
 255        private IEnumerator ExecuteRespectiveTutorialStep(int stepIndex)
 256        {
 0257            if (userAlreadyDidTheTutorial)
 0258                yield return ExecuteSteps(TutorialPath.FromUserThatAlreadyDidTheTutorial, stepIndex);
 0259            else if (tutorialReset)
 0260                yield return ExecuteSteps(TutorialPath.FromResetTutorial, stepIndex);
 0261            else if (playerIsInGenesisPlaza)
 0262                yield return ExecuteSteps(TutorialPath.FromGenesisPlaza, stepIndex);
 0263            else if (openedFromDeepLink)
 0264                yield return ExecuteSteps(TutorialPath.FromDeepLink, stepIndex);
 265            else
 0266                SetTutorialDisabled();
 0267        }
 268
 269        /// <summary>
 270        /// Shows the teacher that will be guiding along the tutorial.
 271        /// </summary>
 272        /// <param name="active">True for show the teacher.</param>
 273        public void ShowTeacher3DModel(bool active)
 274        {
 0275            if (configuration.teacherCamera != null)
 0276                configuration.teacherCamera.enabled = active;
 277
 0278            if (configuration.teacherRawImage != null)
 0279                configuration.teacherRawImage.gameObject.SetActive(active);
 0280        }
 281
 282        /// <summary>
 283        /// Move the tutorial teacher to a specific position.
 284        /// </summary>
 285        /// <param name="destinationPosition">Target position.</param>
 286        /// <param name="animated">True for apply a smooth movement.</param>
 287        public void SetTeacherPosition(Vector3 destinationPosition, bool animated = true)
 288        {
 0289            if (teacherMovementCoroutine != null)
 0290                CoroutineStarter.Stop(teacherMovementCoroutine);
 291
 0292            if (configuration.teacherRawImage != null)
 293            {
 0294                if (animated)
 0295                    teacherMovementCoroutine = CoroutineStarter.Start(MoveTeacher(destinationPosition));
 296                else
 0297                    configuration.teacherRawImage.rectTransform.position = new Vector3(destinationPosition.x, destinatio
 298            }
 0299        }
 300
 301        /// <summary>
 302        /// Plays a specific animation on the tutorial teacher.
 303        /// </summary>
 304        /// <param name="animation">Animation to apply.</param>
 305        public void PlayTeacherAnimation(TutorialTeacher.TeacherAnimation animation)
 306        {
 0307            if (configuration.teacher == null)
 0308                return;
 309
 0310            configuration.teacher.PlayAnimation(animation);
 0311        }
 312
 313        /// <summary>
 314        /// Set sort order for canvas containing teacher RawImage
 315        /// </summary>
 316        /// <param name="sortOrder"></param>
 317        public void SetTeacherCanvasSortingOrder(int sortOrder)
 318        {
 0319            if (configuration.teacherCanvas == null)
 0320                return;
 321
 0322            configuration.teacherCanvas.sortingOrder = sortOrder;
 0323        }
 324
 325        /// <summary>
 326        /// Finishes the current running step, skips all the next ones and completes the tutorial.
 327        /// </summary>
 328        public void SkipTutorial(bool ignoreStatsSending = false)
 329        {
 0330            if (!ignoreStatsSending && NeedToSendStats())
 0331                SendSkipTutorialSegmentStats(configuration.tutorialVersion, runningStep.name);
 332
 0333            int skipIndex = configuration.stepsOnGenesisPlaza.Count +
 334                            configuration.stepsFromDeepLink.Count +
 335                            configuration.stepsFromReset.Count +
 336                            configuration.stepsFromUserThatAlreadyDidTheTutorial.Count;
 337
 0338            CoroutineStarter.Start(StartTutorialFromStep(skipIndex));
 339
 0340            hudController?.taskbarHud?.SetVisibility(true);
 0341        }
 342
 343        /// <summary>
 344        /// Jump to a specific step.
 345        /// </summary>
 346        /// <param name="stepName">Step to jump.</param>
 347        public void GoToSpecificStep(string stepName)
 348        {
 349            int stepIndex;
 350
 0351            if (userAlreadyDidTheTutorial)
 0352                stepIndex = configuration.stepsFromUserThatAlreadyDidTheTutorial.FindIndex(x => x.name == stepName);
 0353            else if (tutorialReset)
 0354                stepIndex = configuration.stepsFromReset.FindIndex(x => x.name == stepName);
 0355            else if (playerIsInGenesisPlaza)
 0356                stepIndex = configuration.stepsOnGenesisPlaza.FindIndex(x => x.name == stepName);
 0357            else if (openedFromDeepLink)
 0358                stepIndex = configuration.stepsFromDeepLink.FindIndex(x => x.name == stepName);
 359            else
 0360                stepIndex = 0;
 361
 0362            nextStepsToSkip = 0;
 363
 0364            if (stepIndex >= 0)
 0365                CoroutineStarter.Start(StartTutorialFromStep(stepIndex));
 366            else
 0367                SkipTutorial(true);
 0368        }
 369
 370        /// <summary>
 371        /// Set the number of steps that will be skipped in the next iteration.
 372        /// </summary>
 373        /// <param name="skippedSteps">Number of steps to skip.</param>
 374        public void SetNextSkippedSteps(int skippedSteps) =>
 0375            nextStepsToSkip = skippedSteps;
 376
 377        /// <summary>
 378        /// Activate/deactivate the eagle eye camera.
 379        /// </summary>
 380        /// <param name="isActive">True for activate the eagle eye camera.</param>
 381        public void SetEagleEyeCameraActive(bool isActive)
 382        {
 0383            configuration.eagleEyeCamera.gameObject.SetActive(isActive);
 0384            CoroutineStarter.Start(BlockPlayerCameraUntilBlendingIsFinished(isActive));
 385
 0386            if (isActive)
 387            {
 0388                configuration.eagleEyeCamera.transform.position = configuration.eagleCamInitPosition;
 0389                configuration.eagleEyeCamera.transform.LookAt(configuration.eagleCamInitLookAtPoint);
 390
 0391                if (configuration.eagleCamRotationActived)
 0392                    eagleEyeRotationCoroutine = CoroutineStarter.Start(EagleEyeCameraRotation(configuration.eagleCamRota
 393            }
 0394            else if (eagleEyeRotationCoroutine != null)
 0395                CoroutineStarter.Stop(eagleEyeRotationCoroutine);
 0396        }
 397
 398        internal void OnRenderingStateChanged(bool renderingEnabled, bool prevState)
 399        {
 0400            if (!renderingEnabled)
 0401                return;
 402
 0403            CommonScriptableObjects.rendererState.OnChange -= OnRenderingStateChanged;
 404
 0405            currentStepIndex = configuration.debugRunTutorial ?  configuration.debugStartingStepIndex : 0;
 406
 0407            PlayTeacherAnimation(TutorialTeacher.TeacherAnimation.Reset);
 0408            executeStepsCoroutine = CoroutineStarter.Start(StartTutorialFromStep(currentStepIndex));
 0409        }
 410
 411        private IEnumerator ExecuteSteps(TutorialPath tutorialPath, int startingStepIndex)
 412        {
 0413            List<TutorialStep> steps = tutorialPath switch
 414                                       {
 0415                                           TutorialPath.FromGenesisPlaza => configuration.stepsOnGenesisPlaza,
 0416                                           TutorialPath.FromDeepLink => configuration.stepsFromDeepLink,
 0417                                           TutorialPath.FromResetTutorial => configuration.stepsFromReset,
 0418                                           TutorialPath.FromUserThatAlreadyDidTheTutorial => configuration.stepsFromUser
 0419                                           _ => new List<TutorialStep>(),
 420                                       };
 421
 0422            currentPath = tutorialPath;
 423
 0424            elapsedTimeInCurrentStep = 0f;
 425
 0426            yield return IterateSteps(tutorialPath, startingStepIndex, steps);
 427
 0428            if (!configuration.debugRunTutorial && tutorialPath != TutorialPath.FromUserThatAlreadyDidTheTutorial)
 0429                SetUserTutorialStepAsCompleted(TutorialFinishStep.NewTutorialFinished);
 430
 0431            runningStep = null;
 432
 0433            SetTutorialDisabled();
 0434        }
 435
 436        private IEnumerator IterateSteps(TutorialPath tutorialPath, int startingStepIndex, List<TutorialStep> steps)
 437        {
 0438            for (int stepId = startingStepIndex; stepId < steps.Count; stepId++)
 439            {
 0440                if (nextStepsToSkip > 0)
 441                {
 0442                    nextStepsToSkip--;
 0443                    continue;
 444                }
 445
 0446                TutorialStep stepPrefab = steps[stepId];
 447
 448                // TODO (Santi): This a TEMPORAL fix. It will be removed when we refactorize the tutorial system in orde
 0449                if (stepPrefab is TutorialStep_Tooltip_ExploreButton && !exploreV2DataStore.isInitialized.Get())
 450                    continue;
 451
 0452                yield return RunStep(tutorialPath, stepPrefab, stepId, steps);
 453
 0454                if (stepId < steps.Count - 1 && configuration.timeBetweenSteps > 0)
 0455                    yield return new WaitForSeconds(configuration.timeBetweenSteps);
 456            }
 0457        }
 458
 459        private IEnumerator RunStep(TutorialPath tutorialPath, TutorialStep stepPrefab, int stepId, List<TutorialStep> s
 460        {
 0461            runningStep = stepPrefab.letInstantiation ? Object.Instantiate(stepPrefab, tutorialView.transform).GetCompon
 462
 0463            runningStep.gameObject.name = runningStep.gameObject.name.Replace("(Clone)", "");
 0464            currentStepIndex = stepId;
 465
 0466            elapsedTimeInCurrentStep = Time.realtimeSinceStartup;
 0467            currentStepNumber = stepId + 1;
 468
 0469            if (NeedToSendStats())
 0470                SendStepStartedSegmentStats(configuration.tutorialVersion, tutorialPath, stepId + 1, runningStep.name);
 471
 0472            runningStep.OnStepStart();
 0473            yield return runningStep.OnStepExecute();
 474
 0475            PlayTeacherAnimation(animation: stepId < steps.Count - 1
 476                ? TutorialTeacher.TeacherAnimation.StepCompleted
 477                : TutorialTeacher.TeacherAnimation.QuickGoodbye);
 478
 0479            yield return runningStep.OnStepPlayHideAnimation();
 0480            runningStep.OnStepFinished();
 0481            elapsedTimeInCurrentStep = Time.realtimeSinceStartup - elapsedTimeInCurrentStep;
 482
 0483            if (NeedToSendStats() && tutorialPath != TutorialPath.FromUserThatAlreadyDidTheTutorial)
 0484                SendStepCompletedSegmentStats(configuration.tutorialVersion, tutorialPath, stepId + 1, runningStep.name,
 485
 0486            Object.Destroy(runningStep.gameObject);
 0487        }
 488
 489        private bool NeedToSendStats() =>
 0490            !configuration.debugRunTutorial && configuration.sendStats;
 491
 492        private static void SetUserTutorialStepAsCompleted(TutorialFinishStep finishStepType) =>
 0493            WebInterface.SaveUserTutorialStep(UserProfile.GetOwnUserProfile().tutorialStep | (int)finishStepType);
 494
 495        internal IEnumerator MoveTeacher(Vector3 toPosition)
 496        {
 0497            if (configuration.teacherRawImage == null)
 0498                yield break;
 499
 0500            var t = 0f;
 501
 0502            Vector3 fromPosition = configuration.teacherRawImage.rectTransform.position;
 503
 0504            while (Vector3.Distance(configuration.teacherRawImage.rectTransform.position, toPosition) > 0)
 505            {
 0506                t += configuration.teacherMovementSpeed * Time.deltaTime;
 507
 0508                configuration.teacherRawImage.rectTransform.position = t <= 1.0f
 509                    ? Vector3.Lerp(fromPosition, toPosition, configuration.teacherMovementCurve.Evaluate(t))
 510                    : toPosition;
 511
 0512                yield return null;
 513            }
 0514        }
 515
 516        private void IsSettingsHUDInitialized_OnChange(bool isInitialized, bool _)
 517        {
 0518            if (isInitialized && hudController is { settingsPanelHud: { } })
 519            {
 0520                hudController.settingsPanelHud.OnRestartTutorial -= OnRestartTutorial;
 0521                hudController.settingsPanelHud.OnRestartTutorial += OnRestartTutorial;
 522            }
 0523        }
 524
 525        private void OnRestartTutorial()
 526        {
 0527            SetTutorialDisabled();
 0528            tutorialReset = true;
 529
 0530            SetTutorialEnabled(JsonUtility.ToJson(new TutorialInitializationMessage
 531            {
 532                fromDeepLink = false.ToString(),
 533                enableNewTutorialCamera = false.ToString(),
 534            }));
 0535        }
 536
 537        private static bool IsPlayerInScene()
 538        {
 0539            IWorldState worldState = Environment.i.world.state;
 540
 0541            if (worldState == null || worldState.GetCurrentSceneNumber() == null)
 0542                return false;
 543
 0544            return true;
 545        }
 546
 547        private static bool IsPlayerInsideGenesisPlaza()
 548        {
 0549            if (Environment.i.world == null)
 0550                return false;
 551
 0552            IWorldState worldState = Environment.i.world.state;
 553
 0554            if (worldState == null || worldState.GetCurrentSceneNumber() == null)
 0555                return false;
 556
 0557            var genesisPlazaBaseCoords = new Vector2Int(-9, -9);
 558
 0559            IParcelScene currentScene = worldState.GetScene(worldState.GetCurrentSceneNumber());
 560
 0561            return currentScene != null && currentScene.IsInsideSceneBoundaries(genesisPlazaBaseCoords);
 562        }
 563
 564        private static void SendStepStartedSegmentStats(int version, TutorialPath tutorialPath, int stepNumber, string s
 565        {
 0566            WebInterface.AnalyticsPayload.Property[] properties =
 567            {
 568                new ("version", version.ToString()),
 569                new ("path", tutorialPath.ToString()),
 570                new ("step number", stepNumber.ToString()),
 571                new ("step name", StepNameForStatsMessage(stepName)),
 572            };
 573
 0574            WebInterface.ReportAnalyticsEvent("tutorial step started", properties);
 0575        }
 576
 577        private static void SendStepCompletedSegmentStats(int version, TutorialPath tutorialPath, int stepNumber, string
 578        {
 0579            WebInterface.AnalyticsPayload.Property[] properties =
 580            {
 581                new ("version", version.ToString()),
 582                new ("path", tutorialPath.ToString()),
 583                new ("step number", stepNumber.ToString()),
 584                new ("step name", StepNameForStatsMessage(stepName)),
 585                new ("elapsed time", elapsedTime.ToString("0.00")),
 586            };
 587
 0588            WebInterface.ReportAnalyticsEvent("tutorial step completed", properties);
 0589        }
 590
 591        private void SendSkipTutorialSegmentStats(int version, string stepName)
 592        {
 0593            WebInterface.AnalyticsPayload.Property[] properties =
 594            {
 595                new ("version", version.ToString()),
 596                new ("path", currentPath.ToString()),
 597                new ("step number", currentStepNumber.ToString()),
 598                new ("step name", StepNameForStatsMessage(stepName)),
 599                new ("elapsed time", (Time.realtimeSinceStartup - elapsedTimeInCurrentStep).ToString("0.00")),
 600            };
 601
 0602            WebInterface.ReportAnalyticsEvent("tutorial skipped", properties);
 0603        }
 604
 605        private static string StepNameForStatsMessage(string stepName) =>
 0606            stepName.Replace("(Clone)", "").Replace("TutorialStep_", "");
 607
 608        internal IEnumerator EagleEyeCameraRotation(float rotationSpeed)
 609        {
 0610            while (true)
 611            {
 0612                configuration.eagleEyeCamera.transform.Rotate(Vector3.up * Time.deltaTime * rotationSpeed, Space.World);
 0613                yield return null;
 614            }
 615        }
 616
 617        private IEnumerator BlockPlayerCameraUntilBlendingIsFinished(bool hideUIs)
 618        {
 0619            if (hideUIs)
 0620                SetHudVisibility(false);
 621
 0622            CommonScriptableObjects.cameraBlocked.Set(true);
 623
 0624            yield return null;
 0625            yield return new WaitUntil(() => !CommonScriptableObjects.cameraIsBlending.Get());
 626
 0627            CommonScriptableObjects.cameraBlocked.Set(false);
 628
 0629            if (!hideUIs)
 0630                SetHudVisibility(true);
 631
 632            void SetHudVisibility(bool isVisible)
 633            {
 0634                hudController?.minimapHud?.SetVisibility(isVisible);
 0635                hudController?.profileHud?.SetVisibility(isVisible);
 0636            }
 0637        }
 638    }
 639}

Methods/Properties

i()
i(DCL.Tutorial.TutorialController)
hudController()
currentStepIndex()
currentStepIndex(System.Int32)
userAlreadyDidTheTutorial()
userAlreadyDidTheTutorial(System.Boolean)
TutorialController(DCL.DataStore_Common, DCL.DataStore_Settings, DCL.DataStore_ExploreV2)
CreateTutorialView()
SetConfiguration(DCL.Tutorial.TutorialSettings)
Dispose()
SetTutorialEnabled(System.String)
SetTutorialEnabledForUsersThatAlreadyDidTheTutorial(System.String)
SetupTutorial(System.String, System.String, System.Boolean)
SetTutorialDisabled()
StartTutorialFromStep()
ExecuteRespectiveTutorialStep()
ShowTeacher3DModel(System.Boolean)
SetTeacherPosition(UnityEngine.Vector3, System.Boolean)
PlayTeacherAnimation(DCL.Tutorial.TutorialTeacher/TeacherAnimation)
SetTeacherCanvasSortingOrder(System.Int32)
SkipTutorial(System.Boolean)
GoToSpecificStep(System.String)
SetNextSkippedSteps(System.Int32)
SetEagleEyeCameraActive(System.Boolean)
OnRenderingStateChanged(System.Boolean, System.Boolean)
ExecuteSteps()
IterateSteps()
RunStep()
NeedToSendStats()
SetUserTutorialStepAsCompleted(DCL.Tutorial.TutorialController/TutorialFinishStep)
MoveTeacher()
IsSettingsHUDInitialized_OnChange(System.Boolean, System.Boolean)
OnRestartTutorial()
IsPlayerInScene()
IsPlayerInsideGenesisPlaza()
SendStepStartedSegmentStats(System.Int32, DCL.Tutorial.TutorialController/TutorialPath, System.Int32, System.String)
SendStepCompletedSegmentStats(System.Int32, DCL.Tutorial.TutorialController/TutorialPath, System.Int32, System.String, System.Single)
SendSkipTutorialSegmentStats(System.Int32, System.String)
StepNameForStatsMessage(System.String)
EagleEyeCameraRotation()
BlockPlayerCameraUntilBlendingIsFinished()