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
andSystem.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.