Objects being destroyed immediately after instantiation

Hi guys,

I'm finding as soon as I instantiate an object with:
TrueSyncManager.SyncedInstantiate(prefab, TSVector.zero, TSQuaternion.identity);
It gets immediately destroyed.

Look likes this is occurring in the CheckGameObjectsSafeMap() method in TrueSyncManager.cs at line 491:
GameObject.Destroy(go);

If i comment this out, the object doesn't get destroyed, but I feel like this is important?

Not sure if there's something else I'm doing wrong

Comments

  • Hi @adamjm, the CheckGameObjectsSafeMap it is used to remove Gos created in a rollback situation, maybe there is some situation that we didn't catch well, can you send in a PM some simple project so we could reproduce your case?
  • Hi @JeffersonHenrique, thanks for replying. I've created a test project that replicates the error and will PM it to you now. Thanks
  • experiencing the same issue
  • Having the same issue. Was working with version 1.0.5, just updated to 1.0.9 and this strange issue has been discovered. It was fine with 1.0.5.
  • Hello @DylanYasen and @ScriptGeek, I saw the script of @adamjm, it has a few things causing this issue, it was not a TS bug. If you want to create a simple project with that issue I can take a look if can be a mistake or a bug, thanks.
  • ScriptGeek
    edited March 2017
    @JeffersonHenrique I created a demonstration from the TrueSync package of the Boxes demo scene here: https://github.com/ScriptGeek/TrueSyncTest

    Attached to the Main Camera game object in the scene is the SpawnTest script. In this script there is a coroutine called "spawner" that is called that instantiates a game object every 2 seconds. The first game object gets instantiated and in the next lockstep an exception is thrown:
    MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.
    TrueSync.LayerCollisionMatrix.CollisionEnabled (UnityEngine.GameObject goA, UnityEngine.GameObject goB) (at Assets/TrueSync/Unity/LayerCollisionMatrix.cs:32)
    TrueSync.PhysicsWorldManager.IsCollisionEnabled (IBody rigidBody1, IBody rigidBody2) (at Assets/TrueSync/Unity/PhysicsWorldManager.cs:277)
    TrueSync.World.CanBodiesCollide (TrueSync.RigidBody body1, TrueSync.RigidBody body2)
    TrueSync.CollisionSystem.CheckBothStaticNonKinematic (IBroadphaseEntity entity1, IBroadphaseEntity entity2)
    TrueSync.CollisionSystemPersistentSAP.Detect (Boolean multiThreaded)
    TrueSync.World.Step (FP timestep, Boolean multithread)
    TrueSync.PhysicsWorldManager.UpdateStep () (at Assets/TrueSync/Unity/PhysicsWorldManager.cs:76)
    TrueSync.AbstractLockstep.ExecutePhysicsStep (System.Collections.Generic.List`1 data, Int32 syncedDataTick)
    TrueSync.AbstractLockstep.Update ()
    TrueSync.TrueSyncManager.FixedUpdate () (at Assets/TrueSync/Unity/TrueSyncManager.cs:703)

    And somehow the game object never visibly exists in the scene and only briefly does it exist immediately after instantiation to output the value of the "go" variable. If the code in the spawner method that instantiates the game object is moved to OnSyncedStart, the game object gets instantiated and remains in the scene without throwing an exception.

    I'm using TrueSync 1.0.9 and Unity 5.5.1f1 with Windows 10.
  • Hi @ScriptGeek, thanks for sharing a sample project, maybe this is issue is related to the use of coroutines, we have to test.
  • hey @JeffersonHenrique, mind if I were to know what are the things that could possibly causes this issue. so I could try debug myself
  • Hello @mmediawyh, it quite tough to say where because it can be either a bug on a script or a bug on TrueSync code, you have to try to isolate what part is causing this issue but it not a simple task.
  • I think a simple explanation of the issue and the solution would be more helpful than "it's ok, it wasn't a TS issue". Something like "you should make sure you don't do X because that will cause problems. This is not a TS issue but it is something to be careful about". :)
  • Hi @Prodigga, a lot of possible problems can happen as I don't have any knowledge about your code, it is why I wrote "you have to try to isolate what part is causing this issue". A main thing here is to think that TS is deterministic, so a use of Unity's callbacks, for example, can trigger an issue like that :)
  • ScriptGeek
    edited March 2017
    I came up with a solution for what I needed by using TrueSync's deterministic time system to manage a timed spawn interval. It can also be used for other situations where execution of code needs to be done on a timed interval. Check out my code:

    using System; using TrueSync; /// <summary> /// Use this to call the specified action at the given time interval /// </summary> public class TrueSyncIntervalExecutor { private Action intervalAction; // Action to be executed upon reaching a time interval private FP intervalTime; // Time interval in which the action is called (in seconds) private FP elapsedTime = FP.Zero; // Running time keeper, like a stop watch, when it reaches the intervalTime, call the action /// <summary> /// Constructor to initialize and interval timer /// </summary> /// <param name="intervalAction">Action to be called upon reaching intervalTime seconds</param> /// <param name="intervalTime">Time in seconds after which Action gets called</param> public TrueSyncIntervalExecutor(Action intervalAction, FP intervalTime) { this.intervalAction = intervalAction; this.intervalTime = intervalTime; } /// <summary> /// Handles processing of a single tick of the interval timer /// Call this every frame (probably inside OnSyncedUpdate) /// </summary> public void Tick() { elapsedTime += TrueSyncManager.DeltaTime; if (elapsedTime >= intervalTime) { elapsedTime -= intervalTime; // Do not set to zero so that overlap time is preserved intervalAction.Invoke(); } } }

    Usage:
    // Defined as member variables in your script: private TrueSyncIntervalExecutor intervalExecutor; public override void OnSyncedStart(){ intervalExecutor = new TrueSyncIntervalExecutor(methodToBeCalledOnInterval, numberOfSecondsPerInterval); } public override void OnSyncedUpdate(){ intervalExecutor.Tick(); } private void methodToBeCalledOnInterval() { Debug.Log("methodToBeCalledOnInterval called"); }