Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only.

    Please, do not make any changes to your username or email addresses at id.unity.com during this transition time.

    It's still possible to reply to existing private message conversations during the migration, but any new replies you post will be missing after the main migration is complete. We'll do our best to migrate these messages in a follow-up step.

    On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live.


    Read our full announcement for more information and let us know if you have any questions.

Bug Custom rate world updates

Discussion in 'Entity Component System' started by Selmar, Jan 16, 2023.

  1. Selmar

    Selmar

    Joined:
    Sep 13, 2011
    Posts:
    61
    Hey!

    I'm trying to create a rollback system in which I can have a current and predicted world, potentially roll back the current world at the start of the frame, and interpolate between them for the rendering. I intend to use Unity Physics.

    To that end, I've created two worlds and copy the state from one to the other after the updates and do another update. The world is completely empty (no entities at all). It results in errors as mentioned below, and also adds three "DebugDisplay.DrawComponent" gameobjects in the scene (as in the screenshot).

    I thought this was a reasonable approach, and it feels like I'm running into a bug; but maybe I'm abusing the system.

    and sometimes this:
    When I stop playing the scene, I see these and a few more of a similar genre:
    The entire code is not very complicated, I copied it from what I've read in the entities code, but surely I missed something.
    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using Unity.Entities;
    6. using Unity.Collections;
    7. using Unity.Burst;
    8.  
    9.  
    10. public class WorldUpdate : MonoBehaviour
    11. {
    12.     World now;
    13.     World future;
    14.  
    15.     int simFrameNumber = 0;
    16.     const int simFramesPerSecond = 10;
    17.  
    18.     // Start is called before the first frame update
    19.     void Start()
    20.     {
    21.         now = new World("Sim", WorldFlags.Simulation | WorldFlags.Shadow);
    22.         future = new World("SimPrediction", WorldFlags.Simulation | WorldFlags.Shadow);
    23.  
    24.         now.CreateSystemManaged<InitializationSystemGroup>();
    25.         now.CreateSystemManaged<SimulationSystemGroup>();
    26.         now.CreateSystemManaged<PresentationSystemGroup>();
    27.         future.CreateSystemManaged<InitializationSystemGroup>();
    28.         future.CreateSystemManaged<SimulationSystemGroup>();
    29.         future.CreateSystemManaged<PresentationSystemGroup>();
    30.  
    31.         IReadOnlyList<System.Type> allSystems = DefaultWorldInitialization.GetAllSystems(WorldSystemFilterFlags.LocalSimulation, false);
    32.         DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(now, allSystems);
    33.         DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(future, allSystems);
    34.     }
    35.  
    36.     private void OnDestroy()
    37.     {
    38.         if(now?.IsCreated == true) now.Dispose();
    39.         if(future?.IsCreated == true) future.Dispose();
    40.     }
    41.  
    42.     static double _GetFrameTime(int frameNumber)
    43.     {
    44.         int simTimeSeconds = frameNumber / simFramesPerSecond;
    45.         int simTimeFraction = frameNumber % simFramesPerSecond;
    46.         return simTimeSeconds + simTimeFraction / ((double)simFramesPerSecond);
    47.     }
    48.  
    49.     // Update is called once per frame
    50.     void Update()
    51.     {
    52.         double currentTime = Time.timeAsDouble;
    53.  
    54.         double simNowFrameTime = _GetFrameTime(simFrameNumber);
    55.         double simFutureFrameTime = _GetFrameTime(simFrameNumber+1);
    56.  
    57.         bool updatedNow = false;
    58.  
    59.         while (currentTime >= simFutureFrameTime)
    60.         {
    61.             ++simFrameNumber;
    62.             simNowFrameTime = _GetFrameTime(simFrameNumber);
    63.             simFutureFrameTime = _GetFrameTime(simFrameNumber + 1);
    64.  
    65.             Debug.LogFormat("Update World {0}", now.ToString());
    66.             now.EntityManager.CompleteAllTrackedJobs();
    67.             now.SetTime(new Unity.Core.TimeData(simNowFrameTime, 1.0f / simFramesPerSecond));
    68.             now.Update();
    69.             updatedNow = true;
    70.         }
    71.  
    72.         if(updatedNow)
    73.         {
    74.             future.EntityManager.CopyAndReplaceEntitiesFrom(now.EntityManager);
    75.             future.SetTime(new Unity.Core.TimeData(simNowFrameTime, 1.0f / simFramesPerSecond));
    76.             future.Update();
    77.         }
    78.     }
    79. }
    80.  
     

    Attached Files:

  2. Selmar

    Selmar

    Joined:
    Sep 13, 2011
    Posts:
    61
    It does not generate these errors if I do not have the "future" world
     
  3. Selmar

    Selmar

    Joined:
    Sep 13, 2011
    Posts:
    61
    I am now compiling all packages in debug to get some more information and I'm trying other approaches, but nothing successful yet.

    I tried serializing the world instead and I get this exception even when I serialize a new and empty world:
    Which makes sense, there's this in there:
    internal unsafe void* m_SimulationPtr;
     
    Last edited: Jan 17, 2023