< 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:258
Coverable lines:258
Total lines:635
Line coverage:0% (0 of 258)
Covered branches:0
Total branches:0
Covered methods:0
Total methods:42
Method coverage:0% (0 of 42)

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            if (!CommonScriptableObjects.rendererState.Get())
 0174                CommonScriptableObjects.rendererState.OnChange += OnRenderingStateChanged;
 175            else
 0176                OnRenderingStateChanged(true, false);
 177
 0178            OnTutorialEnabled?.Invoke();
 0179        }
 180
 181        /// <summary>
 182        /// Stop and disables the tutorial controller.
 183        /// </summary>
 184        public void SetTutorialDisabled()
 185        {
 0186            CommonScriptableObjects.featureKeyTriggersBlocked.Set(false);
 187
 0188            if (executeStepsCoroutine != null)
 189            {
 0190                CoroutineStarter.Stop(executeStepsCoroutine);
 0191                executeStepsCoroutine = null;
 192            }
 193
 0194            if (runningStep != null)
 195            {
 0196                Object.Destroy(runningStep.gameObject);
 0197                runningStep = null;
 198            }
 199
 0200            if (teacherMovementCoroutine != null)
 201            {
 0202                CoroutineStarter.Stop(teacherMovementCoroutine);
 0203                teacherMovementCoroutine = null;
 204            }
 205
 0206            tutorialReset = false;
 0207            commonDataStore.isTutorialRunning.Set(false);
 0208            tutorialView.tutorialMusicHandler.StopTutorialMusic();
 0209            ShowTeacher3DModel(false);
 210
 0211            if (Environment.i is { world: { } })
 0212                WebInterface.SendSceneExternalActionEvent(Environment.i.world.state.GetCurrentSceneNumber(), "tutorial",
 213
 0214            NotificationsController.disableWelcomeNotification = false;
 215
 0216            hudController?.settingsPanelHud?.SetTutorialButtonEnabled(true);
 217
 0218            CommonScriptableObjects.tutorialActive.Set(false);
 219
 0220            CommonScriptableObjects.rendererState.OnChange -= OnRenderingStateChanged;
 221
 0222            OnTutorialDisabled?.Invoke();
 0223        }
 224
 225        /// <summary>
 226        /// Starts to execute the tutorial from a specific step (It is needed to call SetTutorialEnabled() before).
 227        /// </summary>
 228        /// <param name="stepIndex">First step to be executed.</param>
 229        internal IEnumerator StartTutorialFromStep(int stepIndex)
 230        {
 0231            if (!commonDataStore.isTutorialRunning.Get())
 0232                yield break;
 233
 0234            if (runningStep != null)
 235            {
 0236                runningStep.OnStepFinished();
 0237                Object.Destroy(runningStep.gameObject);
 0238                runningStep = null;
 239            }
 240
 0241            yield return new WaitUntil(IsPlayerInScene);
 242
 0243            playerIsInGenesisPlaza = IsPlayerInsideGenesisPlaza();
 244
 0245            if (playerIsInGenesisPlaza)
 0246                tutorialView.tutorialMusicHandler.TryPlayingMusic();
 247
 0248            yield return ExecuteRespectiveTutorialStep(stepIndex);
 0249        }
 250
 251        private IEnumerator ExecuteRespectiveTutorialStep(int stepIndex)
 252        {
 0253            if (userAlreadyDidTheTutorial)
 0254                yield return ExecuteSteps(TutorialPath.FromUserThatAlreadyDidTheTutorial, stepIndex);
 0255            else if (tutorialReset)
 0256                yield return ExecuteSteps(TutorialPath.FromResetTutorial, stepIndex);
 0257            else if (playerIsInGenesisPlaza)
 0258                yield return ExecuteSteps(TutorialPath.FromGenesisPlaza, stepIndex);
 0259            else if (openedFromDeepLink)
 0260                yield return ExecuteSteps(TutorialPath.FromDeepLink, stepIndex);
 261            else
 0262                SetTutorialDisabled();
 0263        }
 264
 265        /// <summary>
 266        /// Shows the teacher that will be guiding along the tutorial.
 267        /// </summary>
 268        /// <param name="active">True for show the teacher.</param>
 269        public void ShowTeacher3DModel(bool active)
 270        {
 0271            if (configuration.teacherCamera != null)
 0272                configuration.teacherCamera.enabled = active;
 273
 0274            if (configuration.teacherRawImage != null)
 0275                configuration.teacherRawImage.gameObject.SetActive(active);
 0276        }
 277
 278        /// <summary>
 279        /// Move the tutorial teacher to a specific position.
 280        /// </summary>
 281        /// <param name="destinationPosition">Target position.</param>
 282        /// <param name="animated">True for apply a smooth movement.</param>
 283        public void SetTeacherPosition(Vector3 destinationPosition, bool animated = true)
 284        {
 0285            if (teacherMovementCoroutine != null)
 0286                CoroutineStarter.Stop(teacherMovementCoroutine);
 287
 0288            if (configuration.teacherRawImage != null)
 289            {
 0290                if (animated)
 0291                    teacherMovementCoroutine = CoroutineStarter.Start(MoveTeacher(destinationPosition));
 292                else
 0293                    configuration.teacherRawImage.rectTransform.position = new Vector3(destinationPosition.x, destinatio
 294            }
 0295        }
 296
 297        /// <summary>
 298        /// Plays a specific animation on the tutorial teacher.
 299        /// </summary>
 300        /// <param name="animation">Animation to apply.</param>
 301        public void PlayTeacherAnimation(TutorialTeacher.TeacherAnimation animation)
 302        {
 0303            if (configuration.teacher == null)
 0304                return;
 305
 0306            configuration.teacher.PlayAnimation(animation);
 0307        }
 308
 309        /// <summary>
 310        /// Set sort order for canvas containing teacher RawImage
 311        /// </summary>
 312        /// <param name="sortOrder"></param>
 313        public void SetTeacherCanvasSortingOrder(int sortOrder)
 314        {
 0315            if (configuration.teacherCanvas == null)
 0316                return;
 317
 0318            configuration.teacherCanvas.sortingOrder = sortOrder;
 0319        }
 320
 321        /// <summary>
 322        /// Finishes the current running step, skips all the next ones and completes the tutorial.
 323        /// </summary>
 324        public void SkipTutorial(bool ignoreStatsSending = false)
 325        {
 0326            if (!ignoreStatsSending && NeedToSendStats())
 0327                SendSkipTutorialSegmentStats(configuration.tutorialVersion, runningStep.name);
 328
 0329            int skipIndex = configuration.stepsOnGenesisPlaza.Count +
 330                            configuration.stepsFromDeepLink.Count +
 331                            configuration.stepsFromReset.Count +
 332                            configuration.stepsFromUserThatAlreadyDidTheTutorial.Count;
 333
 0334            CoroutineStarter.Start(StartTutorialFromStep(skipIndex));
 335
 0336            hudController?.taskbarHud?.SetVisibility(true);
 0337        }
 338
 339        /// <summary>
 340        /// Jump to a specific step.
 341        /// </summary>
 342        /// <param name="stepName">Step to jump.</param>
 343        public void GoToSpecificStep(string stepName)
 344        {
 345            int stepIndex;
 346
 0347            if (userAlreadyDidTheTutorial)
 0348                stepIndex = configuration.stepsFromUserThatAlreadyDidTheTutorial.FindIndex(x => x.name == stepName);
 0349            else if (tutorialReset)
 0350                stepIndex = configuration.stepsFromReset.FindIndex(x => x.name == stepName);
 0351            else if (playerIsInGenesisPlaza)
 0352                stepIndex = configuration.stepsOnGenesisPlaza.FindIndex(x => x.name == stepName);
 0353            else if (openedFromDeepLink)
 0354                stepIndex = configuration.stepsFromDeepLink.FindIndex(x => x.name == stepName);
 355            else
 0356                stepIndex = 0;
 357
 0358            nextStepsToSkip = 0;
 359
 0360            if (stepIndex >= 0)
 0361                CoroutineStarter.Start(StartTutorialFromStep(stepIndex));
 362            else
 0363                SkipTutorial(true);
 0364        }
 365
 366        /// <summary>
 367        /// Set the number of steps that will be skipped in the next iteration.
 368        /// </summary>
 369        /// <param name="skippedSteps">Number of steps to skip.</param>
 370        public void SetNextSkippedSteps(int skippedSteps) =>
 0371            nextStepsToSkip = skippedSteps;
 372
 373        /// <summary>
 374        /// Activate/deactivate the eagle eye camera.
 375        /// </summary>
 376        /// <param name="isActive">True for activate the eagle eye camera.</param>
 377        public void SetEagleEyeCameraActive(bool isActive)
 378        {
 0379            configuration.eagleEyeCamera.gameObject.SetActive(isActive);
 0380            CoroutineStarter.Start(BlockPlayerCameraUntilBlendingIsFinished(isActive));
 381
 0382            if (isActive)
 383            {
 0384                configuration.eagleEyeCamera.transform.position = configuration.eagleCamInitPosition;
 0385                configuration.eagleEyeCamera.transform.LookAt(configuration.eagleCamInitLookAtPoint);
 386
 0387                if (configuration.eagleCamRotationActived)
 0388                    eagleEyeRotationCoroutine = CoroutineStarter.Start(EagleEyeCameraRotation(configuration.eagleCamRota
 389            }
 0390            else if (eagleEyeRotationCoroutine != null)
 0391                CoroutineStarter.Stop(eagleEyeRotationCoroutine);
 0392        }
 393
 394        internal void OnRenderingStateChanged(bool renderingEnabled, bool prevState)
 395        {
 0396            if (!renderingEnabled)
 0397                return;
 398
 0399            CommonScriptableObjects.rendererState.OnChange -= OnRenderingStateChanged;
 400
 0401            currentStepIndex = configuration.debugRunTutorial ?  configuration.debugStartingStepIndex : 0;
 402
 0403            PlayTeacherAnimation(TutorialTeacher.TeacherAnimation.Reset);
 0404            executeStepsCoroutine = CoroutineStarter.Start(StartTutorialFromStep(currentStepIndex));
 0405        }
 406
 407        private IEnumerator ExecuteSteps(TutorialPath tutorialPath, int startingStepIndex)
 408        {
 0409            List<TutorialStep> steps = tutorialPath switch
 410                                       {
 0411                                           TutorialPath.FromGenesisPlaza => configuration.stepsOnGenesisPlaza,
 0412                                           TutorialPath.FromDeepLink => configuration.stepsFromDeepLink,
 0413                                           TutorialPath.FromResetTutorial => configuration.stepsFromReset,
 0414                                           TutorialPath.FromUserThatAlreadyDidTheTutorial => configuration.stepsFromUser
 0415                                           _ => new List<TutorialStep>(),
 416                                       };
 417
 0418            currentPath = tutorialPath;
 419
 0420            elapsedTimeInCurrentStep = 0f;
 421
 0422            yield return IterateSteps(tutorialPath, startingStepIndex, steps);
 423
 0424            if (!configuration.debugRunTutorial && tutorialPath != TutorialPath.FromUserThatAlreadyDidTheTutorial)
 0425                SetUserTutorialStepAsCompleted(TutorialFinishStep.NewTutorialFinished);
 426
 0427            runningStep = null;
 428
 0429            SetTutorialDisabled();
 0430        }
 431
 432        private IEnumerator IterateSteps(TutorialPath tutorialPath, int startingStepIndex, List<TutorialStep> steps)
 433        {
 0434            for (int stepId = startingStepIndex; stepId < steps.Count; stepId++)
 435            {
 0436                if (nextStepsToSkip > 0)
 437                {
 0438                    nextStepsToSkip--;
 0439                    continue;
 440                }
 441
 0442                TutorialStep stepPrefab = steps[stepId];
 443
 444                // TODO (Santi): This a TEMPORAL fix. It will be removed when we refactorize the tutorial system in orde
 0445                if (stepPrefab is TutorialStep_Tooltip_ExploreButton && !exploreV2DataStore.isInitialized.Get())
 446                    continue;
 447
 0448                yield return RunStep(tutorialPath, stepPrefab, stepId, steps);
 449
 0450                if (stepId < steps.Count - 1 && configuration.timeBetweenSteps > 0)
 0451                    yield return new WaitForSeconds(configuration.timeBetweenSteps);
 452            }
 0453        }
 454
 455        private IEnumerator RunStep(TutorialPath tutorialPath, TutorialStep stepPrefab, int stepId, List<TutorialStep> s
 456        {
 0457            runningStep = stepPrefab.letInstantiation ? Object.Instantiate(stepPrefab, tutorialView.transform).GetCompon
 458
 0459            runningStep.gameObject.name = runningStep.gameObject.name.Replace("(Clone)", "");
 0460            currentStepIndex = stepId;
 461
 0462            elapsedTimeInCurrentStep = Time.realtimeSinceStartup;
 0463            currentStepNumber = stepId + 1;
 464
 0465            if (NeedToSendStats())
 0466                SendStepStartedSegmentStats(configuration.tutorialVersion, tutorialPath, stepId + 1, runningStep.name);
 467
 0468            runningStep.OnStepStart();
 0469            yield return runningStep.OnStepExecute();
 470
 0471            PlayTeacherAnimation(animation: stepId < steps.Count - 1
 472                ? TutorialTeacher.TeacherAnimation.StepCompleted
 473                : TutorialTeacher.TeacherAnimation.QuickGoodbye);
 474
 0475            yield return runningStep.OnStepPlayHideAnimation();
 0476            runningStep.OnStepFinished();
 0477            elapsedTimeInCurrentStep = Time.realtimeSinceStartup - elapsedTimeInCurrentStep;
 478
 0479            if (NeedToSendStats() && tutorialPath != TutorialPath.FromUserThatAlreadyDidTheTutorial)
 0480                SendStepCompletedSegmentStats(configuration.tutorialVersion, tutorialPath, stepId + 1, runningStep.name,
 481
 0482            Object.Destroy(runningStep.gameObject);
 0483        }
 484
 485        private bool NeedToSendStats() =>
 0486            !configuration.debugRunTutorial && configuration.sendStats;
 487
 488        private static void SetUserTutorialStepAsCompleted(TutorialFinishStep finishStepType) =>
 0489            WebInterface.SaveUserTutorialStep(UserProfile.GetOwnUserProfile().tutorialStep | (int)finishStepType);
 490
 491        internal IEnumerator MoveTeacher(Vector3 toPosition)
 492        {
 0493            if (configuration.teacherRawImage == null)
 0494                yield break;
 495
 0496            var t = 0f;
 497
 0498            Vector3 fromPosition = configuration.teacherRawImage.rectTransform.position;
 499
 0500            while (Vector3.Distance(configuration.teacherRawImage.rectTransform.position, toPosition) > 0)
 501            {
 0502                t += configuration.teacherMovementSpeed * Time.deltaTime;
 503
 0504                configuration.teacherRawImage.rectTransform.position = t <= 1.0f
 505                    ? Vector3.Lerp(fromPosition, toPosition, configuration.teacherMovementCurve.Evaluate(t))
 506                    : toPosition;
 507
 0508                yield return null;
 509            }
 0510        }
 511
 512        private void IsSettingsHUDInitialized_OnChange(bool isInitialized, bool _)
 513        {
 0514            if (isInitialized && hudController is { settingsPanelHud: { } })
 515            {
 0516                hudController.settingsPanelHud.OnRestartTutorial -= OnRestartTutorial;
 0517                hudController.settingsPanelHud.OnRestartTutorial += OnRestartTutorial;
 518            }
 0519        }
 520
 521        private void OnRestartTutorial()
 522        {
 0523            SetTutorialDisabled();
 0524            tutorialReset = true;
 525
 0526            SetTutorialEnabled(JsonUtility.ToJson(new TutorialInitializationMessage
 527            {
 528                fromDeepLink = false.ToString(),
 529                enableNewTutorialCamera = false.ToString(),
 530            }));
 0531        }
 532
 533        private static bool IsPlayerInScene()
 534        {
 0535            IWorldState worldState = Environment.i.world.state;
 536
 0537            if (worldState == null || worldState.GetCurrentSceneNumber() == null)
 0538                return false;
 539
 0540            return true;
 541        }
 542
 543        private static bool IsPlayerInsideGenesisPlaza()
 544        {
 0545            if (Environment.i.world == null)
 0546                return false;
 547
 0548            IWorldState worldState = Environment.i.world.state;
 549
 0550            if (worldState == null || worldState.GetCurrentSceneNumber() == null)
 0551                return false;
 552
 0553            var genesisPlazaBaseCoords = new Vector2Int(-9, -9);
 554
 0555            IParcelScene currentScene = worldState.GetScene(worldState.GetCurrentSceneNumber());
 556
 0557            return currentScene != null && currentScene.IsInsideSceneBoundaries(genesisPlazaBaseCoords);
 558        }
 559
 560        private static void SendStepStartedSegmentStats(int version, TutorialPath tutorialPath, int stepNumber, string s
 561        {
 0562            WebInterface.AnalyticsPayload.Property[] properties =
 563            {
 564                new ("version", version.ToString()),
 565                new ("path", tutorialPath.ToString()),
 566                new ("step number", stepNumber.ToString()),
 567                new ("step name", StepNameForStatsMessage(stepName)),
 568            };
 569
 0570            WebInterface.ReportAnalyticsEvent("tutorial step started", properties);
 0571        }
 572
 573        private static void SendStepCompletedSegmentStats(int version, TutorialPath tutorialPath, int stepNumber, string
 574        {
 0575            WebInterface.AnalyticsPayload.Property[] properties =
 576            {
 577                new ("version", version.ToString()),
 578                new ("path", tutorialPath.ToString()),
 579                new ("step number", stepNumber.ToString()),
 580                new ("step name", StepNameForStatsMessage(stepName)),
 581                new ("elapsed time", elapsedTime.ToString("0.00")),
 582            };
 583
 0584            WebInterface.ReportAnalyticsEvent("tutorial step completed", properties);
 0585        }
 586
 587        private void SendSkipTutorialSegmentStats(int version, string stepName)
 588        {
 0589            WebInterface.AnalyticsPayload.Property[] properties =
 590            {
 591                new ("version", version.ToString()),
 592                new ("path", currentPath.ToString()),
 593                new ("step number", currentStepNumber.ToString()),
 594                new ("step name", StepNameForStatsMessage(stepName)),
 595                new ("elapsed time", (Time.realtimeSinceStartup - elapsedTimeInCurrentStep).ToString("0.00")),
 596            };
 597
 0598            WebInterface.ReportAnalyticsEvent("tutorial skipped", properties);
 0599        }
 600
 601        private static string StepNameForStatsMessage(string stepName) =>
 0602            stepName.Replace("(Clone)", "").Replace("TutorialStep_", "");
 603
 604        internal IEnumerator EagleEyeCameraRotation(float rotationSpeed)
 605        {
 0606            while (true)
 607            {
 0608                configuration.eagleEyeCamera.transform.Rotate(Vector3.up * Time.deltaTime * rotationSpeed, Space.World);
 0609                yield return null;
 610            }
 611        }
 612
 613        private IEnumerator BlockPlayerCameraUntilBlendingIsFinished(bool hideUIs)
 614        {
 0615            if (hideUIs)
 0616                SetHudVisibility(false);
 617
 0618            CommonScriptableObjects.cameraBlocked.Set(true);
 619
 0620            yield return null;
 0621            yield return new WaitUntil(() => !CommonScriptableObjects.cameraIsBlending.Get());
 622
 0623            CommonScriptableObjects.cameraBlocked.Set(false);
 624
 0625            if (!hideUIs)
 0626                SetHudVisibility(true);
 627
 628            void SetHudVisibility(bool isVisible)
 629            {
 0630                hudController?.minimapHud?.SetVisibility(isVisible);
 0631                hudController?.profileHud?.SetVisibility(isVisible);
 0632            }
 0633        }
 634    }
 635}

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