< 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:677
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]
 38217        private bool renderOuterBoundsGizmo = true;
 18
 380219        public Dictionary<long, IDCLEntity> entities { get; private set; } = new Dictionary<long, IDCLEntity>();
 592620        public IECSComponentsManagerLegacy componentsManagerLegacy { get; private set; }
 947721        public LoadParcelScenesMessage.UnityParcelScene sceneData { get; protected set; }
 22
 38223        public HashSet<Vector2Int> parcels = new HashSet<Vector2Int>();
 540124        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
 173930        public ContentProvider contentProvider { get; set; }
 31
 72432        public bool isTestScene { get; set; } = false;
 350933        public bool isPersistent { get; set; } = false;
 35834        public bool isPortableExperience { get; set; } = false;
 35
 107936        public float loadingProgress { get; private set; }
 37
 38        [System.NonSerialized]
 39        public string sceneName;
 40
 41        [System.NonSerialized]
 38242        public bool unloadWithDistance = true;
 43
 44        SceneDebugPlane sceneDebugPlane = null;
 45
 46        public SceneLifecycleHandler sceneLifecycleHandler;
 47
 69248        public ICRDTExecutor crdtExecutor { get; set; }
 49
 60750        public bool isReleased { get; private set; }
 51
 52        private Bounds outerBounds = new Bounds();
 53
 54        public void Awake()
 55        {
 38256            CommonScriptableObjects.worldOffset.OnChange += OnWorldReposition;
 38257            componentsManagerLegacy = new ECSComponentsManagerLegacy(this);
 38258            sceneLifecycleHandler = new SceneLifecycleHandler(this);
 38259            metricsCounter = new SceneMetricsCounter(DataStore.i.sceneWorldObjects);
 38260        }
 61
 62        private void OnDestroy()
 63        {
 38264            CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition;
 38265            metricsCounter?.Dispose();
 38266            crdtExecutor?.Dispose();
 067        }
 68
 76469        void OnDisable() { metricsCounter?.Disable(); }
 70
 71        private void Update()
 72        {
 3348673            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY
 74                && CommonScriptableObjects.rendererState.Get())
 3296875                SendMetricsEvent();
 3348676        }
 77
 72878        protected virtual string prettyName => sceneData.basePosition.ToString();
 79
 80        public virtual void SetData(LoadParcelScenesMessage.UnityParcelScene data)
 81        {
 37782            Assert.IsTrue( data.sceneNumber > 0, "Scene must have a valid scene number!" );
 83
 37784            this.sceneData = data;
 85
 37786            contentProvider = new ContentProvider();
 37787            contentProvider.baseUrl = data.baseUrl;
 37788            contentProvider.contents = data.contents;
 37789            contentProvider.BakeHashes();
 90
 37791            SetupPositionAndParcels();
 92
 37793            DataStore.i.sceneWorldObjects.AddScene(sceneData.sceneNumber);
 94
 37795            metricsCounter.Configure(sceneData.sceneNumber, sceneData.basePosition, sceneData.parcels.Length);
 37796            metricsCounter.Enable();
 97
 37798            OnSetData?.Invoke(data);
 37799        }
 100
 101        void SetupPositionAndParcels()
 102        {
 377103            gameObject.transform.position = PositionUtils.WorldToUnityPosition(Utils.GridToWorldPosition(sceneData.baseP
 104
 377105            parcels.Clear();
 106
 107            // The scene's gameobject position should already be in 'unityposition'
 377108            Vector3 baseParcelWorldPos = gameObject.transform.position;
 109
 377110            outerBounds.SetMinMax(new Vector3(baseParcelWorldPos.x, 0f, baseParcelWorldPos.z),
 111                new Vector3(baseParcelWorldPos.x + ParcelSettings.PARCEL_SIZE, 0f, baseParcelWorldPos.z + ParcelSettings
 112
 1532113            for (int i = 0; i < sceneData.parcels.Length; i++)
 114            {
 115                // 1. Update outer bounds with parcel's size
 389116                var parcel = sceneData.parcels[i];
 117
 389118                Vector3 parcelWorldPos = PositionUtils.WorldToUnityPosition(Utils.GridToWorldPosition(parcel.x, parcel.y
 389119                outerBounds.Encapsulate(new Vector3(parcelWorldPos.x, 0, parcelWorldPos.z));
 389120                outerBounds.Encapsulate(new Vector3(parcelWorldPos.x + ParcelSettings.PARCEL_SIZE, 0, parcelWorldPos.z +
 121
 122                // 2. add parcel to collection
 389123                parcels.Add(parcel);
 124            }
 125
 126            // Apply outer bounds extra threshold
 377127            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
 377129        }
 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        {
 264151            if (EnvironmentSettings.DEBUG && sceneData.parcels != null && sceneDebugPlane == null)
 152            {
 264153                sceneDebugPlane = new SceneDebugPlane(sceneData, gameObject.transform);
 154            }
 264155        }
 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        {
 302168            if (isReleased || gameObject == null)
 0169                return;
 170
 302171            if (sceneDebugPlane != null)
 172            {
 264173                sceneDebugPlane.Dispose();
 264174                sceneDebugPlane = null;
 175            }
 176
 302177            componentsManagerLegacy.DisposeAllSceneComponents();
 178
 302179            if (crdtExecutor != null)
 180            {
 2181                crdtExecutor.Dispose();
 2182                crdtExecutor = null;
 183            }
 184
 302185            if (immediate) //!CommonScriptableObjects.rendererState.Get())
 186            {
 282187                RemoveAllEntitiesImmediate();
 282188                PoolManager.i.Cleanup(true, true);
 282189                DataStore.i.sceneWorldObjects.RemoveScene(sceneData.sceneNumber);
 190            }
 191            else
 192            {
 20193                if (entities.Count > 0)
 194                {
 4195                    this.gameObject.transform.position = EnvironmentSettings.MORDOR;
 4196                    this.gameObject.SetActive(false);
 197
 4198                    RemoveAllEntities();
 199                }
 200                else
 201                {
 16202                    Destroy(this.gameObject);
 16203                    DataStore.i.sceneWorldObjects.RemoveScene(sceneData.sceneNumber);
 204
 205                }
 206            }
 207
 302208            isReleased = true;
 302209        }
 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
 654218        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        {
 130234            if (isPersistent)
 104235                return true;
 236
 26237            if (parcels.Count == 0)
 0238                return false;
 239
 26240            float heightLimit = metricsCounter.maxCount.sceneHeight;
 241
 26242            if (height > heightLimit)
 0243                return false;
 244
 26245            return parcels.Contains(gridPosition);
 246        }
 247
 248        public virtual bool IsInsideSceneBoundaries(Vector3 worldPosition, float height = 0f)
 249        {
 134250            if (isPersistent)
 0251                return true;
 252
 134253            if (parcels.Count == 0)
 0254                return false;
 255
 134256            float heightLimit = metricsCounter.maxCount.sceneHeight;
 134257            if (height > heightLimit)
 4258                return false;
 259
 130260            int noThresholdZCoordinate = Mathf.FloorToInt(worldPosition.z / ParcelSettings.PARCEL_SIZE);
 130261            int noThresholdXCoordinate = Mathf.FloorToInt(worldPosition.x / ParcelSettings.PARCEL_SIZE);
 262
 263            // We check the target world position
 130264            Vector2Int targetCoordinate = new Vector2Int(noThresholdXCoordinate, noThresholdZCoordinate);
 130265            if (parcels.Contains(targetCoordinate))
 65266                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        {
 124314            if (isPersistent)
 0315                return true;
 316
 124317            objectUnityPosition.y = 0f;
 124318            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(); }
 50340        public Transform GetSceneTransform() { return transform; }
 341
 342        public IDCLEntity CreateEntity(long id)
 343        {
 310344            if (entities.ContainsKey(id))
 345            {
 0346                return entities[id];
 347            }
 348
 310349            var newEntity = new DecentralandEntity();
 310350            newEntity.entityId = id;
 351
 310352            PoolManagerFactory.EnsureEntityPool(false);
 353
 354            // As we know that the pool already exists, we just get one gameobject from it
 310355            PoolableObject po = PoolManager.i.Get(PoolManagerFactory.EMPTY_GO_POOL_NAME);
 356
 310357            newEntity.meshesInfo.innerGameObject = po.gameObject;
 310358            newEntity.gameObject = po.gameObject;
 359
 360#if UNITY_EDITOR
 310361            newEntity.gameObject.name = "ENTITY_" + id;
 362#endif
 310363            newEntity.gameObject.transform.SetParent(gameObject.transform, false);
 310364            newEntity.gameObject.SetActive(true);
 310365            newEntity.scene = this;
 366
 310367            newEntity.OnCleanupEvent += po.OnCleanup;
 368
 310369            if (Environment.i.world.sceneBoundsChecker.enabled)
 157370                newEntity.OnShapeUpdated += OnEntityShapeUpdated;
 371
 310372            entities.Add(id, newEntity);
 373
 310374            DataStore.i.sceneWorldObjects.sceneData[sceneData.sceneNumber].owners.Add(id);
 375
 310376            OnEntityAdded?.Invoke(newEntity);
 377
 310378            Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked(newEntity, runPreliminaryEvaluation: true);
 379
 310380            return newEntity;
 381        }
 382
 383        void OnEntityShapeUpdated(IDCLEntity entity)
 384        {
 210385            Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked(entity, runPreliminaryEvaluation: true);
 210386        }
 387
 388        public void RemoveEntity(long id, bool removeImmediatelyFromEntitiesList = true)
 389        {
 232390            if (entities.ContainsKey(id))
 391            {
 232392                IDCLEntity entity = entities[id];
 393
 232394                if (!entity.markedForCleanup)
 395                {
 396                    // This will also cleanup its children
 232397                    CleanUpEntityRecursively(entity, removeImmediatelyFromEntitiesList);
 398                }
 399
 232400                entities.Remove(id);
 401
 232402                var data = DataStore.i.sceneWorldObjects.sceneData;
 403
 232404                if (data.ContainsKey(sceneData.sceneNumber))
 405                {
 57406                    data[sceneData.sceneNumber].owners.Remove(id);
 407                }
 408            }
 409#if UNITY_EDITOR || DEVELOPMENT_BUILD
 410            else
 411            {
 0412                Debug.LogWarning($"Couldn't remove entity with ID: {id} as it doesn't exist.");
 413            }
 414#endif
 175415        }
 416
 417        void CleanUpEntityRecursively(IDCLEntity entity, bool removeImmediatelyFromEntitiesList)
 418        {
 241419            using (var iterator = entity.children.GetEnumerator())
 420            {
 250421                while (iterator.MoveNext())
 422                {
 9423                    CleanUpEntityRecursively(iterator.Current.Value, removeImmediatelyFromEntitiesList);
 424                }
 241425            }
 426
 241427            OnEntityRemoved?.Invoke(entity);
 428
 241429            if (Environment.i.world.sceneBoundsChecker.enabled)
 430            {
 156431                entity.OnShapeUpdated -= OnEntityShapeUpdated;
 156432                Environment.i.world.sceneBoundsChecker.RemoveEntity(entity, removeIfPersistent: true, resetState: true);
 433            }
 434
 241435            if (removeImmediatelyFromEntitiesList)
 436            {
 437                // Every entity ends up being removed through here
 238438                entity.Cleanup();
 238439                entities.Remove(entity.entityId);
 440            }
 441            else
 442            {
 3443                Environment.i.platform.parcelScenesCleaner.MarkForCleanup(entity);
 444            }
 3445        }
 446
 447        void RemoveAllEntities(bool instant = false)
 448        {
 449            //NOTE(Brian): We need to remove only the rootEntities.
 450            //             If we don't, duplicated entities will get removed when destroying
 451            //             recursively, making this more complicated than it should.
 286452            List<IDCLEntity> rootEntities = new List<IDCLEntity>();
 453
 286454            using (var iterator = entities.GetEnumerator())
 455            {
 509456                while (iterator.MoveNext())
 457                {
 223458                    if (iterator.Current.Value.parent == null)
 459                    {
 215460                        if (instant)
 211461                            rootEntities.Add(iterator.Current.Value);
 462                        else
 4463                            Environment.i.platform.parcelScenesCleaner.MarkRootEntityForCleanup(this, iterator.Current.V
 464                    }
 465                }
 286466            }
 467
 286468            if (instant)
 469            {
 282470                int rootEntitiesCount = rootEntities.Count;
 986471                for (int i = 0; i < rootEntitiesCount; i++)
 472                {
 211473                    IDCLEntity entity = rootEntities[i];
 211474                    RemoveEntity(entity.entityId, instant);
 475                }
 476
 282477                entities.Clear();
 478
 479                // TODO: Does it make sense that 'RemoveAllEntities()' destroys the whole scene GameObject?
 282480                if (gameObject != null)
 282481                    Destroy(gameObject);
 482            }
 286483        }
 484
 564485        private void RemoveAllEntitiesImmediate() { RemoveAllEntities(instant: true); }
 486
 487        public void SetEntityParent(long entityId, long parentId)
 488        {
 17489            if (entityId == parentId)
 490            {
 0491                return;
 492            }
 493
 17494            IDCLEntity me = GetEntityById(entityId);
 495
 17496            if (me == null)
 0497                return;
 498
 17499            Environment.i.platform.cullingController.MarkDirty();
 17500            Environment.i.platform.physicsSyncController.MarkDirty();
 501
 17502            DataStore_World worldData = DataStore.i.Get<DataStore_World>();
 17503            Transform avatarTransform = worldData.avatarTransform.Get();
 17504            Transform firstPersonCameraTransform = worldData.fpsTransform.Get();
 505
 506            // CONST_THIRD_PERSON_CAMERA_ENTITY_REFERENCE is for compatibility purposes
 17507            if (parentId == (long) SpecialEntityId.FIRST_PERSON_CAMERA_ENTITY_REFERENCE ||
 508                parentId == (long) SpecialEntityId.THIRD_PERSON_CAMERA_ENTITY_REFERENCE)
 509            {
 1510                if (firstPersonCameraTransform == null)
 511                {
 0512                    Debug.LogError("FPS transform is null when trying to set parent! " + sceneData.sceneNumber);
 0513                    return;
 514                }
 515
 516                // In this case, the entity will attached to the first person camera
 517                // On first person mode, the entity will rotate with the camera. On third person mode, the entity will r
 1518                me.SetParent(null);
 1519                me.gameObject.transform.SetParent(firstPersonCameraTransform, false);
 1520                Environment.i.world.sceneBoundsChecker.RemoveEntity(me, removeIfPersistent: true, resetState: true);
 1521                Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked(me, isPersistent: true, runPreliminaryEvalua
 1522                return;
 523            }
 524
 16525            if (parentId == (long) SpecialEntityId.AVATAR_ENTITY_REFERENCE ||
 526                parentId == (long) SpecialEntityId
 527                    .AVATAR_POSITION_REFERENCE) // AvatarPositionEntityReference is for compatibility purposes
 528            {
 1529                if (avatarTransform == null)
 530                {
 0531                    Debug.LogError("Avatar transform is null when trying to set parent! " + sceneData.sceneNumber);
 0532                    return;
 533                }
 534
 535                // In this case, the entity will be attached to the avatar
 536                // It will simply rotate with the avatar, regardless of where the camera is pointing
 1537                me.SetParent(null);
 1538                me.gameObject.transform.SetParent(avatarTransform, false);
 1539                Environment.i.world.sceneBoundsChecker.RemoveEntity(me, removeIfPersistent: true, resetState: true);
 1540                Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked(me, isPersistent: true, runPreliminaryEvalua
 1541                return;
 542            }
 543
 544            // Remove from persistent checks if it was formerly added as child of avatarTransform or fpsTransform
 15545            if (me.gameObject.transform.parent == avatarTransform ||
 546                me.gameObject.transform.parent == firstPersonCameraTransform)
 547            {
 2548                if (Environment.i.world.sceneBoundsChecker.WasAddedAsPersistent(me))
 2549                    Environment.i.world.sceneBoundsChecker.RemoveEntity(me, removeIfPersistent: true);
 550            }
 551
 15552            if (parentId == (long) SpecialEntityId.SCENE_ROOT_ENTITY)
 553            {
 554                // The entity will be child of the scene directly
 2555                me.SetParent(null);
 2556                me.gameObject.transform.SetParent(gameObject.transform, false);
 557            }
 558            else
 559            {
 13560                IDCLEntity myParent = GetEntityById(parentId);
 561
 13562                if (myParent != null)
 563                {
 13564                    me.SetParent(myParent);
 565                }
 566            }
 567
 568            // After reparenting the Entity may end up outside the scene boundaries
 15569            Environment.i.world.sceneBoundsChecker?.AddEntityToBeChecked(me, runPreliminaryEvaluation: true);
 15570        }
 571
 572        protected virtual void SendMetricsEvent()
 573        {
 32968574            if (Time.frameCount % 10 == 0)
 3291575                metricsCounter.SendEvent();
 32968576        }
 577
 578        public IDCLEntity GetEntityById(long entityId)
 579        {
 823580            if (!entities.TryGetValue(entityId, out IDCLEntity entity))
 581            {
 0582                return null;
 583            }
 584
 585            //NOTE(Brian): This is for removing stray null references? This should never happen.
 586            //             Maybe move to a different 'clean-up' method to make this method have a single responsibility?
 823587            if (entity == null || entity.gameObject == null)
 588            {
 0589                entities.Remove(entityId);
 0590                return null;
 591            }
 592
 823593            return entity;
 594        }
 595
 596        public string GetStateString()
 597        {
 728598            string baseState = isPersistent ? "global-scene" : "scene";
 728599            switch (sceneLifecycleHandler.state)
 600            {
 601                case SceneLifecycleHandler.State.NOT_READY:
 0602                    return $"{baseState}:{prettyName} - not ready...";
 603                case SceneLifecycleHandler.State.WAITING_FOR_INIT_MESSAGES:
 377604                    return $"{baseState}:{prettyName} - waiting for init messages...";
 605                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 2606                    return $"{baseState}:{prettyName} - {sceneLifecycleHandler.sceneResourcesLoadTracker.GetStateString(
 607                case SceneLifecycleHandler.State.READY:
 349608                    return $"{baseState}:{prettyName} - ready!";
 609            }
 610
 0611            return $"scene:{prettyName} - no state?";
 612        }
 613
 614        public void RefreshLoadingState()
 615        {
 616#if UNITY_STANDALONE || UNITY_EDITOR
 728617            if (DataStore.i.common.isApplicationQuitting.Get())
 0618                return;
 619#endif
 620
 728621            CalculateSceneLoadingState();
 622
 623#if UNITY_EDITOR
 728624            gameObject.name = GetStateString();
 625#endif
 728626        }
 627
 628        [ContextMenu("Get Waiting Components Debug Info")]
 629        public void GetWaitingComponentsDebugInfo()
 630        {
 0631            switch (sceneLifecycleHandler.state)
 632            {
 633                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 0634                    sceneLifecycleHandler.sceneResourcesLoadTracker.PrintWaitingResourcesDebugInfo();
 0635                    break;
 636
 637                default:
 0638                    Debug.Log($"The scene {sceneData.sceneNumber} is not waiting for any components. Its current state i
 639                    break;
 640            }
 0641        }
 642
 643        [ContextMenu("Get Scene Info")]
 644        public void GetSceneDebugInfo()
 645        {
 0646            Debug.Log("-----------------");
 0647            Debug.Log("SCENE DEBUG INFO:");
 0648            Debug.Log($"Scene Id: {sceneData.id}");
 0649            Debug.Log($"Scene Number: {sceneData.sceneNumber}");
 0650            Debug.Log($"Scene Coords: {sceneData.basePosition.ToString()}");
 0651            Debug.Log($"Scene State: {sceneLifecycleHandler.state.ToString()}");
 0652            Debug.Log("-----------------");
 0653        }
 654
 655        /// <summary>
 656        /// Calculates the current loading progress of the scene and raise the event OnLoadingStateUpdated with the perc
 657        /// </summary>
 658        public void CalculateSceneLoadingState()
 659        {
 728660            loadingProgress = 0f;
 661
 728662            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS ||
 663                sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY)
 664            {
 351665                loadingProgress = sceneLifecycleHandler.loadingProgress;
 666            }
 667
 728668            OnLoadingStateUpdated?.Invoke(loadingProgress);
 0669        }
 670
 671        public bool IsInitMessageDone()
 672        {
 2673            return sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY
 674                   || sceneLifecycleHandler.state == SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS;
 675        }
 676    }
 677}

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