< 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:48
Coverable lines:293
Total lines:647
Line coverage:83.6% (245 of 293)
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%6200%
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]
 53617        private bool renderOuterBoundsGizmo = true;
 18
 90319        public Dictionary<long, IDCLEntity> entities { get; private set; } = new Dictionary<long, IDCLEntity>();
 324620        public IECSComponentsManagerLegacy componentsManagerLegacy { get; private set; }
 303821        public LoadParcelScenesMessage.UnityParcelScene sceneData { get; protected set; }
 22
 53623        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
 15330        public ContentProvider contentProvider { get; set; }
 31
 032        public bool isTestScene { get; set; } = false;
 193733        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]
 53640        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        {
 53654            CommonScriptableObjects.worldOffset.OnChange += OnWorldReposition;
 53655            componentsManagerLegacy = new ECSComponentsManagerLegacy(this);
 53656            sceneLifecycleHandler = new SceneLifecycleHandler(this);
 53657            metricsCounter = new SceneMetricsCounter(DataStore.i.sceneWorldObjects);
 53658        }
 59
 60        private void OnDestroy()
 61        {
 53662            CommonScriptableObjects.worldOffset.OnChange -= OnWorldReposition;
 53663            metricsCounter?.Dispose();
 53664            crdtExecutor?.Dispose();
 065        }
 66
 108067        void OnDisable() { metricsCounter?.Disable(); }
 68
 69        private void Update()
 70        {
 845171            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY
 72                && CommonScriptableObjects.rendererState.Get())
 778373                SendMetricsEvent();
 845174        }
 75
 102676        protected virtual string prettyName => sceneData.basePosition.ToString();
 77
 78        public virtual void SetData(LoadParcelScenesMessage.UnityParcelScene data)
 79        {
 52980            Assert.IsTrue( !string.IsNullOrEmpty(data.id), "Scene must have an ID!" );
 81
 52982            this.sceneData = data;
 83
 52984            contentProvider = new ContentProvider();
 52985            contentProvider.baseUrl = data.baseUrl;
 52986            contentProvider.contents = data.contents;
 52987            contentProvider.BakeHashes();
 88
 52989            SetupPositionAndParcels();
 90
 52991            DataStore.i.sceneWorldObjects.AddScene(sceneData.id);
 92
 52993            metricsCounter.Configure(sceneData.id, sceneData.basePosition, sceneData.parcels.Length);
 52994            metricsCounter.Enable();
 95
 52996            OnSetData?.Invoke(data);
 52997        }
 98
 99        void SetupPositionAndParcels()
 100        {
 529101            gameObject.transform.position = PositionUtils.WorldToUnityPosition(Utils.GridToWorldPosition(sceneData.baseP
 102
 529103            parcels.Clear();
 104
 105            // The scene's gameobject position should already be in 'unityposition'
 529106            Vector3 baseParcelWorldPos = gameObject.transform.position;
 107
 529108            outerBounds.SetMinMax(new Vector3(baseParcelWorldPos.x, 0f, baseParcelWorldPos.z),
 109                new Vector3(baseParcelWorldPos.x + ParcelSettings.PARCEL_SIZE, 0f, baseParcelWorldPos.z + ParcelSettings
 110
 2148111            for (int i = 0; i < sceneData.parcels.Length; i++)
 112            {
 113                // 1. Update outer bounds with parcel's size
 545114                var parcel = sceneData.parcels[i];
 115
 545116                Vector3 parcelWorldPos = PositionUtils.WorldToUnityPosition(Utils.GridToWorldPosition(parcel.x, parcel.y
 545117                outerBounds.Encapsulate(new Vector3(parcelWorldPos.x, 0, parcelWorldPos.z));
 545118                outerBounds.Encapsulate(new Vector3(parcelWorldPos.x + ParcelSettings.PARCEL_SIZE, 0, parcelWorldPos.z +
 119
 120                // 2. add parcel to collection
 545121                parcels.Add(parcel);
 122            }
 123
 124            // Apply outer bounds extra threshold
 529125            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
 529127        }
 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        {
 411149            if (EnvironmentSettings.DEBUG && sceneData.parcels != null && sceneDebugPlane == null)
 150            {
 409151                sceneDebugPlane = new SceneDebugPlane(sceneData, gameObject.transform);
 152            }
 411153        }
 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        {
 445166            if (isReleased || gameObject == null)
 0167                return;
 168
 445169            if (sceneDebugPlane != null)
 170            {
 409171                sceneDebugPlane.Dispose();
 409172                sceneDebugPlane = null;
 173            }
 174
 445175            componentsManagerLegacy.DisposeAllSceneComponents();
 176
 445177            if (crdtExecutor != null)
 178            {
 0179                crdtExecutor.Dispose();
 0180                crdtExecutor = null;
 181            }
 182
 445183            if (immediate) //!CommonScriptableObjects.rendererState.Get())
 184            {
 428185                RemoveAllEntitiesImmediate();
 428186                PoolManager.i.Cleanup(true, true);
 428187                DataStore.i.sceneWorldObjects.RemoveScene(sceneData.id);
 428188            }
 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
 445206            isReleased = true;
 445207        }
 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
 943216        public HashSet<Vector2Int> GetParcels() => parcels;
 217        public bool IsInsideSceneBoundaries(Bounds objectBounds)
 218        {
 97219            if (isPersistent)
 13220                return true;
 221
 84222            if (!IsInsideSceneBoundaries(objectBounds.min + CommonScriptableObjects.worldOffset, objectBounds.max.y))
 54223                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        {
 128232            if (isPersistent)
 111233                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        {
 151248            if (isPersistent)
 0249                return true;
 250
 151251            if (parcels.Count == 0)
 0252                return false;
 253
 151254            float heightLimit = metricsCounter.maxCount.sceneHeight;
 151255            if (height > heightLimit)
 10256                return false;
 257
 141258            int noThresholdZCoordinate = Mathf.FloorToInt(worldPosition.z / ParcelSettings.PARCEL_SIZE);
 141259            int noThresholdXCoordinate = Mathf.FloorToInt(worldPosition.x / ParcelSettings.PARCEL_SIZE);
 260
 261            // We check the target world position
 141262            Vector2Int targetCoordinate = new Vector2Int(noThresholdXCoordinate, noThresholdZCoordinate);
 141263            if (parcels.Contains(targetCoordinate))
 79264                return true;
 265
 266            // We need to check using a threshold from the target point, in order to cover correctly the parcel "border/
 62267            Vector2Int coordinateMin = new Vector2Int();
 62268            coordinateMin.x = Mathf.FloorToInt((worldPosition.x - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 62269            coordinateMin.y = Mathf.FloorToInt((worldPosition.z - ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 270
 62271            Vector2Int coordinateMax = new Vector2Int();
 62272            coordinateMax.x = Mathf.FloorToInt((worldPosition.x + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 62273            coordinateMax.y = Mathf.FloorToInt((worldPosition.z + ParcelSettings.PARCEL_BOUNDARIES_THRESHOLD) / ParcelSe
 274
 275            // We check the east/north-threshold position
 62276            targetCoordinate.Set(coordinateMax.x, coordinateMax.y);
 62277            if (parcels.Contains(targetCoordinate))
 0278                return true;
 279
 280            // We check the east/south-threshold position
 62281            targetCoordinate.Set(coordinateMax.x, coordinateMin.y);
 62282            if (parcels.Contains(targetCoordinate))
 0283                return true;
 284
 285            // We check the west/north-threshold position
 62286            targetCoordinate.Set(coordinateMin.x, coordinateMax.y);
 62287            if (parcels.Contains(targetCoordinate))
 0288                return true;
 289
 290            // We check the west/south-threshold position
 62291            targetCoordinate.Set(coordinateMin.x, coordinateMin.y);
 62292            if (parcels.Contains(targetCoordinate))
 0293                return true;
 294
 62295            return false;
 296        }
 297
 298        public bool IsInsideSceneOuterBoundaries(Bounds objectBounds)
 299        {
 146300            if (isPersistent)
 0301                return true;
 302
 146303            Vector3 objectBoundsMin = new Vector3(objectBounds.min.x, 0f, objectBounds.min.z);
 146304            Vector3 objectBoundsMax = new Vector3(objectBounds.max.x, 0f, objectBounds.max.z);
 146305            bool isInsideOuterBoundaries = outerBounds.Contains(objectBoundsMin) && outerBounds.Contains(objectBoundsMax
 306
 82307            return isInsideOuterBoundaries;
 308        }
 309
 310        public bool IsInsideSceneOuterBoundaries(Vector3 objectUnityPosition)
 311        {
 171312            if (isPersistent)
 0313                return true;
 314
 171315            objectUnityPosition.y = 0f;
 171316            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);
 0325        }
 326
 0327        public IDCLEntity GetEntityById(string entityId) { throw new System.NotImplementedException(); }
 58328        public Transform GetSceneTransform() { return transform; }
 329
 330        public IDCLEntity CreateEntity(long id)
 331        {
 605332            if (entities.ContainsKey(id))
 333            {
 2334                return entities[id];
 335            }
 336
 603337            var newEntity = new DecentralandEntity();
 603338            newEntity.entityId = id;
 339
 603340            PoolManagerFactory.EnsureEntityPool(false);
 341
 342            // As we know that the pool already exists, we just get one gameobject from it
 603343            PoolableObject po = PoolManager.i.Get(PoolManagerFactory.EMPTY_GO_POOL_NAME);
 344
 603345            newEntity.meshesInfo.innerGameObject = po.gameObject;
 603346            newEntity.gameObject = po.gameObject;
 347
 348#if UNITY_EDITOR
 603349            newEntity.gameObject.name = "ENTITY_" + id;
 350#endif
 603351            newEntity.gameObject.transform.SetParent(gameObject.transform, false);
 603352            newEntity.gameObject.SetActive(true);
 603353            newEntity.scene = this;
 354
 603355            newEntity.OnCleanupEvent += po.OnCleanup;
 356
 603357            if (Environment.i.world.sceneBoundsChecker.enabled)
 450358                newEntity.OnShapeUpdated += OnEntityShapeUpdated;
 359
 603360            entities.Add(id, newEntity);
 361
 603362            DataStore.i.sceneWorldObjects.sceneData[sceneData.id].owners.Add(id);
 363
 603364            OnEntityAdded?.Invoke(newEntity);
 365
 603366            Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked(newEntity, runPreliminaryEvaluation: true);
 367
 603368            return newEntity;
 369        }
 370
 371        void OnEntityShapeUpdated(IDCLEntity entity)
 372        {
 223373            Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked(entity, runPreliminaryEvaluation: true);
 223374        }
 375
 376        public void RemoveEntity(long id, bool removeImmediatelyFromEntitiesList = true)
 377        {
 523378            if (entities.ContainsKey(id))
 379            {
 523380                IDCLEntity entity = entities[id];
 381
 523382                if (!entity.markedForCleanup)
 383                {
 384                    // This will also cleanup its children
 523385                    CleanUpEntityRecursively(entity, removeImmediatelyFromEntitiesList);
 386                }
 387
 523388                entities.Remove(id);
 389
 523390                var data = DataStore.i.sceneWorldObjects.sceneData;
 391
 523392                if (data.ContainsKey(sceneData.id))
 393                {
 68394                    data[sceneData.id].owners.Remove(id);
 395                }
 68396            }
 397#if UNITY_EDITOR || DEVELOPMENT_BUILD
 398            else
 399            {
 0400                Debug.LogWarning($"Couldn't remove entity with ID: {id} as it doesn't exist.");
 401            }
 402#endif
 455403        }
 404
 405        void CleanUpEntityRecursively(IDCLEntity entity, bool removeImmediatelyFromEntitiesList)
 406        {
 532407            using (var iterator = entity.children.GetEnumerator())
 408            {
 541409                while (iterator.MoveNext())
 410                {
 9411                    CleanUpEntityRecursively(iterator.Current.Value, removeImmediatelyFromEntitiesList);
 412                }
 532413            }
 414
 532415            OnEntityRemoved?.Invoke(entity);
 416
 532417            if (Environment.i.world.sceneBoundsChecker.enabled)
 418            {
 447419                entity.OnShapeUpdated -= OnEntityShapeUpdated;
 447420                Environment.i.world.sceneBoundsChecker.RemoveEntity(entity, removeIfPersistent: true, resetState: true);
 421            }
 422
 532423            if (removeImmediatelyFromEntitiesList)
 424            {
 425                // Every entity ends up being removed through here
 531426                entity.Cleanup();
 531427                entities.Remove(entity.entityId);
 531428            }
 429            else
 430            {
 1431                Environment.i.platform.parcelScenesCleaner.MarkForCleanup(entity);
 432            }
 1433        }
 434
 435        void RemoveAllEntities(bool instant = false)
 436        {
 437            //NOTE(Brian): We need to remove only the rootEntities.
 438            //             If we don't, duplicated entities will get removed when destroying
 439            //             recursively, making this more complicated than it should.
 429440            List<IDCLEntity> rootEntities = new List<IDCLEntity>();
 441
 429442            using (var iterator = entities.GetEnumerator())
 443            {
 929444                while (iterator.MoveNext())
 445                {
 500446                    if (iterator.Current.Value.parent == null)
 447                    {
 492448                        if (instant)
 491449                            rootEntities.Add(iterator.Current.Value);
 450                        else
 1451                            Environment.i.platform.parcelScenesCleaner.MarkRootEntityForCleanup(this, iterator.Current.V
 452                    }
 453                }
 429454            }
 455
 429456            if (instant)
 457            {
 428458                int rootEntitiesCount = rootEntities.Count;
 1838459                for (int i = 0; i < rootEntitiesCount; i++)
 460                {
 491461                    IDCLEntity entity = rootEntities[i];
 491462                    RemoveEntity(entity.entityId, instant);
 463                }
 464
 428465                entities.Clear();
 466
 467                // TODO: Does it make sense that 'RemoveAllEntities()' destroys the whole scene GameObject?
 428468                if (gameObject != null)
 428469                    Destroy(gameObject);
 470            }
 429471        }
 472
 856473        private void RemoveAllEntitiesImmediate() { RemoveAllEntities(instant: true); }
 474
 475        public void SetEntityParent(long entityId, long parentId)
 476        {
 17477            if (entityId == parentId)
 478            {
 0479                return;
 480            }
 481
 17482            IDCLEntity me = GetEntityById(entityId);
 483
 17484            if (me == null)
 0485                return;
 486
 17487            Environment.i.platform.cullingController.MarkDirty();
 17488            Environment.i.platform.physicsSyncController.MarkDirty();
 489
 17490            DataStore_World worldData = DataStore.i.Get<DataStore_World>();
 17491            Transform avatarTransform = worldData.avatarTransform.Get();
 17492            Transform firstPersonCameraTransform = worldData.fpsTransform.Get();
 493
 494            // CONST_THIRD_PERSON_CAMERA_ENTITY_REFERENCE is for compatibility purposes
 17495            if (parentId == (long) SpecialEntityId.FIRST_PERSON_CAMERA_ENTITY_REFERENCE ||
 496                parentId == (long) SpecialEntityId.THIRD_PERSON_CAMERA_ENTITY_REFERENCE)
 497            {
 1498                if (firstPersonCameraTransform == null)
 499                {
 0500                    Debug.LogError("FPS transform is null when trying to set parent! " + sceneData.id);
 0501                    return;
 502                }
 503
 504                // In this case, the entity will attached to the first person camera
 505                // On first person mode, the entity will rotate with the camera. On third person mode, the entity will r
 1506                me.SetParent(null);
 1507                me.gameObject.transform.SetParent(firstPersonCameraTransform, false);
 1508                Environment.i.world.sceneBoundsChecker.RemoveEntity(me, removeIfPersistent: true, resetState: true);
 1509                Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked(me, isPersistent: true, runPreliminaryEvalua
 1510                return;
 511            }
 512
 16513            if (parentId == (long) SpecialEntityId.AVATAR_ENTITY_REFERENCE ||
 514                parentId == (long) SpecialEntityId
 515                    .AVATAR_POSITION_REFERENCE) // AvatarPositionEntityReference is for compatibility purposes
 516            {
 1517                if (avatarTransform == null)
 518                {
 0519                    Debug.LogError("Avatar transform is null when trying to set parent! " + sceneData.id);
 0520                    return;
 521                }
 522
 523                // In this case, the entity will be attached to the avatar
 524                // It will simply rotate with the avatar, regardless of where the camera is pointing
 1525                me.SetParent(null);
 1526                me.gameObject.transform.SetParent(avatarTransform, false);
 1527                Environment.i.world.sceneBoundsChecker.RemoveEntity(me, removeIfPersistent: true, resetState: true);
 1528                Environment.i.world.sceneBoundsChecker.AddEntityToBeChecked(me, isPersistent: true, runPreliminaryEvalua
 1529                return;
 530            }
 531
 532            // Remove from persistent checks if it was formerly added as child of avatarTransform or fpsTransform
 15533            if (me.gameObject.transform.parent == avatarTransform ||
 534                me.gameObject.transform.parent == firstPersonCameraTransform)
 535            {
 2536                if (Environment.i.world.sceneBoundsChecker.WasAddedAsPersistent(me))
 2537                    Environment.i.world.sceneBoundsChecker.RemoveEntity(me, removeIfPersistent: true);
 538            }
 539
 15540            if (parentId == (long) SpecialEntityId.SCENE_ROOT_ENTITY)
 541            {
 542                // The entity will be child of the scene directly
 2543                me.SetParent(null);
 2544                me.gameObject.transform.SetParent(gameObject.transform, false);
 2545            }
 546            else
 547            {
 13548                IDCLEntity myParent = GetEntityById(parentId);
 549
 13550                if (myParent != null)
 551                {
 13552                    me.SetParent(myParent);
 553                }
 554            }
 555
 556            // After reparenting the Entity may end up outside the scene boundaries
 15557            Environment.i.world.sceneBoundsChecker?.AddEntityToBeChecked(me, runPreliminaryEvaluation: true);
 15558        }
 559
 560        protected virtual void SendMetricsEvent()
 561        {
 7783562            if (Time.frameCount % 10 == 0)
 782563                metricsCounter.SendEvent();
 7783564        }
 565
 566        public IDCLEntity GetEntityById(long entityId)
 567        {
 955568            if (!entities.TryGetValue(entityId, out IDCLEntity entity))
 569            {
 2570                return null;
 571            }
 572
 573            //NOTE(Brian): This is for removing stray null references? This should never happen.
 574            //             Maybe move to a different 'clean-up' method to make this method have a single responsibility?
 953575            if (entity == null || entity.gameObject == null)
 576            {
 0577                entities.Remove(entityId);
 0578                return null;
 579            }
 580
 953581            return entity;
 582        }
 583
 584        public string GetStateString()
 585        {
 1026586            string baseState = isPersistent ? "global-scene" : "scene";
 1026587            switch (sceneLifecycleHandler.state)
 588            {
 589                case SceneLifecycleHandler.State.NOT_READY:
 0590                    return $"{baseState}:{prettyName} - not ready...";
 591                case SceneLifecycleHandler.State.WAITING_FOR_INIT_MESSAGES:
 529592                    return $"{baseState}:{prettyName} - waiting for init messages...";
 593                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 0594                    return $"{baseState}:{prettyName} - {sceneLifecycleHandler.sceneResourcesLoadTracker.GetStateString(
 595                case SceneLifecycleHandler.State.READY:
 497596                    return $"{baseState}:{prettyName} - ready!";
 597            }
 598
 0599            return $"scene:{prettyName} - no state?";
 600        }
 601
 602        public void RefreshLoadingState()
 603        {
 604#if UNITY_STANDALONE || UNITY_EDITOR
 1026605            if (DataStore.i.common.isApplicationQuitting.Get())
 0606                return;
 607#endif
 608
 1026609            CalculateSceneLoadingState();
 610
 611#if UNITY_EDITOR
 1026612            gameObject.name = GetStateString();
 613#endif
 1026614        }
 615
 616        [ContextMenu("Get Waiting Components Debug Info")]
 617        public void GetWaitingComponentsDebugInfo()
 618        {
 0619            switch (sceneLifecycleHandler.state)
 620            {
 621                case SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS:
 0622                    sceneLifecycleHandler.sceneResourcesLoadTracker.PrintWaitingResourcesDebugInfo();
 0623                    break;
 624
 625                default:
 0626                    Debug.Log($"The scene {sceneData.id} is not waiting for any components. Its current state is " + sce
 627                    break;
 628            }
 0629        }
 630
 631        /// <summary>
 632        /// Calculates the current loading progress of the scene and raise the event OnLoadingStateUpdated with the perc
 633        /// </summary>
 634        public void CalculateSceneLoadingState()
 635        {
 1026636            loadingProgress = 0f;
 637
 1026638            if (sceneLifecycleHandler.state == SceneLifecycleHandler.State.WAITING_FOR_COMPONENTS ||
 639                sceneLifecycleHandler.state == SceneLifecycleHandler.State.READY)
 640            {
 497641                loadingProgress = sceneLifecycleHandler.loadingProgress;
 642            }
 643
 1026644            OnLoadingStateUpdated?.Invoke(loadingProgress);
 0645        }
 646    }
 647}

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