Greetings,
I’m facing a problem regarding the update of several meshes materials.
I’m developing a projection mapping app, currently I have 3 planes on my surface, each has 4 points that define their position in space (each point, named DestinationPoint is located at the edge of the plane’s corners representing the mesh). By moving (manually, using the OnMouseDown() and OnMouseDrag() functions) each point, the mesh is updated accordingly so that each corner follows each of the point (the goal is matches a real world surface.)
So that I don’t have to do this calibration each time, I’m saving the values (local position property) of these 12 points (3 planes * 4 points) in a XML file. The saving/loading process of the XML file is working just fine, all points are automatically moved to the positions previously saved in the XML file. The problem arises when Unity updates each mesh material, it is only updating ONE mesh.
For example, this is the saved scene, saved into a XML file, with 3 planes, each having 4 points represented by the white spheres.
This is the scene loaded from the XML file. The points are moved into the proper position, yet the mesh isn’t updated.
The function that loads the XML file is the following:
void LoadScenario(){
filePath = Application.dataPath + "/XmlData/"+scenario+".xml";
XmlReader reader = XmlReader.Create(filePath);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);
XmlNodeList Surfaces = xmlDoc.GetElementsByTagName("Surfaces");
/* XML file structure
*
* <Surfaces>
<ProjectionSurface1>
<DestinationPoints>
<DP0>
<Position>-8.28037,18.33852,10.06745</Position>
</DP0>
<DP1>
<Position>-31.55436,-3.485761,3.270439</Position>
</DP1>
<DP2>
<Position>38.00045,-1.380948,4.482903</Position>
</DP2>
<DP3>
<Position>30.65092,19.90506,10.96985</Position>
</DP3>
</DestinationPoints>
</ProjectionSurface1>
</Surfaces>
*/
for(int surface = 0; surface < Surfaces.Count; surface++){
// There is only 1 type of Surface, so only 1 node for now...
XmlNode NodeSurface = Surfaces.Item(surface);
// Get List of Projection Surfaces
XmlNodeList allProjSurfaces = NodeSurface.ChildNodes;
//Debug.Log("Number of Proj Surfaces = " + allProjSurfaces.Count);
for(int projSurf = 0 ; projSurf < allProjSurfaces.Count; projSurf++){
XmlNode nodeProjSurface = allProjSurfaces.Item(projSurf);
string activeProjSurfStr = nodeProjSurface.Name;
//Debug.Log("Projection Surface: " + nodeProjSurface.Name);
// Get the DestinationPoints node
XmlNode nodeDestPoints = nodeProjSurface.FirstChild;
// Get all DPs node list
XmlNodeList allDPs = nodeDestPoints.ChildNodes;
for(int dp = 0; dp < allDPs.Count; dp++){
XmlNode nodeDP = allDPs.Item(dp);
XmlNode nodePos = nodeDP.FirstChild;
string dpStr = nodeDP.Name;
Debug.Log("dpStr: " + dpStr);
string[] split_position = nodePos.InnerText.Split(',');
/*Debug.Log("ProjectionSurface : " + nodeProjSurface.Name +
" with " + nodeDP.Name +
" ,with PosX: " + float.Parse(split_position[0]) +
" ,with PosY: " + float.Parse(split_position[1]) +
" ,with PosZ: " + float.Parse(split_position[2]));*/
float xmlXPos = float.Parse(split_position[0]);
float xmlYPos = float.Parse(split_position[1]);
float xmlZPos = float.Parse(split_position[2]);
Vector3 xmlPosVec = new Vector3(xmlXPos, xmlYPos, xmlZPos);
List <GameObject> dpList = sleManager.listOfDestPoints;
int multiplier = destControl.ReturnModifier(projSurf+1);
dpList[dp+multiplier].transform.localPosition = xmlPosVec;
GameObject dpActiveObj = dpList[dp+multiplier].gameObject;
}
}
}
reader.Close();
// Test to force an update to all 3 projection surfaces meshes
GameObject dp0 = sleManager.listOfDestPoints[0];
GameObject dp4 = sleManager.listOfDestPoints[4];
GameObject dp8 = sleManager.listOfDestPoints[8];
destControl.Run(dp0);
Debug.Log("0");
destControl.Run(dp4);
destControl.Run(dp8);
}
}
The function Run(GameObj obj) that I’m using in the end has the main goal of updating the material properties of obj in the argument and is as follows:
public void Run(GameObject dpObj){
Debug.Log("Run com arg obj name: " + dpObj.gameObject.name);
manager.indexChanged = true;
string activeDPStr = dpObj.name;
string activeProjSurfStr = dpObj.transform.root.ToString();
manager.activeProjSurfObj = ReturnActiveProjSurf(dpObj);
manager.activePlaneObj = ReturnActivePlaneObj(manager.activeProjSurfObj);
string activePlaneStr = manager.activePlaneObj.name;
manager.activeProjSurf = int.Parse(activeProjSurfStr[17].ToString());
manager.modifier = ReturnModifier(manager.activeProjSurf);
manager.activeIndex = int.Parse(activeDPStr[2].ToString()) + manager.modifier;
manager.meshMaterial = manager.activePlaneObj.renderer.material;
}
The list “listOfDestPoints” contains all existing destination points. Keep in mind each plane has 4 points, so every 4 members in the list, the target plane changes.
Now, if I try to run do:
destControl.Run(dp0); // Updates Plane 1, works just fine.
But if I try:
destControl.Run(dp0);
destControl.Run(dp4); // Does not update Plane 1, only Plane 2.
p.s: Sorry about the wall of text!