< 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:260
Coverable lines:260
Total lines:638
Line coverage:0% (0 of 260)
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%72800%
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 (PlayerPrefsBridge.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);
 170
 0171            NotificationsController.disableWelcomeNotification = true;
 172
 0173            WebInterface.SetDelightedSurveyEnabled(false);
 174
 0175            if (!CommonScriptableObjects.rendererState.Get())
 0176                CommonScriptableObjects.rendererState.OnChange += OnRenderingStateChanged;
 177            else
 0178                OnRenderingStateChanged(true, false);
 179
 0180            OnTutorialEnabled?.Invoke();
 0181        }
 182
 183        /// <summary>
 184        /// Stop and disables the tutorial controller.
 185        /// </summary>
 186        public void SetTutorialDisabled()
 187        {
 0188            CommonScriptableObjects.featureKeyTriggersBlocked.Set(false);
 189
 0190            if (executeStepsCoroutine != null)
 191            {
 0192                CoroutineStarter.Stop(executeStepsCoroutine);
 0193                executeStepsCoroutine = null;
 194            }
 195
 0196            if (runningStep != null)
 197            {
 0198                Object.Destroy(runningStep.gameObject);
 0199                runningStep = null;
 200            }
 201
 0202            if (teacherMovementCoroutine != null)
 203            {
 0204                CoroutineStarter.Stop(teacherMovementCoroutine);
 0205                teacherMovementCoroutine = null;
 206            }
 207
 0208            tutorialReset = false;
 0209            commonDataStore.isTutorialRunning.Set(false);
 0210            tutorialView.tutorialMusicHandler.StopTutorialMusic();
 0211            ShowTeacher3DModel(false);
 0212            WebInterface.SetDelightedSurveyEnabled(true);
 213
 0214            if (Environment.i is { world: { } })
 0215                WebInterface.SendSceneExternalActionEvent(Environment.i.world.state.GetCurrentSceneNumber(), "tutorial",
 216
 0217            NotificationsController.disableWelcomeNotification = false;
 218
 0219            hudController?.settingsPanelHud?.SetTutorialButtonEnabled(true);
 220
 0221            CommonScriptableObjects.tutorialActive.Set(false);
 222
 0223            CommonScriptableObjects.rendererState.OnChange -= OnRenderingStateChanged;
 224
 0225            OnTutorialDisabled?.Invoke();
 0226        }
 227
 228        /// <summary>
 229        /// Starts to execute the tutorial from a specific step (It is needed to call SetTutorialEnabled() before).
 230        /// </summary>
 231        /// <param name="stepIndex">First step to be executed.</param>
 232        internal IEnumerator StartTutorialFromStep(int stepIndex)
 233        {
 0234            if (!commonDataStore.isTutorialRunning.Get())
 0235                yield break;
 236
 0237            if (runningStep != null)
 238            {
 0239                runningStep.OnStepFinished();
 0240                Object.Destroy(runningStep.gameObject);
 0241                runningStep = null;
 242            }
 243
 0244            yield return new WaitUntil(IsPlayerInScene);
 245
 0246            playerIsInGenesisPlaza = IsPlayerInsideGenesisPlaza();
 247
 0248            if (playerIsInGenesisPlaza)
 0249                tutorialView.tutorialMusicHandler.TryPlayingMusic();
 250
 0251            yield return ExecuteRespectiveTutorialStep(stepIndex);
 0252        }
 253
 254        private IEnumerator ExecuteRespectiveTutorialStep(int stepIndex)
 255        {
 0256            if (userAlreadyDidTheTutorial)
 0257                yield return ExecuteSteps(TutorialPath.FromUserThatAlreadyDidTheTutorial, stepIndex);
 0258            else if (tutorialReset)
 0259                yield return ExecuteSteps(TutorialPath.FromResetTutorial, stepIndex);
 0260            else if (playerIsInGenesisPlaza)
 0261                yield return ExecuteSteps(TutorialPath.FromGenesisPlaza, stepIndex);
 0262            else if (openedFromDeepLink)
 0263                yield return ExecuteSteps(TutorialPath.FromDeepLink, stepIndex);
 264            else
 0265                SetTutorialDisabled();
 0266        }
 267
 268        /// <summary>
 269        /// Shows the teacher that will be guiding along the tutorial.
 270        /// </summary>
 271        /// <param name="active">True for show the teacher.</param>
 272        public void ShowTeacher3DModel(bool active)
 273        {
 0274            if (configuration.teacherCamera != null)
 0275                configuration.teacherCamera.enabled = active;
 276
 0277            if (configuration.teacherRawImage != null)
 0278                configuration.teacherRawImage.gameObject.SetActive(active);
 0279        }
 280
 281        /// <summary>
 282        /// Move the tutorial teacher to a specific position.
 283        /// </summary>
 284        /// <param name="destinationPosition">Target position.</param>
 285        /// <param name="animated">True for apply a smooth movement.</param>
 286        public void SetTeacherPosition(Vector3 destinationPosition, bool animated = true)
 287        {
 0288            if (teacherMovementCoroutine != null)
 0289                CoroutineStarter.Stop(teacherMovementCoroutine);
 290
 0291            if (configuration.teacherRawImage != null)
 292            {
 0293                if (animated)
 0294                    teacherMovementCoroutine = CoroutineStarter.Start(MoveTeacher(destinationPosition));
 295                else
 0296                    configuration.teacherRawImage.rectTransform.position = new Vector3(destinationPosition.x, destinatio
 297            }
 0298        }
 299
 300        /// <summary>
 301        /// Plays a specific animation on the tutorial teacher.
 302        /// </summary>
 303        /// <param name="animation">Animation to apply.</param>
 304        public void PlayTeacherAnimation(TutorialTeacher.TeacherAnimation animation)
 305        {
 0306            if (configuration.teacher == null)
 0307                return;
 308
 0309            configuration.teacher.PlayAnimation(animation);
 0310        }
 311
 312        /// <summary>
 313        /// Set sort order for canvas containing teacher RawImage
 314        /// </summary>
 315        /// <param name="sortOrder"></param>
 316        public void SetTeacherCanvasSortingOrder(int sortOrder)
 317        {
 0318            if (configuration.teacherCanvas == null)
 0319                return;
 320
 0321            configuration.teacherCanvas.sortingOrder = sortOrder;
 0322        }
 323
 324        /// <summary>
 325        /// Finishes the current running step, skips all the next ones and completes the tutorial.
 326        /// </summary>
 327        public void SkipTutorial(bool ignoreStatsSending = false)
 328        {
 0329            if (!ignoreStatsSending && NeedToSendStats())
 0330                SendSkipTutorialSegmentStats(configuration.tutorialVersion, runningStep.name);
 331
 0332            int skipIndex = configuration.stepsOnGenesisPlaza.Count +
 333                            configuration.stepsFromDeepLink.Count +
 334                            configuration.stepsFromReset.Count +
 335                            configuration.stepsFromUserThatAlreadyDidTheTutorial.Count;
 336
 0337            CoroutineStarter.Start(StartTutorialFromStep(skipIndex));
 338
 0339            hudController?.taskbarHud?.SetVisibility(true);
 0340        }
 341
 342        /// <summary>
 343        /// Jump to a specific step.
 344        /// </summary>
 345        /// <param name="stepName">Step to jump.</param>
 346        public void GoToSpecificStep(string stepName)
 347        {
 348            int stepIndex;
 349
 0350            if (userAlreadyDidTheTutorial)
 0351                stepIndex = configuration.stepsFromUserThatAlreadyDidTheTutorial.FindIndex(x => x.name == stepName);
 0352            else if (tutorialReset)
 0353                stepIndex = configuration.stepsFromReset.FindIndex(x => x.name == stepName);
 0354            else if (playerIsInGenesisPlaza)
 0355                stepIndex = configuration.stepsOnGenesisPlaza.FindIndex(x => x.name == stepName);
 0356            else if (openedFromDeepLink)
 0357                stepIndex = configuration.stepsFromDeepLink.FindIndex(x => x.name == stepName);
 358            else
 0359                stepIndex = 0;
 360
 0361            nextStepsToSkip = 0;
 362
 0363            if (stepIndex >= 0)
 0364                CoroutineStarter.Start(StartTutorialFromStep(stepIndex));
 365            else
 0366                SkipTutorial(true);
 0367        }
 368
 369        /// <summary>
 370        /// Set the number of steps that will be skipped in the next iteration.
 371        /// </summary>
 372        /// <param name="skippedSteps">Number of steps to skip.</param>
 373        public void SetNextSkippedSteps(int skippedSteps) =>
 0374            nextStepsToSkip = skippedSteps;
 375
 376        /// <summary>
 377        /// Activate/deactivate the eagle eye camera.
 378        /// </summary>
 379        /// <param name="isActive">True for activate the eagle eye camera.</param>
 380        public void SetEagleEyeCameraActive(bool isActive)
 381        {
 0382            configuration.eagleEyeCamera.gameObject.SetActive(isActive);
 0383            CoroutineStarter.Start(BlockPlayerCameraUntilBlendingIsFinished(isActive));
 384
 0385            if (isActive)
 386            {
 0387                configuration.eagleEyeCamera.transform.position = configuration.eagleCamInitPosition;
 0388                configuration.eagleEyeCamera.transform.LookAt(configuration.eagleCamInitLookAtPoint);
 389
 0390                if (configuration.eagleCamRotationActived)
 0391                    eagleEyeRotationCoroutine = CoroutineStarter.Start(EagleEyeCameraRotation(configuration.eagleCamRota
 392            }
 0393            else if (eagleEyeRotationCoroutine != null)
 0394                CoroutineStarter.Stop(eagleEyeRotationCoroutine);
 0395        }
 396
 397        internal void OnRenderingStateChanged(bool renderingEnabled, bool prevState)
 398        {
 0399            if (!renderingEnabled)
 0400                return;
 401
 0402            CommonScriptableObjects.rendererState.OnChange -= OnRenderingStateChanged;
 403
 0404            currentStepIndex = configuration.debugRunTutorial ?  configuration.debugStartingStepIndex : 0;
 405
 0406            PlayTeacherAnimation(TutorialTeacher.TeacherAnimation.Reset);
 0407            executeStepsCoroutine = CoroutineStarter.Start(StartTutorialFromStep(currentStepIndex));
 0408        }
 409
 410        private IEnumerator ExecuteSteps(TutorialPath tutorialPath, int startingStepIndex)
 411        {
 0412            List<TutorialStep> steps = tutorialPath switch
 413                                       {
 0414                                           TutorialPath.FromGenesisPlaza => configuration.stepsOnGenesisPlaza,
 0415                                           TutorialPath.FromDeepLink => configuration.stepsFromDeepLink,
 0416                                           TutorialPath.FromResetTutorial => configuration.stepsFromReset,
 0417                                           TutorialPath.FromUserThatAlreadyDidTheTutorial => configuration.stepsFromUser
 0418                                           _ => new List<TutorialStep>(),
 419                                       };
 420
 0421            currentPath = tutorialPath;
 422
 0423            elapsedTimeInCurrentStep = 0f;
 424
 0425            yield return IterateSteps(tutorialPath, startingStepIndex, steps);
 426
 0427            if (!configuration.debugRunTutorial && tutorialPath != TutorialPath.FromUserThatAlreadyDidTheTutorial)
 0428                SetUserTutorialStepAsCompleted(TutorialFinishStep.NewTutorialFinished);
 429
 0430            runningStep = null;
 431
 0432            SetTutorialDisabled();
 0433        }
 434
 435        private IEnumerator IterateSteps(TutorialPath tutorialPath, int startingStepIndex, List<TutorialStep> steps)
 436        {
 0437            for (int stepId = startingStepIndex; stepId < steps.Count; stepId++)
 438            {
 0439                if (nextStepsToSkip > 0)
 440                {
 0441                    nextStepsToSkip--;
 0442                    continue;
 443                }
 444
 0445                TutorialStep stepPrefab = steps[stepId];
 446
 447                // TODO (Santi): This a TEMPORAL fix. It will be removed when we refactorize the tutorial system in orde
 0448                if (stepPrefab is TutorialStep_Tooltip_ExploreButton && !exploreV2DataStore.isInitialized.Get())
 449                    continue;
 450
 0451                yield return RunStep(tutorialPath, stepPrefab, stepId, steps);
 452
 0453                if (stepId < steps.Count - 1 && configuration.timeBetweenSteps > 0)
 0454                    yield return new WaitForSeconds(configuration.timeBetweenSteps);
 455            }
 0456        }
 457
 458        private IEnumerator RunStep(TutorialPath tutorialPath, TutorialStep stepPrefab, int stepId, List<TutorialStep> s
 459        {
 0460            runningStep = stepPrefab.letInstantiation ? Object.Instantiate(stepPrefab, tutorialView.transform).GetCompon
 461
 0462            runningStep.gameObject.name = runningStep.gameObject.name.Replace("(Clone)", "");
 0463            currentStepIndex = stepId;
 464
 0465            elapsedTimeInCurrentStep = Time.realtimeSinceStartup;
 0466            currentStepNumber = stepId + 1;
 467
 0468            if (NeedToSendStats())
 0469                SendStepStartedSegmentStats(configuration.tutorialVersion, tutorialPath, stepId + 1, runningStep.name);
 470
 0471            runningStep.OnStepStart();
 0472            yield return runningStep.OnStepExecute();
 473
 0474            PlayTeacherAnimation(animation: stepId < steps.Count - 1
 475                ? TutorialTeacher.TeacherAnimation.StepCompleted
 476                : TutorialTeacher.TeacherAnimation.QuickGoodbye);
 477
 0478            yield return runningStep.OnStepPlayHideAnimation();
 0479            runningStep.OnStepFinished();
 0480            elapsedTimeInCurrentStep = Time.realtimeSinceStartup - elapsedTimeInCurrentStep;
 481
 0482            if (NeedToSendStats() && tutorialPath != TutorialPath.FromUserThatAlreadyDidTheTutorial)
 0483                SendStepCompletedSegmentStats(configuration.tutorialVersion, tutorialPath, stepId + 1, runningStep.name,
 484
 0485            Object.Destroy(runningStep.gameObject);
 0486        }
 487
 488        private bool NeedToSendStats() =>
 0489            !configuration.debugRunTutorial && configuration.sendStats;
 490
 491        private static void SetUserTutorialStepAsCompleted(TutorialFinishStep finishStepType) =>
 0492            WebInterface.SaveUserTutorialStep(UserProfile.GetOwnUserProfile().tutorialStep | (int)finishStepType);
 493
 494        internal IEnumerator MoveTeacher(Vector3 toPosition)
 495        {
 0496            if (configuration.teacherRawImage == null)
 0497                yield break;
 498
 0499            var t = 0f;
 500
 0501            Vector3 fromPosition = configuration.teacherRawImage.rectTransform.position;
 502
 0503            while (Vector3.Distance(configuration.teacherRawImage.rectTransform.position, toPosition) > 0)
 504            {
 0505                t += configuration.teacherMovementSpeed * Time.deltaTime;
 506
 0507                configuration.teacherRawImage.rectTransform.position = t <= 1.0f
 508                    ? Vector3.Lerp(fromPosition, toPosition, configuration.teacherMovementCurve.Evaluate(t))
 509                    : toPosition;
 510
 0511                yield return null;
 512            }
 0513        }
 514
 515        private void IsSettingsHUDInitialized_OnChange(bool isInitialized, bool _)
 516        {
 0517            if (isInitialized && hudController is { settingsPanelHud: { } })
 518            {
 0519                hudController.settingsPanelHud.OnRestartTutorial -= OnRestartTutorial;
 0520                hudController.settingsPanelHud.OnRestartTutorial += OnRestartTutorial;
 521            }
 0522        }
 523
 524        private void OnRestartTutorial()
 525        {
 0526            SetTutorialDisabled();
 0527            tutorialReset = true;
 528
 0529            SetTutorialEnabled(JsonUtility.ToJson(new TutorialInitializationMessage
 530            {
 531                fromDeepLink = false.ToString(),
 532                enableNewTutorialCamera = false.ToString(),
 533            }));
 0534        }
 535
 536        private static bool IsPlayerInScene()
 537        {
 0538            IWorldState worldState = Environment.i.world.state;
 539
 0540            if (worldState == null || worldState.GetCurrentSceneNumber() == null)
 0541                return false;
 542
 0543            return true;
 544        }
 545
 546        private static bool IsPlayerInsideGenesisPlaza()
 547        {
 0548            if (Environment.i.world == null)
 0549                return false;
 550
 0551            IWorldState worldState = Environment.i.world.state;
 552
 0553            if (worldState == null || worldState.GetCurrentSceneNumber() == null)
 0554                return false;
 555
 0556            var genesisPlazaBaseCoords = new Vector2Int(-9, -9);
 557
 0558            IParcelScene currentScene = worldState.GetScene(worldState.GetCurrentSceneNumber());
 559
 0560            return currentScene != null && currentScene.IsInsideSceneBoundaries(genesisPlazaBaseCoords);
 561        }
 562
 563        private static void SendStepStartedSegmentStats(int version, TutorialPath tutorialPath, int stepNumber, string s
 564        {
 0565            WebInterface.AnalyticsPayload.Property[] properties =
 566            {
 567                new ("version", version.ToString()),
 568                new ("path", tutorialPath.ToString()),
 569                new ("step number", stepNumber.ToString()),
 570                new ("step name", StepNameForStatsMessage(stepName)),
 571            };
 572
 0573            WebInterface.ReportAnalyticsEvent("tutorial step started", properties);
 0574        }
 575
 576        private static void SendStepCompletedSegmentStats(int version, TutorialPath tutorialPath, int stepNumber, string
 577        {
 0578            WebInterface.AnalyticsPayload.Property[] properties =
 579            {
 580                new ("version", version.ToString()),
 581                new ("path", tutorialPath.ToString()),
 582                new ("step number", stepNumber.ToString()),
 583                new ("step name", StepNameForStatsMessage(stepName)),
 584                new ("elapsed time", elapsedTime.ToString("0.00")),
 585            };
 586
 0587            WebInterface.ReportAnalyticsEvent("tutorial step completed", properties);
 0588        }
 589
 590        private void SendSkipTutorialSegmentStats(int version, string stepName)
 591        {
 0592            WebInterface.AnalyticsPayload.Property[] properties =
 593            {
 594                new ("version", version.ToString()),
 595                new ("path", currentPath.ToString()),
 596                new ("step number", currentStepNumber.ToString()),
 597                new ("step name", StepNameForStatsMessage(stepName)),
 598                new ("elapsed time", (Time.realtimeSinceStartup - elapsedTimeInCurrentStep).ToString("0.00")),
 599            };
 600
 0601            WebInterface.ReportAnalyticsEvent("tutorial skipped", properties);
 0602        }
 603
 604        private static string StepNameForStatsMessage(string stepName) =>
 0605            stepName.Replace("(Clone)", "").Replace("TutorialStep_", "");
 606
 607        internal IEnumerator EagleEyeCameraRotation(float rotationSpeed)
 608        {
 0609            while (true)
 610            {
 0611                configuration.eagleEyeCamera.transform.Rotate(Vector3.up * Time.deltaTime * rotationSpeed, Space.World);
 0612                yield return null;
 613            }
 614        }
 615
 616        private IEnumerator BlockPlayerCameraUntilBlendingIsFinished(bool hideUIs)
 617        {
 0618            if (hideUIs)
 0619                SetHudVisibility(false);
 620
 0621            CommonScriptableObjects.cameraBlocked.Set(true);
 622
 0623            yield return null;
 0624            yield return new WaitUntil(() => !CommonScriptableObjects.cameraIsBlending.Get());
 625
 0626            CommonScriptableObjects.cameraBlocked.Set(false);
 627
 0628            if (!hideUIs)
 0629                SetHudVisibility(true);
 630
 631            void SetHudVisibility(bool isVisible)
 632            {
 0633                hudController?.minimapHud?.SetVisibility(isVisible);
 0634                hudController?.profileHud?.SetVisibility(isVisible);
 0635            }
 0636        }
 637    }
 638}

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()