< Summary

Class:DCL.Controllers.ParcelScene
Assembly:DCL.Runtime
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/ParcelScene.cs
Covered lines:241
Uncovered lines:64
Coverable lines:305
Total lines:678
Line coverage:79% (241 of 305)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ParcelScene()0%110100%
Awake()0%110100%
OnDestroy()0%3.143075%
OnDisable()0%220100%
Update()0%330100%
SetData(...)0%220100%
SetupPositionAndParcels()0%220100%
OnWorldReposition(...)0%110100%
SetUpdateData(...)0%2100%
InitializeDebugPlane()0%440100%
RemoveDebugPlane()0%6200%
Cleanup(...)0%7.017095.24%
ToString()0%12300%
GetSceneName()0%6200%
GetParcels()0%110100%
IsInsideSceneBoundaries(...)0%4.054085.71%
IsInsideSceneBoundaries(...)0%4.254075%
IsInsideSceneBoundaries(...)0%9.599080.65%
IsInsideSceneOuterBoundaries(...)0%3.043083.33%
IsInsideSceneOuterBoundaries(...)0%2.062075%
OnDrawGizmosSelected()0%12300%
GetEntityById(...)0%2100%
GetSceneTransform()0%110100%
CreateEntity(...)0%44095%
OnEntityShapeUpdated(...)0%110100%
RemoveEntity(...)0%4.024090%
CleanUpEntityRecursively(...)0%550100%
RemoveAllEntities(...)0%770100%
RemoveAllEntitiesImmediate()0%110100%
SetEntityParent(...)0%15.8215084.62%
SendMetricsEvent()0%220100%
GetEntityById(...)0%64050%
GetStateString()0%9.498071.43%
RefreshLoadingState()0%2.032080%
GetWaitingComponentsDebugInfo()0%6200%
GetSceneDebugInfo()0%2100%
CalculateSceneLoadingState()0%4.134080%
IsInitMessageDone()0%220100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/ParcelScene.cs

#LineLine coverage
 1using DCL.Configuration;
 2using DCL.Helpers;
 3using DCL.Models;
 4using DCL.Controllers.ParcelSceneDebug;
 5using System.Collections.Generic;
 6using DCL.CRDT;
 7using DCL.Interface;
 8using UnityEngine;
 9using UnityEngine.Assertions;
 10
 11namespace DCL.Controllers
 12{
 13    public class ParcelScene : MonoBehaviour, IParcelScene
 14    {
 15        [Header("Debug")]
 16        [SerializeField]
 38817        private bool renderOuterBoundsGizmo = true;
 18
 383719        public Dictionary<long, IDCLEntity> entities { get; private set; } = new Dictionary<long, IDCLEntity>();
 594520        public IECSComponentsManagerLegacy componentsManagerLegacy { get; private set; }
 960421        public LoadParcelScenesMessage.UnityParcelScene sceneData { get; protected set; }
 22
 38823        public HashSet<Vector2Int> parcels = new HashSet<Vector2Int>();
 542524        public ISceneMetricsCounter metricsCounter { get; set; }
 25        public event System.Action<IDCLEntity> OnEntityAdded;
 26        public event System.Action<IDCLEntity> OnEntityRemoved;
 27        public event System.Action<LoadParcelScenesMessage.UnityParcelScene> OnSetData;
 28        public event System.Action<float> OnLoadingStateUpdated;
 29
 176330        public ContentProvider contentProvider { get; set; }
 31
 72932        public bool isTestScene { get; set; } = false;
 354133        public bool isPersistent { get; set; } = false;
 36534        public bool isPortableExperience { get; set; } = false;
 35
 108536        public float loadingProgress { get; private set; }
 37
 38        [System.NonSerialized]
 39        public string sceneName;
 40
 41        [System.NonSerialized]
 38842        public bool unloadWithDistance = true;
 43
 44        SceneDebugPlane sceneDebugPlane = null;
 45
 46        public SceneLifecycleHandler sceneLifecycleHandler;
 47
 71348        public ICRDTExecutor crdtExecutor { get; set; }
 49
 61950        public bool isReleased { get; private set; }
 51
 52        private Bounds outerBounds = new Bounds();
 53
 54        public void Awake()
 55        {
 38856            CommonScriptableObjects.worldOffset.OnChange += OnWorldReposition;
 38857            componentsManagerLegacy = new ECSComponentsManagerLegacy(this);
 38858            sceneLifecycleHandler = new SceneLifecycleHandler(this);
 38859            metricsCounter = new SceneMetricsCounter(DataStore.i.sceneWorldObjects);
 38860        }
 61
 62        private void OnDestroy()
 63        {
 38864            CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition;
 38865            metricsCounter?.Dispose();
 38866            crdtExecutor?.Dispose();
 067        }
 68
 77669        void OnDisable() { metricsCounter?.Disable(); }
 70
 71        private void Update()
 72        {
 3346573            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY
 74                && CommonScriptableObjects.rendererState.Get())
 3294375                SendMetricsEvent();
 3346576        }
 77
 73378        protected virtual string prettyName => sceneData.basePosition.ToString();
 79
 80        public virtual void SetData(LoadParcelScenesMessage.UnityParcelScene data)
 81        {
 38182            Assert.IsTrue( data.sceneNumber > 0, "Scene must have a valid scene number!" );
 83
 38184            this.sceneData = data;
 85
 38186            contentProvider = new ContentProvider();
 38187            contentProvider.baseUrl = data.baseUrl;
 38188            contentProvider.contents = data.contents;
 38189            contentProvider.BakeHashes();
 90
 38191            SetupPositionAndParcels();
 92
 38193            DataStore.i.sceneWorldObjects.AddScene(sceneData.sceneNumber);
 94
 38195            metricsCounter.Configure(sceneData.sceneNumber, sceneData.basePosition, sceneData.parcels.Length);
 38196            metricsCounter.Enable();
 97
 38198            OnSetData?.Invoke(data);
 38199        }
 100
 101        void SetupPositionAndParcels()
 102        {
 381103            gameObject.transform.position = PositionUtils.WorldToUnityPosition(Utils.GridToWorldPosition(sceneData.baseP
 104
 381105            parcels.Clear();
 106
 107            // The scene's gameobject position should already be in 'unityposition'
 381108            Vector3 baseParcelWorldPos = gameObject.transform.position;
 109
 381110            outerBounds.SetMinMax(new Vector3(baseParcelWorldPos.x, 0f, baseParcelWorldPos.z),
 111                new Vector3(baseParcelWorldPos.x + ParcelSettings.PARCEL_SIZE, 0f, baseParcelWorldPos.z + ParcelSettings
 112
 1548113            for (int i = 0; i < sceneData.parcels.Length; i++)
 114            {
 115                // 1. Update outer bounds with parcel's size
 393116                var parcel = sceneData.parcels[i];
 117
 393118                Vector3 parcelWorldPos = PositionUtils.WorldToUnityPosition(Utils.GridToWorldPosition(parcel.x, parcel.y
 393119                outerBounds.Encapsulate(new Vector3(parcelWorldPos.x, 0, parcelWorldPos.z));
 393120                outerBounds.Encapsulate(new Vector3(parcelWorldPos.x + ParcelSettings.PARCEL_SIZE, 0, parcelWorldPos.z +
 121
 122                // 2. add parcel to collection
 393123                parcels.Add(parcel);
 124            }
 125
 126            // Apply outer bounds extra threshold
 381127            outerBounds.SetMinMax(new Vector3(outerBounds.min.x - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD, 0f, outerB
 128                new Vector3(outerBounds.max.x + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD, 0f, outerBounds.max.z + Parc
 381129        }
 130
 131        void OnWorldReposition(Vector3 current, Vector3 previous)
 132        {
 2133            Vector3 currentSceneWorldPos = Utils.GridToWorldPosition(sceneData.basePosition.x, sceneData.basePosition.y)
 2134            Vector3 oldSceneUnityPos = gameObject.transform.position;
 2135            Vector3 newSceneUnityPos = PositionUtils.WorldToUnityPosition(currentSceneWorldPos);
 136
 2137            gameObject.transform.position = newSceneUnityPos;
 2138            outerBounds.center += newSceneUnityPos - oldSceneUnityPos;
 2139        }
 140
 141        public virtual void SetUpdateData(LoadParcelScenesMessage.UnityParcelScene data)
 142        {
 0143            contentProvider = new ContentProvider();
 0144            contentProvider.baseUrl = data.baseUrl;
 0145            contentProvider.contents = data.contents;
 0146            contentProvider.BakeHashes();
 0147        }
 148
 149        public void InitializeDebugPlane()
 150        {
 265151            if (EnvironmentSettings.DEBUG && sceneData.parcels != null && sceneDebugPlane == null)
 152            {
 265153                sceneDebugPlane = new SceneDebugPlane(sceneData, gameObject.transform);
 154            }
 265155        }
 156
 157        public void RemoveDebugPlane()
 158        {
 0159            if (sceneDebugPlane != null)
 160            {
 0161                sceneDebugPlane.Dispose();
 0162                sceneDebugPlane = null;
 163            }
 0164        }
 165
 166        public void Cleanup(bool immediate)
 167        {
 308168            if (isReleased || gameObject == null)
 0169                return;
 170
 308171            if (sceneDebugPlane != null)
 172            {
 265173                sceneDebugPlane.Dispose();
 265174                sceneDebugPlane = null;
 175            }
 176
 308177            componentsManagerLegacy.DisposeAllSceneComponents();
 178
 308179            if (crdtExecutor != null)
 180            {
 3181                crdtExecutor.Dispose();
 3182                crdtExecutor = null;
 183            }
 184
 308185            if (immediate) //!CommonScriptableObjects.rendererState.Get())
 186            {
 283187                RemoveAllEntitiesImmediate();
 283188                PoolManager.i.Cleanup(true, true);
 283189                DataStore.i.sceneWorldObjects.RemoveScene(sceneData.sceneNumber);
 190            }
 191            else
 192            {
 25193                if (entities.Count > 0)
 194                {
 5195                    this.gameObject.transform.position = EnvironmentSettings.MORDOR;
 5196                    this.gameObject.SetActive(false);
 197
 5198                    RemoveAllEntities();
 199                }
 200                else
 201                {
 20202                    Destroy(this.gameObject);
 20203                    DataStore.i.sceneWorldObjects.RemoveScene(sceneData.sceneNumber);
 204
 205                }
 206            }
 207
 308208            isReleased = true;
 308209        }
 210
 0211        public override string ToString() { return "Parcel Scene: " + base.ToString() + "\n" + sceneData; }
 212
 213        public string GetSceneName()
 214        {
 0215            return string.IsNullOrEmpty(sceneName) ? "Unnamed" : sceneName;
 216        }
 217
 666218        public HashSet<Vector2Int> GetParcels() => parcels;
 219        public bool IsInsideSceneBoundaries(Bounds objectBounds)
 220        {
 75221            if (isPersistent)
 0222                return true;
 223
 75224            if (!IsInsideSceneBoundaries(objectBounds.min + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 50225                return false;
 25226            if (!IsInsideSceneBoundaries(objectBounds.max + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 1227                return false;
 228
 24229            return true;
 230        }
 231
 232        public virtual bool IsInsideSceneBoundaries(Vector2Int gridPosition, float height = 0f)
 233        {
 133234            if (isPersistent)
 106235                return true;
 236
 27237            if (parcels.Count == 0)
 0238                return false;
 239
 27240            float heightLimit = metricsCounter.maxCount.sceneHeight;
 241
 27242            if (height > heightLimit)
 0243                return false;
 244
 27245            return parcels.Contains(gridPosition);
 246        }
 247
 248        public virtual bool IsInsideSceneBoundaries(Vector3 worldPosition, float height = 0f)
 249        {
 136250            if (isPersistent)
 0251                return true;
 252
 136253            if (parcels.Count == 0)
 0254                return false;
 255
 136256            float heightLimit = metricsCounter.maxCount.sceneHeight;
 136257            if (height > heightLimit)
 4258                return false;
 259
 132260            int noThresholdZCoordinate = Mathf.FloorToInt(worldPosition.z / ParcelSettings.PARCEL_SIZE);
 132261            int noThresholdXCoordinate = Mathf.FloorToInt(worldPosition.x / ParcelSettings.PARCEL_SIZE);
 262
 263            // We check the target world position
 132264            Vector2Int targetCoordinate = new Vector2Int(noThresholdXCoordinate, noThresholdZCoordinate);
 132265            if (parcels.Contains(targetCoordinate))
 67266                return true;
 267
 268            // We need to check using a threshold from the target point, in order to cover correctly the parcel "border/
 65269            Vector2Int coordinateMin = new Vector2Int();
 65270            coordinateMin.x = Mathf.FloorToInt((worldPosition.x - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 65271            coordinateMin.y = Mathf.FloorToInt((worldPosition.z - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 272
 65273            Vector2Int coordinateMax = new Vector2Int();
 65274            coordinateMax.x = Mathf.FloorToInt((worldPosition.x + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 65275            coordinateMax.y = Mathf.FloorToInt((worldPosition.z + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 276
 277            // We check the east/north-threshold position
 65278            targetCoordinate.Set(coordinateMax.x, coordinateMax.y);
 65279            if (parcels.Contains(targetCoordinate))
 0280                return true;
 281
 282            // We check the east/south-threshold position
 65283            targetCoordinate.Set(coordinateMax.x, coordinateMin.y);
 65284            if (parcels.Contains(targetCoordinate))
 0285                return true;
 286
 287            // We check the west/north-threshold position
 65288            targetCoordinate.Set(coordinateMin.x, coordinateMax.y);
 65289            if (parcels.Contains(targetCoordinate))
 0290                return true;
 291
 292            // We check the west/south-threshold position
 65293            targetCoordinate.Set(coordinateMin.x, coordinateMin.y);
 65294            if (parcels.Contains(targetCoordinate))
 0295                return true;
 296
 65297            return false;
 298        }
 299
 300        public bool IsInsideSceneOuterBoundaries(Bounds objectBounds)
 301        {
 148302            if (isPersistent)
 0303                return true;
 304
 148305            Vector3 objectBoundsMin = new Vector3(objectBounds.min.x, 0f, objectBounds.min.z);
 148306            Vector3 objectBoundsMax = new Vector3(objectBounds.max.x, 0f, objectBounds.max.z);
 148307            bool isInsideOuterBoundaries = outerBounds.Contains(objectBoundsMin) && outerBounds.Contains(objectBoundsMax
 308
 85309            return isInsideOuterBoundaries;
 310        }
 311
 312        public bool IsInsideSceneOuterBoundaries(Vector3 objectUnityPosition)
 313        {
 131314            if (isPersistent)
 0315                return true;
 316
 131317            objectUnityPosition.y = 0f;
 131318            return outerBounds.Contains(objectUnityPosition);
 319        }
 320
 321        private void OnDrawGizmosSelected()
 322        {
 0323            if(!renderOuterBoundsGizmo) return;
 324
 0325            Gizmos.color = new Color(Color.yellow.r, Color.yellow.g, Color.yellow.b, 0.5f);
 0326            Gizmos.DrawCube(outerBounds.center, outerBounds.size + Vector3.up);
 327
 0328            Gizmos.color = new Color(Color.green.r, Color.green.g, Color.green.b, 0.5f);
 0329            Bounds  parcelBounds = new Bounds();
 0330            foreach (Vector2Int parcel in parcels)
 331            {
 0332                Vector3 parcelSceneUnityPos = PositionUtils.WorldToUnityPosition(Utils.GridToWorldPosition(parcel.x, par
 0333                parcelBounds.center = parcelSceneUnityPos + new Vector3(8f, 0f, 8f);
 0334                parcelBounds.size = new Vector3(16f, 0.1f, 16f);
 0335                Gizmos.DrawCube(parcelBounds.center, parcelBounds.size);
 336            }
 0337        }
 338
 0339        public IDCLEntity GetEntityById(string entityId) { throw new System.NotImplementedException(); }
 340
 54341        public Transform GetSceneTransform() { return transform; }
 342
 343        public IDCLEntity CreateEntity(long id)
 344        {
 314345            if (entities.ContainsKey(id))
 346            {
 0347                return entities[id];
 348            }
 349
 314350            var newEntity = new DecentralandEntity();
 314351            newEntity.entityId = id;
 352
 314353            PoolManagerFactory.EnsureEntityPool(false);
 354
 355            // As we know that the pool already exists, we just get one gameobject from it
 314356            PoolableObject po = PoolManager.i.Get(PoolManagerFactory.EMPTY_GO_POOL_NAME);
 357
 314358            newEntity.meshesInfo.innerGameObject = po.gameObject;
 314359            newEntity.gameObject = po.gameObject;
 360
 361#if UNITY_EDITOR
 314362            newEntity.gameObject.name = "ENTITY_" + id;
 363#endif
 314364            newEntity.gameObject.transform.SetParent(gameObject.transform, false);
 314365            newEntity.gameObject.SetActive(true);
 314366            newEntity.scene = this;
 367
 314368            newEntity.OnCleanupEvent += po.OnCleanup;
 369
 314370            if (Environment.i.world.sceneBoundsChecker.enabled)
 161371                newEntity.OnShapeUpdated += OnEntityShapeUpdated;
 372
 314373            entities.Add(id, newEntity);
 374
 314375            DataStore.i.sceneWorldObjects.sceneData[sceneData.sceneNumber].owners.Add(id);
 376
 314377            OnEntityAdded?.Invoke(newEntity);
 378
 314379            Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked(newEntity, runPreliminaryEvaluation: true);
 380
 314381            return newEntity;
 382        }
 383
 384        void OnEntityShapeUpdated(IDCLEntity entity)
 385        {
 209386            Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked(entity, runPreliminaryEvaluation: true);
 209387        }
 388
 389        public void RemoveEntity(long id, bool removeImmediatelyFromEntitiesList = true)
 390        {
 234391            if (entities.ContainsKey(id))
 392            {
 234393                IDCLEntity entity = entities[id];
 394
 234395                if (!entity.markedForCleanup)
 396                {
 397                    // This will also cleanup its children
 234398                    CleanUpEntityRecursively(entity, removeImmediatelyFromEntitiesList);
 399                }
 400
 234401                entities.Remove(id);
 402
 234403                var data = DataStore.i.sceneWorldObjects.sceneData;
 404
 234405                if (data.ContainsKey(sceneData.sceneNumber))
 406                {
 59407                    data[sceneData.sceneNumber].owners.Remove(id);
 408                }
 409            }
 410#if UNITY_EDITOR || DEVELOPMENT_BUILD
 411            else
 412            {
 0413                Debug.LogWarning($"Couldn't remove entity with ID: {id} as it doesn't exist.");
 414            }
 415#endif
 175416        }
 417
 418        void CleanUpEntityRecursively(IDCLEntity entity, bool removeImmediatelyFromEntitiesList)
 419        {
 243420            using (var iterator = entity.children.GetEnumerator())
 421            {
 252422                while (iterator.MoveNext())
 423                {
 9424                    CleanUpEntityRecursively(iterator.Current.Value, removeImmediatelyFromEntitiesList);
 425                }
 243426            }
 427
 243428            OnEntityRemoved?.Invoke(entity);
 429
 243430            if (Environment.i.world.sceneBoundsChecker.enabled)
 431            {
 158432                entity.OnShapeUpdated -= OnEntityShapeUpdated;
 158433                Environment.i.world.sceneBoundsChecker.RemoveEntity(entity, removeIfPersistent: true, resetState: true);
 434            }
 435
 243436            if (removeImmediatelyFromEntitiesList)
 437            {
 438                // Every entity ends up being removed through here
 237439                entity.Cleanup();
 237440                entities.Remove(entity.entityId);
 441            }
 442            else
 443            {
 6444                Environment.i.platform.parcelScenesCleaner.MarkForCleanup(entity);
 445            }
 6446        }
 447
 448        void RemoveAllEntities(bool instant = false)
 449        {
 450            //NOTE(Brian): We need to remove only the rootEntities.
 451            //             If we don't, duplicated entities will get removed when destroying
 452            //             recursively, making this more complicated than it should.
 288453            List<IDCLEntity> rootEntities = new List<IDCLEntity>();
 454
 288455            using (var iterator = entities.GetEnumerator())
 456            {
 515457                while (iterator.MoveNext())
 458                {
 227459                    if (iterator.Current.Value.parent == null)
 460                    {
 219461                        if (instant)
 210462                            rootEntities.Add(iterator.Current.Value);
 463                        else
 9464                            Environment.i.platform.parcelScenesCleaner.MarkRootEntityForCleanup(this, iterator.Current.V
 465                    }
 466                }
 288467            }
 468
 288469            if (instant)
 470            {
 283471                int rootEntitiesCount = rootEntities.Count;
 986472                for (int i = 0; i < rootEntitiesCount; i++)
 473                {
 210474                    IDCLEntity entity = rootEntities[i];
 210475                    RemoveEntity(entity.entityId, instant);
 476                }
 477
 283478                entities.Clear();
 479
 480                // TODO: Does it make sense that 'RemoveAllEntities()' destroys the whole scene GameObject?
 283481                if (gameObject != null)
 283482                    Destroy(gameObject);
 483            }
 288484        }
 485
 566486        private void RemoveAllEntitiesImmediate() { RemoveAllEntities(instant: true); }
 487
 488        public void SetEntityParent(long entityId, long parentId)
 489        {
 17490            if (entityId == parentId)
 491            {
 0492                return;
 493            }
 494
 17495            IDCLEntity me = GetEntityById(entityId);
 496
 17497            if (me == null)
 0498                return;
 499
 17500            Environment.i.platform.cullingController.MarkDirty();
 17501            Environment.i.platform.physicsSyncController.MarkDirty();
 502
 17503            DataStore_World worldData = DataStore.i.Get<DataStore_World>();
 17504            Transform avatarTransform = worldData.avatarTransform.Get();
 17505            Transform firstPersonCameraTransform = worldData.fpsTransform.Get();
 506
 507            // CONST_THIRD_PERSON_CAMERA_ENTITY_REFERENCE is for compatibility purposes
 17508            if (parentId == (long) SpecialEntityId.FIRST_PERSON_CAMERA_ENTITY_REFERENCE ||
 509                parentId == (long) SpecialEntityId.THIRD_PERSON_CAMERA_ENTITY_REFERENCE)
 510            {
 1511                if (firstPersonCameraTransform == null)
 512                {
 0513                    Debug.LogError("FPS transform is null when trying to set parent! " + sceneData.sceneNumber);
 0514                    return;
 515                }
 516
 517                // In this case, the entity will attached to the first person camera
 518                // On first person mode, the entity will rotate with the camera. On third person mode, the entity will r
 1519                me.SetParent(null);
 1520                me.gameObject.transform.SetParent(firstPersonCameraTransform, false);
 1521                Environment.i.world.sceneBoundsChecker.RemoveEntity(me, removeIfPersistent: true, resetState: true);
 1522                Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked(me, isPersistent: true, runPreliminaryEvalua
 1523                return;
 524            }
 525
 16526            if (parentId == (long) SpecialEntityId.AVATAR_ENTITY_REFERENCE ||
 527                parentId == (long) SpecialEntityId
 528                    .AVATAR_POSITION_REFERENCE) // AvatarPositionEntityReference is for compatibility purposes
 529            {
 1530                if (avatarTransform == null)
 531                {
 0532                    Debug.LogError("Avatar transform is null when trying to set parent! " + sceneData.sceneNumber);
 0533                    return;
 534                }
 535
 536                // In this case, the entity will be attached to the avatar
 537                // It will simply rotate with the avatar, regardless of where the camera is pointing
 1538                me.SetParent(null);
 1539                me.gameObject.transform.SetParent(avatarTransform, false);
 1540                Environment.i.world.sceneBoundsChecker.RemoveEntity(me, removeIfPersistent: true, resetState: true);
 1541                Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked(me, isPersistent: true, runPreliminaryEvalua
 1542                return;
 543            }
 544
 545            // Remove from persistent checks if it was formerly added as child of avatarTransform or fpsTransform
 15546            if (me.gameObject.transform.parent == avatarTransform ||
 547                me.gameObject.transform.parent == firstPersonCameraTransform)
 548            {
 2549                if (Environment.i.world.sceneBoundsChecker.WasAddedAsPersistent(me))
 2550                    Environment.i.world.sceneBoundsChecker.RemoveEntity(me, removeIfPersistent: true);
 551            }
 552
 15553            if (parentId == (long) SpecialEntityId.SCENE_ROOT_ENTITY)
 554            {
 555                // The entity will be child of the scene directly
 2556                me.SetParent(null);
 2557                me.gameObject.transform.SetParent(gameObject.transform, false);
 558            }
 559            else
 560            {
 13561                IDCLEntity myParent = GetEntityById(parentId);
 562
 13563                if (myParent != null)
 564                {
 13565                    me.SetParent(myParent);
 566                }
 567            }
 568
 569            // After reparenting the Entity may end up outside the scene boundaries
 15570            Environment.i.world.sceneBoundsChecker?.AddEntityToBeChecked(me, runPreliminaryEvaluation: true);
 15571        }
 572
 573        protected virtual void SendMetricsEvent()
 574        {
 32943575            if (Time.frameCount % 10 == 0)
 3286576                metricsCounter.SendEvent();
 32943577        }
 578
 579        public IDCLEntity GetEntityById(long entityId)
 580        {
 820581            if (!entities.TryGetValue(entityId, out IDCLEntity entity))
 582            {
 0583                return null;
 584            }
 585
 586            //NOTE(Brian): This is for removing stray null references? This should never happen.
 587            //             Maybe move to a different 'clean-up' method to make this method have a single responsibility?
 820588            if (entity == null || entity.gameObject == null)
 589            {
 0590                entities.Remove(entityId);
 0591                return null;
 592            }
 593
 820594            return entity;
 595        }
 596
 597        public string GetStateString()
 598        {
 733599            string baseState = isPersistent ? "global-scene" : "scene";
 733600            switch (sceneLifecycleHandler.state)
 601            {
 602                case SceneLifecycleHandler.State.NOT_READY:
 0603                    return $"{baseState}:{prettyName} - not ready...";
 604                case SceneLifecycleHandler.State.WAITING_FOR_INIT_MESSAGES:
 381605                    return $"{baseState}:{prettyName} - waiting for init messages...";
 606                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 2607                    return $"{baseState}:{prettyName} - {sceneLifecycleHandler.sceneResourcesLoadTracker.GetStateString(
 608                case SceneLifecycleHandler.State.READY:
 350609                    return $"{baseState}:{prettyName} - ready!";
 610            }
 611
 0612            return $"scene:{prettyName} - no state?";
 613        }
 614
 615        public void RefreshLoadingState()
 616        {
 617#if UNITY_STANDALONE || UNITY_EDITOR
 733618            if (DataStore.i.common.isApplicationQuitting.Get())
 0619                return;
 620#endif
 621
 733622            CalculateSceneLoadingState();
 623
 624#if UNITY_EDITOR
 733625            gameObject.name = GetStateString();
 626#endif
 733627        }
 628
 629        [ContextMenu("Get Waiting Components Debug Info")]
 630        public void GetWaitingComponentsDebugInfo()
 631        {
 0632            switch (sceneLifecycleHandler.state)
 633            {
 634                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 0635                    sceneLifecycleHandler.sceneResourcesLoadTracker.PrintWaitingResourcesDebugInfo();
 0636                    break;
 637
 638                default:
 0639                    Debug.Log($"The scene {sceneData.sceneNumber} is not waiting for any components. Its current state i
 640                    break;
 641            }
 0642        }
 643
 644        [ContextMenu("Get Scene Info")]
 645        public void GetSceneDebugInfo()
 646        {
 0647            Debug.Log("-----------------");
 0648            Debug.Log("SCENE DEBUG INFO:");
 0649            Debug.Log($"Scene Id: {sceneData.id}");
 0650            Debug.Log($"Scene Number: {sceneData.sceneNumber}");
 0651            Debug.Log($"Scene Coords: {sceneData.basePosition.ToString()}");
 0652            Debug.Log($"Scene State: {sceneLifecycleHandler.state.ToString()}");
 0653            Debug.Log("-----------------");
 0654        }
 655
 656        /// <summary>
 657        /// Calculates the current loading progress of the scene and raise the event OnLoadingStateUpdated with the perc
 658        /// </summary>
 659        public void CalculateSceneLoadingState()
 660        {
 733661            loadingProgress = 0f;
 662
 733663            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS ||
 664                sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY)
 665            {
 352666                loadingProgress = sceneLifecycleHandler.loadingProgress;
 667            }
 668
 733669            OnLoadingStateUpdated?.Invoke(loadingProgress);
 0670        }
 671
 672        public bool IsInitMessageDone()
 673        {
 2674            return sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY
 675                   || sceneLifecycleHandler.state == SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS;
 676        }
 677    }
 678}

Methods/Properties

ParcelScene()
entities()
entities(System.Collections.Generic.Dictionary[Int64,IDCLEntity])
componentsManagerLegacy()
componentsManagerLegacy(DCL.IECSComponentsManagerLegacy)
sceneData()
sceneData(DCL.Models.LoadParcelScenesMessage/UnityParcelScene)
metricsCounter()
metricsCounter(DCL.ISceneMetricsCounter)
contentProvider()
contentProvider(DCL.ContentProvider)
isTestScene()
isTestScene(System.Boolean)
isPersistent()
isPersistent(System.Boolean)
isPortableExperience()
isPortableExperience(System.Boolean)
loadingProgress()
loadingProgress(System.Single)
crdtExecutor()
crdtExecutor(DCL.CRDT.ICRDTExecutor)
isReleased()
isReleased(System.Boolean)
Awake()
OnDestroy()
OnDisable()
Update()
prettyName()
SetData(DCL.Models.LoadParcelScenesMessage/UnityParcelScene)
SetupPositionAndParcels()
OnWorldReposition(UnityEngine.Vector3, UnityEngine.Vector3)
SetUpdateData(DCL.Models.LoadParcelScenesMessage/UnityParcelScene)
InitializeDebugPlane()
RemoveDebugPlane()
Cleanup(System.Boolean)
ToString()
GetSceneName()
GetParcels()
IsInsideSceneBoundaries(UnityEngine.Bounds)
IsInsideSceneBoundaries(UnityEngine.Vector2Int, System.Single)
IsInsideSceneBoundaries(UnityEngine.Vector3, System.Single)
IsInsideSceneOuterBoundaries(UnityEngine.Bounds)
IsInsideSceneOuterBoundaries(UnityEngine.Vector3)
OnDrawGizmosSelected()
GetEntityById(System.String)
GetSceneTransform()
CreateEntity(System.Int64)
OnEntityShapeUpdated(DCL.Models.IDCLEntity)
RemoveEntity(System.Int64, System.Boolean)
CleanUpEntityRecursively(DCL.Models.IDCLEntity, System.Boolean)
RemoveAllEntities(System.Boolean)
RemoveAllEntitiesImmediate()
SetEntityParent(System.Int64, System.Int64)
SendMetricsEvent()
GetEntityById(System.Int64)
GetStateString()
RefreshLoadingState()
GetWaitingComponentsDebugInfo()
GetSceneDebugInfo()
CalculateSceneLoadingState()
IsInitMessageDone()