< 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:245
Uncovered lines:55
Coverable lines:300
Total lines:657
Line coverage:81.6% (245 of 300)
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%110100%
InitializeDebugPlane()0%440100%
RemoveDebugPlane()0%6200%
Cleanup(...)0%7.117086.96%
ToString()0%12300%
GetSceneName()0%6200%
GetParcels()0%110100%
IsInsideSceneBoundaries(...)0%440100%
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%440100%
OnEntityShapeUpdated(...)0%110100%
RemoveEntity(...)0%4.014090.91%
CleanUpEntityRecursively(...)0%550100%
RemoveAllEntities(...)0%770100%
RemoveAllEntitiesImmediate()0%110100%
SetEntityParent(...)0%15.7615085%
SendMetricsEvent()0%220100%
GetEntityById(...)0%4.594066.67%
GetStateString()0%13.048057.14%
RefreshLoadingState()0%2.032080%
GetWaitingComponentsDebugInfo()0%6200%
CalculateSceneLoadingState()0%4.134080%

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]
 53917        private bool renderOuterBoundsGizmo = true;
 18
 91019        public Dictionary<long, IDCLEntity> entities { get; private set; } = new Dictionary<long, IDCLEntity>();
 343820        public IECSComponentsManagerLegacy componentsManagerLegacy { get; private set; }
 305221        public LoadParcelScenesMessage.UnityParcelScene sceneData { get; protected set; }
 22
 53923        public HashSet<Vector2Int> parcels = new HashSet<Vector2Int>();
 4924        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
 15430        public ContentProvider contentProvider { get; set; }
 31
 032        public bool isTestScene { get; set; } = false;
 197533        public bool isPersistent { get; set; } = false;
 034        public float loadingProgress { get; private set; }
 35
 36        [System.NonSerialized]
 37        public string sceneName;
 38
 39        [System.NonSerialized]
 53940        public bool unloadWithDistance = true;
 41
 42        SceneDebugPlane sceneDebugPlane = null;
 43
 44        public SceneLifecycleHandler sceneLifecycleHandler;
 45
 046        public ICRDTExecutor crdtExecutor { get; set; }
 47
 048        public bool isReleased { get; private set; }
 49
 50        private Bounds outerBounds = new Bounds();
 51
 52        public void Awake()
 53        {
 53954            CommonScriptableObjects.worldOffset.OnChange += OnWorldReposition;
 53955            componentsManagerLegacy = new ECSComponentsManagerLegacy(this);
 53956            sceneLifecycleHandler = new SceneLifecycleHandler(this);
 53957            metricsCounter = new SceneMetricsCounter(DataStore.i.sceneWorldObjects);
 53958        }
 59
 60        private void OnDestroy()
 61        {
 53962            CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition;
 53963            metricsCounter?.Dispose();
 53964            crdtExecutor?.Dispose();
 065        }
 66
 108667        void OnDisable() { metricsCounter?.Disable(); }
 68
 69        private void Update()
 70        {
 851171            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY
 72                && CommonScriptableObjects.rendererState.Get())
 784073                SendMetricsEvent();
 851174        }
 75
 103276        protected virtual string prettyName => sceneData.basePosition.ToString();
 77
 78        public virtual void SetData(LoadParcelScenesMessage.UnityParcelScene data)
 79        {
 53280            Assert.IsTrue( !string.IsNullOrEmpty(data.id), "Scene must have an ID!" );
 81
 53282            this.sceneData = data;
 83
 53284            contentProvider = new ContentProvider();
 53285            contentProvider.baseUrl = data.baseUrl;
 53286            contentProvider.contents = data.contents;
 53287            contentProvider.BakeHashes();
 88
 53289            SetupPositionAndParcels();
 90
 53291            DataStore.i.sceneWorldObjects.AddScene(sceneData.id);
 92
 53293            metricsCounter.Configure(sceneData.id, sceneData.basePosition, sceneData.parcels.Length);
 53294            metricsCounter.Enable();
 95
 53296            OnSetData?.Invoke(data);
 53297        }
 98
 99        void SetupPositionAndParcels()
 100        {
 532101            gameObject.transform.position = PositionUtils.WorldToUnityPosition(Utils.GridToWorldPosition(sceneData.baseP
 102
 532103            parcels.Clear();
 104
 105            // The scene's gameobject position should already be in 'unityposition'
 532106            Vector3 baseParcelWorldPos = gameObject.transform.position;
 107
 532108            outerBounds.SetMinMax(new Vector3(baseParcelWorldPos.x, 0f, baseParcelWorldPos.z),
 109                new Vector3(baseParcelWorldPos.x + ParcelSettings.PARCEL_SIZE, 0f, baseParcelWorldPos.z + ParcelSettings
 110
 2160111            for (int i = 0; i < sceneData.parcels.Length; i++)
 112            {
 113                // 1. Update outer bounds with parcel's size
 548114                var parcel = sceneData.parcels[i];
 115
 548116                Vector3 parcelWorldPos = PositionUtils.WorldToUnityPosition(Utils.GridToWorldPosition(parcel.x, parcel.y
 548117                outerBounds.Encapsulate(new Vector3(parcelWorldPos.x, 0, parcelWorldPos.z));
 548118                outerBounds.Encapsulate(new Vector3(parcelWorldPos.x + ParcelSettings.PARCEL_SIZE, 0, parcelWorldPos.z +
 119
 120                // 2. add parcel to collection
 548121                parcels.Add(parcel);
 122            }
 123
 124            // Apply outer bounds extra threshold
 532125            outerBounds.SetMinMax(new Vector3(outerBounds.min.x - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD, 0f, outerB
 126                new Vector3(outerBounds.max.x + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD, 0f, outerBounds.max.z + Parc
 532127        }
 128
 129        void OnWorldReposition(Vector3 current, Vector3 previous)
 130        {
 2131            Vector3 currentSceneWorldPos = Utils.GridToWorldPosition(sceneData.basePosition.x, sceneData.basePosition.y)
 2132            Vector3 oldSceneUnityPos = gameObject.transform.position;
 2133            Vector3 newSceneUnityPos = PositionUtils.WorldToUnityPosition(currentSceneWorldPos);
 134
 2135            gameObject.transform.position = newSceneUnityPos;
 2136            outerBounds.center += newSceneUnityPos - oldSceneUnityPos;
 2137        }
 138
 139        public virtual void SetUpdateData(LoadParcelScenesMessage.UnityParcelScene data)
 140        {
 15141            contentProvider = new ContentProvider();
 15142            contentProvider.baseUrl = data.baseUrl;
 15143            contentProvider.contents = data.contents;
 15144            contentProvider.BakeHashes();
 15145        }
 146
 147        public void InitializeDebugPlane()
 148        {
 414149            if (EnvironmentSettings.DEBUG && sceneData.parcels != null && sceneDebugPlane == null)
 150            {
 412151                sceneDebugPlane = new SceneDebugPlane(sceneData, gameObject.transform);
 152            }
 414153        }
 154
 155        public void RemoveDebugPlane()
 156        {
 0157            if (sceneDebugPlane != null)
 158            {
 0159                sceneDebugPlane.Dispose();
 0160                sceneDebugPlane = null;
 161            }
 0162        }
 163
 164        public void Cleanup(bool immediate)
 165        {
 448166            if (isReleased || gameObject == null)
 0167                return;
 168
 448169            if (sceneDebugPlane != null)
 170            {
 412171                sceneDebugPlane.Dispose();
 412172                sceneDebugPlane = null;
 173            }
 174
 448175            componentsManagerLegacy.DisposeAllSceneComponents();
 176
 448177            if (crdtExecutor != null)
 178            {
 0179                crdtExecutor.Dispose();
 0180                crdtExecutor = null;
 181            }
 182
 448183            if (immediate) //!CommonScriptableObjects.rendererState.Get())
 184            {
 431185                RemoveAllEntitiesImmediate();
 431186                PoolManager.i.Cleanup(true, true);
 431187                DataStore.i.sceneWorldObjects.RemoveScene(sceneData.id);
 431188            }
 189            else
 190            {
 17191                if (entities.Count > 0)
 192                {
 1193                    this.gameObject.transform.position = EnvironmentSettings.MORDOR;
 1194                    this.gameObject.SetActive(false);
 195
 1196                    RemoveAllEntities();
 1197                }
 198                else
 199                {
 16200                    Destroy(this.gameObject);
 16201                    DataStore.i.sceneWorldObjects.RemoveScene(sceneData.id);
 202
 203                }
 204            }
 205
 448206            isReleased = true;
 448207        }
 208
 0209        public override string ToString() { return "Parcel Scene: " + base.ToString() + "\n" + sceneData; }
 210
 211        public string GetSceneName()
 212        {
 0213            return string.IsNullOrEmpty(sceneName) ? "Unnamed" : sceneName;
 214        }
 215
 949216        public HashSet<Vector2Int> GetParcels() => parcels;
 217        public bool IsInsideSceneBoundaries(Bounds objectBounds)
 218        {
 101219            if (isPersistent)
 13220                return true;
 221
 88222            if (!IsInsideSceneBoundaries(objectBounds.min + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 58223                return false;
 30224            if (!IsInsideSceneBoundaries(objectBounds.max + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 1225                return false;
 226
 29227            return true;
 228        }
 229
 230        public virtual bool IsInsideSceneBoundaries(Vector2Int gridPosition, float height = 0f)
 231        {
 129232            if (isPersistent)
 112233                return true;
 234
 17235            if (parcels.Count == 0)
 0236                return false;
 237
 17238            float heightLimit = metricsCounter.maxCount.sceneHeight;
 239
 17240            if (height > heightLimit)
 0241                return false;
 242
 17243            return parcels.Contains(gridPosition);
 244        }
 245
 246        public virtual bool IsInsideSceneBoundaries(Vector3 worldPosition, float height = 0f)
 247        {
 157248            if (isPersistent)
 0249                return true;
 250
 157251            if (parcels.Count == 0)
 0252                return false;
 253
 157254            float heightLimit = metricsCounter.maxCount.sceneHeight;
 157255            if (height > heightLimit)
 10256                return false;
 257
 147258            int noThresholdZCoordinate = Mathf.FloorToInt(worldPosition.z / ParcelSettings.PARCEL_SIZE);
 147259            int noThresholdXCoordinate = Mathf.FloorToInt(worldPosition.x / ParcelSettings.PARCEL_SIZE);
 260
 261            // We check the target world position
 147262            Vector2Int targetCoordinate = new Vector2Int(noThresholdXCoordinate, noThresholdZCoordinate);
 147263            if (parcels.Contains(targetCoordinate))
 80264                return true;
 265
 266            // We need to check using a threshold from the target point, in order to cover correctly the parcel "border/
 67267            Vector2Int coordinateMin = new Vector2Int();
 67268            coordinateMin.x = Mathf.FloorToInt((worldPosition.x - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 67269            coordinateMin.y = Mathf.FloorToInt((worldPosition.z - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 270
 67271            Vector2Int coordinateMax = new Vector2Int();
 67272            coordinateMax.x = Mathf.FloorToInt((worldPosition.x + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 67273            coordinateMax.y = Mathf.FloorToInt((worldPosition.z + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 274
 275            // We check the east/north-threshold position
 67276            targetCoordinate.Set(coordinateMax.x, coordinateMax.y);
 67277            if (parcels.Contains(targetCoordinate))
 0278                return true;
 279
 280            // We check the east/south-threshold position
 67281            targetCoordinate.Set(coordinateMax.x, coordinateMin.y);
 67282            if (parcels.Contains(targetCoordinate))
 0283                return true;
 284
 285            // We check the west/north-threshold position
 67286            targetCoordinate.Set(coordinateMin.x, coordinateMax.y);
 67287            if (parcels.Contains(targetCoordinate))
 0288                return true;
 289
 290            // We check the west/south-threshold position
 67291            targetCoordinate.Set(coordinateMin.x, coordinateMin.y);
 67292            if (parcels.Contains(targetCoordinate))
 0293                return true;
 294
 67295            return false;
 296        }
 297
 298        public bool IsInsideSceneOuterBoundaries(Bounds objectBounds)
 299        {
 153300            if (isPersistent)
 0301                return true;
 302
 153303            Vector3 objectBoundsMin = new Vector3(objectBounds.min.x, 0f, objectBounds.min.z);
 153304            Vector3 objectBoundsMax = new Vector3(objectBounds.max.x, 0f, objectBounds.max.z);
 153305            bool isInsideOuterBoundaries = outerBounds.Contains(objectBoundsMin) && outerBounds.Contains(objectBoundsMax
 306
 88307            return isInsideOuterBoundaries;
 308        }
 309
 310        public bool IsInsideSceneOuterBoundaries(Vector3 objectUnityPosition)
 311        {
 178312            if (isPersistent)
 0313                return true;
 314
 178315            objectUnityPosition.y = 0f;
 178316            return outerBounds.Contains(objectUnityPosition);
 317        }
 318
 319        private void OnDrawGizmosSelected()
 320        {
 0321            if(!renderOuterBoundsGizmo) return;
 322
 0323            Gizmos.color = new Color(Color.yellow.r, Color.yellow.g, Color.yellow.b, 0.5f);
 0324            Gizmos.DrawCube(outerBounds.center, outerBounds.size + Vector3.up);
 325
 0326            Gizmos.color = new Color(Color.green.r, Color.green.g, Color.green.b, 0.5f);
 0327            Bounds  parcelBounds = new Bounds();
 0328            foreach (Vector2Int parcel in parcels)
 329            {
 0330                Vector3 parcelSceneUnityPos = PositionUtils.WorldToUnityPosition(Utils.GridToWorldPosition(parcel.x, par
 0331                parcelBounds.center = parcelSceneUnityPos + new Vector3(8f, 0f, 8f);
 0332                parcelBounds.size = new Vector3(16f, 0.1f, 16f);
 0333                Gizmos.DrawCube(parcelBounds.center, parcelBounds.size);
 334            }
 0335        }
 336
 0337        public IDCLEntity GetEntityById(string entityId) { throw new System.NotImplementedException(); }
 58338        public Transform GetSceneTransform() { return transform; }
 339
 340        public IDCLEntity CreateEntity(long id)
 341        {
 608342            if (entities.ContainsKey(id))
 343            {
 2344                return entities[id];
 345            }
 346
 606347            var newEntity = new DecentralandEntity();
 606348            newEntity.entityId = id;
 349
 606350            PoolManagerFactory.EnsureEntityPool(false);
 351
 352            // As we know that the pool already exists, we just get one gameobject from it
 606353            PoolableObject po = PoolManager.i.Get(PoolManagerFactory.EMPTY_GO_POOL_NAME);
 354
 606355            newEntity.meshesInfo.innerGameObject = po.gameObject;
 606356            newEntity.gameObject = po.gameObject;
 357
 358#if UNITY_EDITOR
 606359            newEntity.gameObject.name = "ENTITY_" + id;
 360#endif
 606361            newEntity.gameObject.transform.SetParent(gameObject.transform, false);
 606362            newEntity.gameObject.SetActive(true);
 606363            newEntity.scene = this;
 364
 606365            newEntity.OnCleanupEvent += po.OnCleanup;
 366
 606367            if (Environment.i.world.sceneBoundsChecker.enabled)
 453368                newEntity.OnShapeUpdated += OnEntityShapeUpdated;
 369
 606370            entities.Add(id, newEntity);
 371
 606372            DataStore.i.sceneWorldObjects.sceneData[sceneData.id].owners.Add(id);
 373
 606374            OnEntityAdded?.Invoke(newEntity);
 375
 606376            Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked(newEntity, runPreliminaryEvaluation: true);
 377
 606378            return newEntity;
 379        }
 380
 381        void OnEntityShapeUpdated(IDCLEntity entity)
 382        {
 227383            Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked(entity, runPreliminaryEvaluation: true);
 227384        }
 385
 386        public void RemoveEntity(long id, bool removeImmediatelyFromEntitiesList = true)
 387        {
 526388            if (entities.ContainsKey(id))
 389            {
 526390                IDCLEntity entity = entities[id];
 391
 526392                if (!entity.markedForCleanup)
 393                {
 394                    // This will also cleanup its children
 526395                    CleanUpEntityRecursively(entity, removeImmediatelyFromEntitiesList);
 396                }
 397
 526398                entities.Remove(id);
 399
 526400                var data = DataStore.i.sceneWorldObjects.sceneData;
 401
 526402                if (data.ContainsKey(sceneData.id))
 403                {
 68404                    data[sceneData.id].owners.Remove(id);
 405                }
 68406            }
 407#if UNITY_EDITOR || DEVELOPMENT_BUILD
 408            else
 409            {
 0410                Debug.LogWarning($"Couldn't remove entity with ID: {id} as it doesn't exist.");
 411            }
 412#endif
 458413        }
 414
 415        void CleanUpEntityRecursively(IDCLEntity entity, bool removeImmediatelyFromEntitiesList)
 416        {
 535417            using (var iterator = entity.children.GetEnumerator())
 418            {
 544419                while (iterator.MoveNext())
 420                {
 9421                    CleanUpEntityRecursively(iterator.Current.Value, removeImmediatelyFromEntitiesList);
 422                }
 535423            }
 424
 535425            OnEntityRemoved?.Invoke(entity);
 426
 535427            if (Environment.i.world.sceneBoundsChecker.enabled)
 428            {
 450429                entity.OnShapeUpdated -= OnEntityShapeUpdated;
 450430                Environment.i.world.sceneBoundsChecker.RemoveEntity(entity, removeIfPersistent: true, resetState: true);
 431            }
 432
 535433            if (removeImmediatelyFromEntitiesList)
 434            {
 435                // Every entity ends up being removed through here
 534436                entity.Cleanup();
 534437                entities.Remove(entity.entityId);
 534438            }
 439            else
 440            {
 1441                Environment.i.platform.parcelScenesCleaner.MarkForCleanup(entity);
 442            }
 1443        }
 444
 445        void RemoveAllEntities(bool instant = false)
 446        {
 447            //NOTE(Brian): We need to remove only the rootEntities.
 448            //             If we don't, duplicated entities will get removed when destroying
 449            //             recursively, making this more complicated than it should.
 432450            List<IDCLEntity> rootEntities = new List<IDCLEntity>();
 451
 432452            using (var iterator = entities.GetEnumerator())
 453            {
 935454                while (iterator.MoveNext())
 455                {
 503456                    if (iterator.Current.Value.parent == null)
 457                    {
 495458                        if (instant)
 494459                            rootEntities.Add(iterator.Current.Value);
 460                        else
 1461                            Environment.i.platform.parcelScenesCleaner.MarkRootEntityForCleanup(this, iterator.Current.V
 462                    }
 463                }
 432464            }
 465
 432466            if (instant)
 467            {
 431468                int rootEntitiesCount = rootEntities.Count;
 1850469                for (int i = 0; i < rootEntitiesCount; i++)
 470                {
 494471                    IDCLEntity entity = rootEntities[i];
 494472                    RemoveEntity(entity.entityId, instant);
 473                }
 474
 431475                entities.Clear();
 476
 477                // TODO: Does it make sense that 'RemoveAllEntities()' destroys the whole scene GameObject?
 431478                if (gameObject != null)
 431479                    Destroy(gameObject);
 480            }
 432481        }
 482
 862483        private void RemoveAllEntitiesImmediate() { RemoveAllEntities(instant: true); }
 484
 485        public void SetEntityParent(long entityId, long parentId)
 486        {
 17487            if (entityId == parentId)
 488            {
 0489                return;
 490            }
 491
 17492            IDCLEntity me = GetEntityById(entityId);
 493
 17494            if (me == null)
 0495                return;
 496
 17497            Environment.i.platform.cullingController.MarkDirty();
 17498            Environment.i.platform.physicsSyncController.MarkDirty();
 499
 17500            DataStore_World worldData = DataStore.i.Get<DataStore_World>();
 17501            Transform avatarTransform = worldData.avatarTransform.Get();
 17502            Transform firstPersonCameraTransform = worldData.fpsTransform.Get();
 503
 504            // CONST_THIRD_PERSON_CAMERA_ENTITY_REFERENCE is for compatibility purposes
 17505            if (parentId == (long) SpecialEntityId.FIRST_PERSON_CAMERA_ENTITY_REFERENCE ||
 506                parentId == (long) SpecialEntityId.THIRD_PERSON_CAMERA_ENTITY_REFERENCE)
 507            {
 1508                if (firstPersonCameraTransform == null)
 509                {
 0510                    Debug.LogError("FPS transform is null when trying to set parent! " + sceneData.id);
 0511                    return;
 512                }
 513
 514                // In this case, the entity will attached to the first person camera
 515                // On first person mode, the entity will rotate with the camera. On third person mode, the entity will r
 1516                me.SetParent(null);
 1517                me.gameObject.transform.SetParent(firstPersonCameraTransform, false);
 1518                Environment.i.world.sceneBoundsChecker.RemoveEntity(me, removeIfPersistent: true, resetState: true);
 1519                Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked(me, isPersistent: true, runPreliminaryEvalua
 1520                return;
 521            }
 522
 16523            if (parentId == (long) SpecialEntityId.AVATAR_ENTITY_REFERENCE ||
 524                parentId == (long) SpecialEntityId
 525                    .AVATAR_POSITION_REFERENCE) // AvatarPositionEntityReference is for compatibility purposes
 526            {
 1527                if (avatarTransform == null)
 528                {
 0529                    Debug.LogError("Avatar transform is null when trying to set parent! " + sceneData.id);
 0530                    return;
 531                }
 532
 533                // In this case, the entity will be attached to the avatar
 534                // It will simply rotate with the avatar, regardless of where the camera is pointing
 1535                me.SetParent(null);
 1536                me.gameObject.transform.SetParent(avatarTransform, false);
 1537                Environment.i.world.sceneBoundsChecker.RemoveEntity(me, removeIfPersistent: true, resetState: true);
 1538                Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked(me, isPersistent: true, runPreliminaryEvalua
 1539                return;
 540            }
 541
 542            // Remove from persistent checks if it was formerly added as child of avatarTransform or fpsTransform
 15543            if (me.gameObject.transform.parent == avatarTransform ||
 544                me.gameObject.transform.parent == firstPersonCameraTransform)
 545            {
 2546                if (Environment.i.world.sceneBoundsChecker.WasAddedAsPersistent(me))
 2547                    Environment.i.world.sceneBoundsChecker.RemoveEntity(me, removeIfPersistent: true);
 548            }
 549
 15550            if (parentId == (long) SpecialEntityId.SCENE_ROOT_ENTITY)
 551            {
 552                // The entity will be child of the scene directly
 2553                me.SetParent(null);
 2554                me.gameObject.transform.SetParent(gameObject.transform, false);
 2555            }
 556            else
 557            {
 13558                IDCLEntity myParent = GetEntityById(parentId);
 559
 13560                if (myParent != null)
 561                {
 13562                    me.SetParent(myParent);
 563                }
 564            }
 565
 566            // After reparenting the Entity may end up outside the scene boundaries
 15567            Environment.i.world.sceneBoundsChecker?.AddEntityToBeChecked(me, runPreliminaryEvaluation: true);
 15568        }
 569
 570        protected virtual void SendMetricsEvent()
 571        {
 7840572            if (Time.frameCount % 10 == 0)
 759573                metricsCounter.SendEvent();
 7840574        }
 575
 576        public IDCLEntity GetEntityById(long entityId)
 577        {
 962578            if (!entities.TryGetValue(entityId, out IDCLEntity entity))
 579            {
 2580                return null;
 581            }
 582
 583            //NOTE(Brian): This is for removing stray null references? This should never happen.
 584            //             Maybe move to a different 'clean-up' method to make this method have a single responsibility?
 960585            if (entity == null || entity.gameObject == null)
 586            {
 0587                entities.Remove(entityId);
 0588                return null;
 589            }
 590
 960591            return entity;
 592        }
 593
 594        public string GetStateString()
 595        {
 1032596            string baseState = isPersistent ? "global-scene" : "scene";
 1032597            switch (sceneLifecycleHandler.state)
 598            {
 599                case SceneLifecycleHandler.State.NOT_READY:
 0600                    return $"{baseState}:{prettyName} - not ready...";
 601                case SceneLifecycleHandler.State.WAITING_FOR_INIT_MESSAGES:
 532602                    return $"{baseState}:{prettyName} - waiting for init messages...";
 603                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 0604                    return $"{baseState}:{prettyName} - {sceneLifecycleHandler.sceneResourcesLoadTracker.GetStateString(
 605                case SceneLifecycleHandler.State.READY:
 500606                    return $"{baseState}:{prettyName} - ready!";
 607            }
 608
 0609            return $"scene:{prettyName} - no state?";
 610        }
 611
 612        public void RefreshLoadingState()
 613        {
 614#if UNITY_STANDALONE || UNITY_EDITOR
 1032615            if (DataStore.i.common.isApplicationQuitting.Get())
 0616                return;
 617#endif
 618
 1032619            CalculateSceneLoadingState();
 620
 621#if UNITY_EDITOR
 1032622            gameObject.name = GetStateString();
 623#endif
 1032624        }
 625
 626        [ContextMenu("Get Waiting Components Debug Info")]
 627        public void GetWaitingComponentsDebugInfo()
 628        {
 0629            switch (sceneLifecycleHandler.state)
 630            {
 631                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 0632                    sceneLifecycleHandler.sceneResourcesLoadTracker.PrintWaitingResourcesDebugInfo();
 0633                    break;
 634
 635                default:
 0636                    Debug.Log($"The scene {sceneData.id} is not waiting for any components. Its current state is " + sce
 637                    break;
 638            }
 0639        }
 640
 641        /// <summary>
 642        /// Calculates the current loading progress of the scene and raise the event OnLoadingStateUpdated with the perc
 643        /// </summary>
 644        public void CalculateSceneLoadingState()
 645        {
 1032646            loadingProgress = 0f;
 647
 1032648            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS ||
 649                sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY)
 650            {
 500651                loadingProgress = sceneLifecycleHandler.loadingProgress;
 652            }
 653
 1032654            OnLoadingStateUpdated?.Invoke(loadingProgress);
 0655        }
 656    }
 657}

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