Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved EntityQuery doesn't find player tag in first 1 or 2 frames of game

Discussion in 'Entity Component System' started by Gudarzi, Apr 18, 2021.

  1. Gudarzi

    Gudarzi

    Joined:
    Feb 28, 2021
    Posts:
    6
    I have a query for finding the player, like this:
    Code (CSharp):
    1. EntityQuery playerQuery = GetEntityQuery(ComponentType.ReadOnly<PlayerTag>());
    Then I try to get to the player entity, like this:
    Code (CSharp):
    1. Entity playerEntity = playerQuery.GetSingletonEntity();
    The problem is that if I run this code inside
    OnUpdate ()
    of a system, for the first 1 or 2 frames of my game, the query doesn't return anything and
    GetSingletonEntity()
    throws this error:
    Code (CSharp):
    1. InvalidOperationException: GetSingletonEntity() requires that exactly one entity exists that matches this query, but there are 0.
    After 2 frames, everything is fine and query finds the player. Also, it doesn't matter how much I use
    UpdateBefore
    s and
    UpdateAfter
    s. I get this error anyway.

    Edit:
    I'm currently using:
    • Unity 2020.2.5
    • Universal Render Pipeline
    • hybrid renderer package version 0.11.0.preview.42 and its default dependencies
    • and I have enabled Hybrid_Renderer_V2.
     
    Last edited: Apr 18, 2021
  2. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,754
    If you use
    Code (CSharp):
    1. protected override void OnCreate ()
    to set query,
    add below your group definition
    Code (CSharp):
    1. RequireForUpdate ( playerQuery );
    That should solve the issue.

    Another option, is to add early exit in OnUpdate, i.e.
    Code (CSharp):
    1. if ( group_meshes.CalculateChunkCount () == 0 ) return; // Early exit.
     
    Egad_McDad and Gudarzi like this.
  3. Gudarzi

    Gudarzi

    Joined:
    Feb 28, 2021
    Posts:
    6
    Well, I don't want to run this on every frame update. I need to find the player only once (need to run this code inside OnCreate() or OnStartRunning() so that it doesn't look for the player on every frame).
    As I said, the problem gets fixed after 2 frames. What you're suggesting is the same!
     
  4. Vari-Mods

    Vari-Mods

    Joined:
    Jan 21, 2021
    Posts:
    7
  5. Rupture13

    Rupture13

    Joined:
    Apr 12, 2016
    Posts:
    129
    I think that if you were to add
    RequireSingletonForUpdate<PlayerTag>();
    to the system's OnCreate() and then execute the part where you find your player in the system's OnStartRunning(), it will behave as you expect: waiting until the player singleton exists before finding the player in the OnStartRunning() and then not having to manually check anything in the OnUpdate() after that.
    The downside to this would be that the OnUpdate() will remain dependant on the PlayerTag singleton existing, but I suppose that's not an issue for this usecase.
     
    Gudarzi likes this.
  6. Gudarzi

    Gudarzi

    Joined:
    Feb 28, 2021
    Posts:
    6
    Thanks, it fixed the problem.
    (But still, this is a weird behavior. I don't understand why it doesn't find the player on the first 2 frames, while the player is definitely there!)
     
    Rupture13 likes this.
  7. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,754
    Are you using Entity conversion work flow or ECBs? If so, they may impose the delay.
     
  8. Gudarzi

    Gudarzi

    Joined:
    Feb 28, 2021
    Posts:
    6
    I'm using entity conversion workflow using separate subscenes. The reason I'm trying to find the player like this, is that it's on another subscene.
     
  9. TWolfram

    TWolfram

    Joined:
    Aug 6, 2017
    Posts:
    75
    SubScenes are supposed to be the way of doing stuff like this to make sure data is already in your scene before runtime, yet when doing things like this it seems like the Entities aren't correctly set up in the first two frames. This probably happens because it still needs to fix the Entity indexes when loading the SubScenes; though I'm really not sure why this couldn't be done pre-runtime as well.

    In my opinion/experience SubScenes are kind of useless if you need some sort of reference in code to an entity within a subscene. You can't even set up references in the inspector because of "scene mismatch", and trying to find those references through code like you're trying here delays the first few (I think in my case it was 2 as well) frames anyways, which seems to completely defeat the purpose of wanting the Entities to be pre-converted in the first place.
    I really hope the whole pre-runtime conversion gets a lot of love in the next update, and I especially hope they don't get rid of ConvertToEntity before this actually works properly.
     
    Gudarzi likes this.