Home > database >  foreach loop iterating only once? C# Unity3D
foreach loop iterating only once? C# Unity3D

Time:03-06

I am trying to Instantiate a tree prefab based on transforms (specifically the position and rotation) that are loaded from a firebase database.

The problem here is that the foreach loop only iterates one time even though there are a total of 4 children in snapshot.Children, so I am confused as to why it only runs once.

This is the method

public void GetTrees()
   {
       reference.Child("Player").Child(scenarioName).GetValueAsync().ContinueWith(task =>
       {
           if (task.IsFaulted)
           {
               Debug.LogError("Error");
           }
           else if (task.IsCompleted)
           {
               DataSnapshot snapshot = task.Result;

               foreach (DataSnapshot tree in snapshot.Children)
               {
                   xPos = float.Parse(tree.Child("xPos").Value.ToString());
                   yPos = float.Parse(tree.Child("yPos").Value.ToString());
                   zPos = float.Parse(tree.Child("zPos").Value.ToString());

                   xRot = float.Parse(tree.Child("xRot").Value.ToString());
                   yRot = float.Parse(tree.Child("yRot").Value.ToString());
                   zRot = float.Parse(tree.Child("zRot").Value.ToString());
                   wRot = float.Parse(tree.Child("wRot").Value.ToString());

                   Vector3 loadTreePosition = new Vector3(xPos, yPos, zPos);
                   Quaternion loadTreeRotation = new Quaternion(xRot, yRot, zRot, wRot);

                   //returns the position of Tree 0 (31.63, .03, -38.79)
                   Debug.Log("Tree Positons "   loadTreePosition); 

                   //returns the rotation of Tree 0 (0,0,0,1)
                   Debug.Log("Tree Rotations "   loadTreeRotation);

                   //returns 4
                   Debug.Log(snapshot.ChildrenCount);

                   Instantiate(treePrefab, loadTreePosition, loadTreeRotation);

                   //THIS DOES NOT RETURN ANYTHING 
                   Debug.Log(snapshot.ChildrenCount);
               }
           }
       });
   }

Here is the console with the debug.log statements shown in the method debug log console image

Here is the database information as json

{
  "Player" : {
    "test" : {
      "Tree 0" : {
        "mesh" : "palm-01 Instance",
        "wRot" : 1,
        "xPos" : 31.629507064819336,
        "xRot" : 0,
        "yPos" : 0.029083967208862305,
        "yRot" : 0,
        "zPos" : -38.7875862121582,
        "zRot" : 0
      },
      "Tree 1" : {
        "mesh" : "palm-01 Instance",
        "wRot" : 1,
        "xPos" : 31.059694290161133,
        "xRot" : 0,
        "yPos" : 0.029083967208862305,
        "yRot" : 0,
        "zPos" : -40.921390533447266,
        "zRot" : 0
      },
      "Tree 2" : {
        "mesh" : "palm-01 Instance",
        "wRot" : 1,
        "xPos" : 31.059694290161133,
        "xRot" : 0,
        "yPos" : 0.029083967208862305,
        "yRot" : 0,
        "zPos" : -40.921390533447266,
        "zRot" : 0
      },
      "Tree 3" : {
        "mesh" : "palm-01 Instance",
        "wRot" : 1,
        "xPos" : 31.46793556213379,
        "xRot" : 0,
        "yPos" : 0.029083967208862305,
        "yRot" : 0,
        "zPos" : -43.42497253417969,
        "zRot" : 0
      }
    }
  }
}

CodePudding user response:

Most likely method Instantiate(treePrefab, loadTreePosition, loadTreeRotation); throw an exception and that prevents further cycle iterations. Try to wrap up Instantiate(); into try .. except and log catched exceptions

CodePudding user response:

Most of the Unity API can only be executed in the Unity main thread!

You are using ContinueWith(Action<Task>) without a specific TaskScheduler

Creates a continuation that executes asynchronously when the target Task completes.

which doesn't assure that the callback is called on the main thread so latest at Instantiate it fails.

Firebase specific for Unity provides the task extension method ContinueWithOnMainThread

Extension methods for System.Threading.Tasks.Task and System.Threading.Tasks.Task<T> that allow the continuation function to be executed on the main thread in Unity.

you should rather use here

reference.Child("Player").Child(scenarioName).GetValueAsync().ContinueWithOnMainThread(task =>
{
    ....
});

In general make sure you haven't disabled any log type in the console. You should afaik have seen a warning telling you that Instantiate can not be used outside the main thread.

  • Related