void LeavePlayingState()
    {
        //Game.game.clientFrontend.Clear();

        PrefabAssetManager.DestroyEntity(m_GameWorld.EntityManager, m_LocalPlayer);
        m_LocalPlayer = Entity.Null;

        m_clientWorld.Shutdown();
        m_clientWorld = null;

        // TODO (petera) replace this with a stack of levels or similar thing. For now we just load the menu no matter what
        //Game.game.levelManager.UnloadLevel();
        //Game.game.levelManager.LoadLevel("level_menu");

        PrefabAssetManager.Shutdown();
#pragma warning disable 618
        // we're keeping World.Active until we can properly remove them all
        // FIXME: not compatible with dots netcode
        m_GameWorld = World.Active;
        World.Active.CreateSystem <GameTimeSystem>();
#pragma warning restore 618

        //Game.game.clientFrontend.ShowMenu(ClientFrontend.MenuShowing.None);

        //Game.game.levelManager.LoadLevel("level_menu");

        GameDebug.Log("Left playingstate");
    }
        protected override JobHandle OnUpdate(JobHandle inputDependencies)
        {
            inputDependencies.Complete();

            Entities
            .WithStructuralChanges()
            .WithNone <CameraEntity>()
            .WithAll <PlayerCameraControl.State>()
            .ForEach((Entity entity) =>
            {
                var cameraEntity = PrefabAssetManager.CreateEntity(World, m_cameraPrefab);

                var camera     = EntityManager.GetComponentObject <Camera>(cameraEntity);
                camera.enabled = false;

                var audioListener     = EntityManager.GetComponentObject <AudioListener>(cameraEntity);
                audioListener.enabled = false;

                EntityManager.AddComponentData(entity, new CameraEntity
                {
                    Value = cameraEntity,
                });
            }).Run();

            return(default);
    protected override void OnUpdate()
    {
        var requestArray = DespawnGroup.ToComponentDataArray <CharacterDespawnRequest>(Allocator.Persistent);

        if (requestArray.Length == 0)
        {
            requestArray.Dispose();
            return;
        }

        Profiler.BeginSample("HandleCharacterDespawnRequests");

        var requestEntityArray = DespawnGroup.ToEntityArray(Allocator.Persistent);

        for (var i = 0; i < requestArray.Length; i++)
        {
            var request = requestArray[i];

            GameDebug.Assert(EntityManager.HasComponent <Character.State>(request.characterEntity), "Character despawn requst entity is not a character");

            Inventory.Server_DestroyAll(EntityManager, PostUpdateCommands, request.characterEntity);

            GameDebug.Log(World, Character.ShowLifetime, "Despawning character:{0}", request.characterEntity);

            PrefabAssetManager.DestroyEntity(EntityManager, request.characterEntity);
            PostUpdateCommands.DestroyEntity(requestEntityArray[i]);
            if (Character.ShowLifetime.IntValue > 0)
            {
                AnimationGraphHelper.DumpState(World);
            }
        }
        requestEntityArray.Dispose();
        requestArray.Dispose();
        Profiler.EndSample();
    }
Exemple #4
0
 private void CmdDespawnBoxes(string[] args)
 {
     foreach (var box in m_Movables)
     {
         PrefabAssetManager.DestroyEntity(m_GameWorld.EntityManager, box);
     }
     m_Movables.Clear();
 }
Exemple #5
0
        protected override JobHandle OnUpdate(JobHandle inputDependencies)
        {
            inputDependencies.Complete();

            var animGraphSys = World.GetExistingSystem <AnimationGraphSystem>();

            // Initialize
            Entities
            .WithStructuralChanges()
            .WithNone <LOD>()
            .WithAll <Settings>()
            .ForEach((Entity entity) =>
            {
                GameDebug.Log(World, ShowLifetime, "InitSys: Initialize DotsAnimStateCtrl:{0}", entity);

                // Setup lowest LOD rig
                var rigDataBuffer = EntityManager.GetBuffer <RigData>(entity);
//                var lowestLod = rigDataBuffer.Length - 1;
                // TODO (mogensh) for now we only use Rig LOD for selecting low lod on server
                var isServer = World.GetExistingSystem <ServerSimulationSystemGroup>() != null;// TODO (mogensh) cant we find better way to test for server?
                var lod      = isServer ? 1 : 0;
                var rigData  = rigDataBuffer[lod];
                RigEntityBuilder.SetupRigEntity(entity, EntityManager, rigData.Rig);

                var animLocalToRigBuffer = EntityManager.AddBuffer <AnimatedLocalToRig>(entity);
                animLocalToRigBuffer.ResizeUninitialized(rigData.Rig.Value.Skeleton.Ids.Length);

                // Create root animsource
                var settings             = EntityManager.GetComponentData <Settings>(entity);
                var rootAnimSourceEntity = PrefabAssetManager.CreateEntity(EntityManager, settings.RootAnimSource);
#if UNITY_EDITOR
                var name = EntityManager.GetName(rootAnimSourceEntity) + " -> Entity " + entity.Index + ".DotsAnimStateController.RootAnimSource";
                EntityManager.SetName(rootAnimSourceEntity, name);
#endif
                AnimSource.SetAnimStateEntityOnPrefab(EntityManager, rootAnimSourceEntity, entity);

                var rootAnimSource   = RootAnimSource.Default;
                rootAnimSource.Value = rootAnimSourceEntity;
                EntityManager.AddComponentData(entity, rootAnimSource);

                EntityManager.AddComponentData(entity, new LOD {
                    Value = lod,
                });
            }).Run();


            // Deinitialize
            Entities
            .WithStructuralChanges()
            .WithNone <Settings>()
            .WithAll <LOD>()
            .ForEach((Entity entity, ref RootAnimSource rootAnimSource, ref OutputNode outputNode, ref GraphOutput graphOutput) =>
            {
                Deinitialize(EntityManager, entity, animGraphSys);
            }).Run();

            return(default);
Exemple #6
0
    public static void Server_DestroyAll(EntityManager entityManager, EntityCommandBuffer cmdBuffer, Entity inventoryEntity)
    {
        var slots = entityManager.GetBuffer <ItemEntry>(inventoryEntity);

        for (int j = 0; j < slots.Length; j++)
        {
            GameDebug.Assert(entityManager.Exists(slots[j].entity));
            PrefabAssetManager.DestroyEntity(cmdBuffer, slots[j].entity);
        }
        slots.Clear();
    }
    public void Shutdown()
    {
        GameDebug.Log("ClientGameLoop shutdown");
        Console.RemoveCommandsWithTag(this.GetHashCode());

        m_StateMachine.Shutdown();

        m_NetworkClient.Shutdown();

        PrefabAssetManager.Shutdown();
        m_Transport.Shutdown();
    }
    public Entity CreatePlayerEntity(World world, int playerId, int teamIndex, string playerName, bool isReady)
    {
        var playerEntity = PrefabAssetManager.CreateEntity(m_world.EntityManager, m_settings.playerStatePrefab);

        var playerState = world.EntityManager.GetComponentData <Player.State>(playerEntity);

        playerState.playerId = playerId;
        //playerState.playerName = new NativeString64(playerName);
        //playerState.teamIndex = teamIndex;
        world.EntityManager.SetComponentData(playerEntity, playerState);

        return(playerEntity);
    }
Exemple #9
0
    protected override void OnCreate()
    {
        base.OnCreate();
        playersComponentGroup      = GetEntityQuery(typeof(Player.State));
        m_SpawnPointComponentGroup = GetEntityQuery(typeof(SpawnPoint.State));
        m_PlayersComponentGroup    = GetEntityQuery(typeof(Player.State), typeof(PlayerCharacterControl.State));

        // Create game mode state

        //gameModeEntity = PrefabAssetManager.CreateEntity(World, RepEntityType.GameMode);
        var reg = EntityManager.GetComponentData <GlobalAssetRegistry>(GetEntityQuery(typeof(GlobalAssetRegistry)).GetSingletonEntity());

        gameModeEntity = PrefabAssetManager.CreateEntity(World.EntityManager, reg.gameModePrefab);
    }
Exemple #10
0
    public Entity SpawnCharacter(int playerId, Vector3 position, Quaternion rotation,
                                 int heroIndex)
    {
        var heroRegistry = HeroRegistry.GetRegistry(EntityManager);
        var heroCount    = heroRegistry.Value.Heroes.Length;

        heroIndex = Mathf.Clamp(heroIndex, 0, heroCount - 1);

        var charEntity = PrefabAssetManager.CreateEntity(EntityManager, heroRegistry.Value.Heroes[heroIndex].characterPrefab);

        var charSettings = EntityManager.GetComponentData <Character.Settings>(charEntity);

        Character.TeleportTo(ref charSettings, position, rotation);
        PostUpdateCommands.SetComponent(charEntity, charSettings);

        var charRepAll = EntityManager.GetComponentData <Character.ReplicatedData>(charEntity);

        charRepAll.heroTypeIndex = heroIndex;
        PostUpdateCommands.SetComponent(charEntity, charRepAll);
        PostUpdateCommands.SetComponent(charEntity, new Player.OwnerPlayerId
        {
            Value = playerId,
        });

        // TODO (mogensh) move this to inventory code (server part)
        // Spawn items in inventory
        var itemCount = heroRegistry.Value.Heroes[heroIndex].Items.Length;

        for (int nItem = 0; nItem < itemCount; nItem++)
        {
            var entry = heroRegistry.Value.Heroes[heroIndex].Items[nItem];

            if (!entry.asset.IsSet())
            {
                continue;
            }

            var itemEntity = PrefabAssetManager.CreateEntity(EntityManager, entry.asset);

            var itemState = EntityManager.GetComponentData <Item.InputState>(itemEntity);
            itemState.owner    = charEntity;
            itemState.slot     = entry.slot;
            itemState.playerId = playerId;
            PostUpdateCommands.SetComponent(itemEntity, itemState);
        }

        return(charEntity);
    }
Exemple #11
0
 protected override void OnDestroy()
 {
     Entities.ForEach((Entity e, ref LocalPlayer lp) =>
     {
         if (lp.hudEntity != Entity.Null)
         {
             PrefabAssetManager.DestroyEntity(EntityManager, lp.hudEntity);
         }
     });
     foreach (var e in m_NamePlates)
     {
         if (e != null)
         {
             GameObject.Destroy(e);
         }
     }
 }
Exemple #12
0
    public static BlobAssetReference <PartRegistry.PartRegistryBlob> GetPartRegistry(World world, WeakAssetReference asset)
    {
        var tuple    = new Tuple <World, WeakAssetReference>(world, asset);
        var registry = BlobAssetReference <PartRegistry.PartRegistryBlob> .Null;

        if (g_PartRegistries.TryGetValue(tuple, out registry))
        {
            return(registry);
        }

        var entity           = PrefabAssetManager.CreateEntity(world.EntityManager, asset);
        var partRegistryData = world.EntityManager.GetComponentData <PartRegistryData>(entity);

        registry = partRegistryData.Value;
//        GameDebug.Log("Loaded registry");
        g_PartRegistries.Add(tuple, registry);
        return(registry);
    }
Exemple #13
0
    public void Shutdown()
    {
        Resources.UnloadAsset(m_settings);

        if (World.AllWorlds.Contains(m_world))
        {
            m_world.DestroySystem(m_HandlePlayerCameraControlSpawn);
            m_world.DestroySystem(m_UpdatePlayerCameras);
            m_world.DestroySystem(m_ResolvePlayerCharacterReference);
            m_world.DestroySystem(m_ResolvePlayerReference);
            m_world.DestroySystem(m_UpdateServerEntityComponent);
        }

        if (m_LocalPlayer != Entity.Null)
        {
            PrefabAssetManager.DestroyEntity(m_world.EntityManager, m_LocalPlayer);
        }
    }
Exemple #14
0
    public void Update()
    {
        if (spawnNum <= 0)
        {
            return;
        }
        spawnNum--;

        int x = spawnNum % 10 - 5;
        int z = spawnNum / 10 - 5;

        var movable = PrefabAssetManager.CreateEntity(m_GameWorld.EntityManager, Game.game.movableBoxPrototype);

        var transform = m_GameWorld.EntityManager.GetComponentObject <Transform>(movable);

        transform.position = new Vector3(40 + x * 3, 30, 30 + z * 3);// level_00: new Vector3(-20+x*3,10,-10+z*3)
        transform.rotation = UnityEngine.Random.rotation;

        m_Movables.Add(movable);
    }
Exemple #15
0
    public Entity RegisterLocalPlayer(int playerId)
    {
        m_LocalPlayer = PrefabAssetManager.CreateEntity(m_world.EntityManager, m_settings.localPlayerPrefab);

        var query = m_world.EntityManager.CreateEntityQuery(typeof(ThinClientComponent));

        if (query.CalculateEntityCount() == 1)
        {
            m_world.EntityManager.AddComponent <FakeLocalPlayer>(m_LocalPlayer);
        }
        var localPlayerState = m_world.EntityManager.GetComponentData <LocalPlayer>(m_LocalPlayer);

        localPlayerState.playerId          = playerId;
        localPlayerState.command.lookPitch = 90;

        m_world.EntityManager.SetComponentData(m_LocalPlayer, localPlayerState);

        m_ResolvePlayerReference.SetLocalPlayer(m_LocalPlayer);
        m_world.EntityManager.GetBuffer <UserCommand>(m_LocalPlayer).Clear();
        // Find the correct thing
        var q = m_world.EntityManager.CreateEntityQuery(ComponentType.ReadWrite <CommandTargetComponent>(),
                                                        ComponentType.ReadWrite <NetworkStreamConnection>(), ComponentType.ReadWrite <NetworkIdComponent>());
        var ents = q.ToEntityArray(Allocator.TempJob);
        var ids  = q.ToComponentDataArray <NetworkIdComponent>(Allocator.TempJob);

        for (int i = 0; i < ents.Length; ++i)
        {
            if (ids[i].Value == playerId)
            {
                UnityEngine.Debug.Log("Assign command on client");
                m_world.EntityManager.SetComponentData(ents[i], new CommandTargetComponent {
                    targetEntity = m_LocalPlayer
                });
            }
        }
        ents.Dispose();
        ids.Dispose();
        return(m_LocalPlayer);
    }
    public Entity RegisterLocalPlayer(int playerId)
    {
        // Create player state
        var settings     = Resources.Load <PlayerModuleSettings>("PlayerModuleSettings");
        var playerEntity = PrefabAssetManager.CreateEntity(m_GameWorld.EntityManager, settings.playerStatePrefab);
        var playerState  = m_GameWorld.EntityManager.GetComponentData <Player.State>(playerEntity);

        playerState.playerId   = playerId;
        playerState.playerName = new NativeString64("asdf");
        m_GameWorld.EntityManager.SetComponentData(playerEntity, playerState);


        // Create local player
        m_localPlayer = PrefabAssetManager.CreateEntity(m_GameWorld.EntityManager, settings.localPlayerPrefab);
        var localPlayerState = m_GameWorld.EntityManager.GetComponentData <LocalPlayer>(m_localPlayer);

        localPlayerState.playerId          = playerId;
        localPlayerState.command.lookPitch = 90;
        localPlayerState.playerEntity      = playerEntity;

        m_GameWorld.EntityManager.SetComponentData(m_localPlayer, localPlayerState);

        return(m_localPlayer);
    }
    public void Shutdown()
    {
        m_GameMode.Shutdown();

        PrefabAssetManager.DestroyEntity(m_World.EntityManager, gameModeEntity);
    }
Exemple #18
0
        protected override void OnUpdate()
        {
            // Camera.main may not be available when the system is created, so need this to set it for the first time
            if (MainCamera == null)
            {
                if (Camera.main != null)
                {
                    MainCamera = Camera.main;
                }
                else
                {
                    GameDebug.LogWarning("PartOwner update: No camera.main");
                    return;
                }
            }

            var camPos = (float3)MainCamera.transform.position;

            // TODO: Jobified ForEach blocked by PrefabAssetRegistry.CreateEntity
            Entities.ForEach((Entity partOwnerEntity, ref Translation translation, ref RegistryAsset registryAsset, ref InputState inputState,
                              ref State state) =>
            {
                var registry = PartRegistry.GetPartRegistry(World, registryAsset.Value);

                // Calc lod
                var charPos = translation.Value;
                var dist    = math.distance(camPos, charPos);
                var newLod  = -1;
                // TODO (mogensh) add threshold that needs to be passed before change (so it does not flicker)
                for (int lod = 0; lod < registry.Value.LODLevels.Length; lod++)
                {
                    if (dist <= registry.Value.LODLevels[lod].EndDist)
                    {
                        newLod = lod;
                        break;
                    }
                }


                // TODO (mogensh) hack: force LOD 0
                newLod = 0;


                // Handle out of lod distance specifically
                if (newLod == -1)
                {
                    if (state.currentLOD != newLod)
                    {
                        state.currentLOD = newLod;

                        GameDebug.Log(Part.ShowLifetime, "Out of LOD distance");

                        var partBuf = EntityManager.GetBuffer <PartElement>(partOwnerEntity)
                                      .ToNativeArray(Allocator.Temp);
                        var partOutBuf = PostUpdateCommands.SetBuffer <PartElement>(partOwnerEntity);
                        partOutBuf.ResizeUninitialized(partBuf.Length);
                        for (int j = 0; j < partBuf.Length; j++)
                        {
                            var partElement = partBuf[j];

                            // Destroy old part
                            if (partElement.PartId != 0)
                            {
                                if (partElement.PartEntity != Entity.Null)
                                {
                                    GameDebug.Log(Part.ShowLifetime, "Destroying part. Category:{0} partId:{1}", j,
                                                  partElement.PartId);
                                    PostUpdateCommands.DestroyEntity(partElement.PartEntity);
                                }

                                partElement.PartEntity = Entity.Null;
                                partElement.PartId     = 0;
                                partElement.Asset      = WeakAssetReference.Default;
                            }

                            partOutBuf[j] = partElement;
                        }

                        PostUpdateCommands.SetComponent(partOwnerEntity, state);
                    }


                    return;
                }



                var newRig = BlobAssetReference <RigDefinition> .Null;
                if (EntityManager.HasComponent <SharedRigDefinition>(partOwnerEntity))
                {
                    newRig = EntityManager.GetSharedComponentData <SharedRigDefinition>(partOwnerEntity).Value;
                }


                // Change bodypart if LOD or rig changed
                var packedPartIds = inputState.PackedPartIds;
                if (packedPartIds != state.CurrentPackedPartIds ||
                    newLod != state.currentLOD ||
                    (newRig != BlobAssetReference <RigDefinition> .Null && newRig != state.currentRig))
                {
                    var partBuf = EntityManager.GetBuffer <PartElement>(partOwnerEntity).ToNativeArray(Allocator.Temp);


                    var partIds = new NativeArray <int>(partBuf.Length, Allocator.Temp);
                    registry.Value.UnpackPartsList(inputState.PackedPartIds, partIds);

                    GameDebug.Log(World, Part.ShowLifetime, "Property changed. Lod:{0}", newLod);

                    var partOutBuf = PostUpdateCommands.SetBuffer <PartElement>(partOwnerEntity);
                    partOutBuf.ResizeUninitialized(partBuf.Length);
                    for (int j = 0; j < partBuf.Length; j++)
                    {
                        var partId      = partIds[j];
                        var partElement = partBuf[j];

                        // Find new asset given the new properties
                        var asset = new WeakAssetReference();
                        if (partId > 0)
                        {
                            var skeletonHash = newRig.IsCreated ? newRig.Value.GetHashCode() : 0;
                            var found        = registry.Value.FindAsset(j, partId, skeletonHash, newLod, ref asset);
                            if (!found)
                            {
                                GameDebug.Log(World, Part.ShowLifetime,
                                              "Failed to find valid part. Category:{0} PartId:{1}", j, partId);
                            }
                        }


                        // No change if asset has not changed
                        if (partElement.Asset == asset)
                        {
                            partOutBuf[j] = partElement;
                            continue;
                        }


                        // Destroy old part
                        if (partElement.PartId != 0)
                        {
                            if (partElement.PartEntity != Entity.Null)
                            {
                                GameDebug.Log(World, Part.ShowLifetime, "Destroying part. Category:{0} partId:", j,
                                              partElement.PartId);
                                PostUpdateCommands.DestroyEntity(partElement.PartEntity);
                            }

                            partElement.PartEntity = Entity.Null;
                            partElement.PartId     = 0;
                            partElement.Asset      = WeakAssetReference.Default;
                        }

                        // Create new part
                        if (partId != 0 && asset.IsSet())
                        {
                            partElement.PartEntity = PrefabAssetManager.CreateEntity(EntityManager, asset);
                            partElement.PartId     = partId;
                            partElement.Asset      = asset;

                            if (partElement.PartEntity != Entity.Null)
                            {
                                GameDebug.Log(World, Part.ShowLifetime,
                                              "Creating part. Owner:{0} Cat:{1} PartId:{2} Asset:{3} part:{4}", partOwnerEntity,
                                              j, partId, asset.ToGuidStr(), partElement.PartEntity);
                                var part   = Part.Owner.Default;
                                part.Value = partOwnerEntity;
                                PostUpdateCommands.SetComponent(partElement.PartEntity, part);

                                // TODO (mogensh) add "static" property on owner (or get somehow). If static just set world transform
                                PostUpdateCommands.AddComponent(partElement.PartEntity,
                                                                new Parent {
                                    Value = partOwnerEntity
                                });
                                PostUpdateCommands.AddComponent(partElement.PartEntity, new LocalToParent());
                            }
                            else
                            {
                                GameDebug.LogError("Failed to create part. Asset:" + asset.ToGuidStr());
                            }
                        }

                        partOutBuf[j] = partElement;
                    }

                    state.CurrentPackedPartIds = packedPartIds;
                    state.currentRig           = newRig;
                    state.currentLOD           = newLod;
                    PostUpdateCommands.SetComponent(partOwnerEntity, state);
                }
            });
        }
 public void CleanupPlayer(Entity player)
 {
     PrefabAssetManager.DestroyEntity(m_world.EntityManager, player);
 }
Exemple #20
0
    protected override void OnUpdate()
    {
        // Create and update health UI
        int self_id     = -1;
        int selfTeamIdx = -1;

        Entities.ForEach((Entity e, ref LocalPlayer localPlayer) =>
        {
            self_id = localPlayer.playerId;
            if (localPlayer.hudEntity == Entity.Null)
            {
                localPlayer.hudEntity = PrefabAssetManager.CreateEntity(EntityManager.World, m_Hud.gameObject);
            }

            if (localPlayer.controlledEntity != Entity.Null)
            {
                var h   = EntityManager.GetComponentData <HealthStateData>(localPlayer.controlledEntity);
                var hud = EntityManager.GetComponentObject <IngameHUD>(localPlayer.hudEntity);
                hud.FrameUpdate();
                hud.m_Health.UpdateUI(ref h);
            }

            // Store our team idx for nameplate coloring below
            if (EntityManager.Exists(localPlayer.playerEntity))
            {
                var ps      = EntityManager.GetComponentData <Player.State>(localPlayer.playerEntity);
                selfTeamIdx = ps.teamIndex;
            }
        });

        // Create nameplate for new players
        Entities.WithNone <NamePlateEntityHolder>().ForEach((Entity e, ref Player.State player) =>
        {
            if (player.playerId == self_id)
            {
                return;
            }

            var npe   = new NamePlateEntityHolder();
            var avail = m_NamePlates.IndexOf(null);
            if (avail < 0)
            {
                avail = m_NamePlates.Count;
                m_NamePlates.Add(null);
            }
            npe.namePlateIdx    = avail;
            m_NamePlates[avail] = GameObject.Instantiate <NamePlate>(m_NamePlate);
            EntityManager.AddComponentData(e, npe);
        });

        // Destroy nameplate for players gone
        Entities.WithNone <Player.State>().ForEach((Entity e, ref NamePlateEntityHolder namePlateEntity) =>
        {
            GameObject.Destroy(m_NamePlates[namePlateEntity.namePlateIdx]);
            m_NamePlates[namePlateEntity.namePlateIdx] = null;
            EntityManager.RemoveComponent(e, typeof(NamePlateEntityHolder));
        });

        var physicsWorldSystem = World.GetExistingSystem <BuildPhysicsWorld>();

        // Update nameplates
        Entities.ForEach((Entity e, ref Player.State player, ref NamePlateEntityHolder plateHolder) =>
        {
            // Skip players not controlling anything
            if (player.controlledEntity == Entity.Null)
            {
                return;
            }

            // Skip self
            if (player.playerId == self_id)
            {
                return;
            }

            // Only if controlling somethin with pos
            if (!EntityManager.HasComponent <Unity.Transforms.LocalToWorld>(player.controlledEntity))
            {
                return;
            }

            // Get screenpos
            var ltw       = EntityManager.GetComponentData <Unity.Transforms.LocalToWorld>(player.controlledEntity);
            var camera    = GameApp.CameraStack.TopCamera();
            var platePos  = ltw.Position + new float3(0, 1.8f, 0);
            var screenPos = camera.WorldToScreenPoint(platePos);

            var namePlate = m_NamePlates[plateHolder.namePlateIdx];

            // Update visibility
            bool visible = screenPos.z > 0;

            if (visible)
            {
                // Check for occlusion
                var rayStart = camera.ScreenToWorldPoint(new Vector3(screenPos.x, screenPos.y, 0));

                var filter          = CollisionFilter.Default;
                filter.CollidesWith = 1 << 0;
                var ray             = new RaycastInput()
                {
                    Start  = rayStart,
                    End    = platePos,
                    Filter = filter
                };
                Unity.Physics.RaycastHit hit;
                if (physicsWorldSystem.PhysicsWorld.CollisionWorld.CastRay(ray, out hit))
                {
                    visible = false;
                }
            }

            if (!visible && namePlate.gameObject.activeSelf)
            {
                namePlate.gameObject.SetActive(false);
            }
            else if (visible && !namePlate.gameObject.activeSelf)
            {
                namePlate.gameObject.SetActive(true);
            }

            if (!visible)
            {
                return;
            }

            var friendly = player.teamIndex == selfTeamIdx;

            // Update position and name and color
            namePlate.namePlateRoot.transform.position = screenPos;
            namePlate.nameText.Set(ref player.playerName);
            namePlate.nameText.color = Game.game.gameColors[friendly ? (int)Game.GameColor.Friend : (int)Game.GameColor.Enemy];
        });
    }