我有一个save-Method,可以使用位置,健康状况,旋转等五个特定标签之一保存有关每个块的信息。
我首先要获取所有对象(甚至是不活动的对象),因此我使用FindObjectsOfTypeAll()-Method。
然后,我通过一个foreach循环遍历所有已找到的对象,并检查它们是否具有正确的标签,如果有,我保存它们。
这是我使用的代码:
GameObject[] allObjects = Resources.FindObjectsOfTypeAll(typeof (GameObject)) as GameObject[];
using (StreamWriter write = new StreamWriter(dir + "blocksSave.dat"))
{
Debug.Log(allObjects.Length);
foreach (GameObject block in allObjects)
{
bool isActive = block.activeSelf;
block.SetActive(true);
if (block.tag == "WoodBlock" || block.tag == "WoodSteps" || block.tag == "WoodRamp" || block.tag == "GlasBlock" || block.tag == "WoodDoor")
{
// SAVE
write.WriteLine(block.tag + "," + block.transform.position.x + "," + block.transform.position.y + "," + block.transform.position.z + "," + block.GetComponent<BlockControl>().GetHealth().x + "," + block.GetComponent<BlockControl>().GetHealth().y + "," + block.transform.rotation.x + "," + block.transform.rotation.y + "," + block.transform.rotation.z);
}
block.SetActive(isActive);
}
write.Close();
}
我对此进行了调试,if (block.tag == "WoodBlock" || ...)
行工作正常。
问题是下一行:
write.WriteLine(...);
在这里我得到一个nullReferenceException
,它告诉我:
NullReferenceException:对象引用未设置为的实例 对象
我不知道为什么吗?!
答案 0 :(得分:1)
问题很可能是
block.GetComponent<BlockControl>()
为找到的null
中的一个返回GameObjects
,因为它根本不包含该成分。
您可以使用
Resources.FindObjectsOfTypeAll<BlockCo troll>();
确保在单独的列表中仅包含类型BlockControl
的所有组件。
比起列表,您可以更轻松地过滤标记的对象,而不是那些||
条件
var searchedTags = new List<string>()
{
"WoodBlock",
"WoodSteps",
"WoodRamp",
"GlasBlock",
"WoodDoor"
};
if (searchedTags.Contains(block.gameObject.tag))
{
....
}
甚至更简单的使用Linq来获取您感兴趣的对象:
var objectsOfInterest = allObjects.Where(obj => searchedTags.Contains(obj.gameObject.tag)).ToList();
我也只会使用StreamWriter
进行实际写操作,而在该using
块中什么也不做。
请注意,如果您在StreamWriter
块内使用using
,则不必使用write.Close()
,因为它会自动放置在using
块之后完成。
因此,我将使用类似的
var searchedTags = new List<string>()
{
"WoodBlock",
"WoodSteps",
"WoodRamp",
"GlasBlock",
"WoodDoor"
};
// This list is used to get all GameObject
// keep track which where active and activate all
var allObjects = Resources.FindObjectsOfTypeAll<GameObject>();
// Here we get all BlockController components
var allBlockObjects = Resources.FindObjectsOfTypeAll<BlockController>();
// finally we only get BlockControllers with the tags we want
var objectsOfInterest = allBlockObjects.Where(obj => searchedTags.Contains(obj.gameObject.tag)).ToList();
Debug.Log("objects total: " + allObjects.Length);
Debug.Log("block objects: " + allBlockObjects.Length);
Debug.Log("objects of interest: " + objectsOfInterest.Length);
// Step 1 keep track which GameObjects where active and activate all
var objectWasNotActive = new List<GameObject>();
foreach (var obj in allObjects)
{
if(!obj.activeSelf)
{
// keep track which objects where not active
objectWasNotActive.Add(obj);
}
// Set all to true
obj.SetActive(true);
}
// Step 2 save your BlockControllers with searched tags
using (StreamWriter write = new StreamWriter(dir + "blocksSave.dat"))
{
foreach (var block in objectsOfInterest)
{
// Here you already have components of type BlockController
// so you don't need to get them
// But GetHealth might also return null so maybe you want to check that too
// It is up to you whether you want to skip or fill it with default values in such case
var health = block.GetHealth();
if(health == null)
{
//option 1 skip
continue;
// OR option 2 default e.g.
// Assuming it is Vector2
health = Vector2.zero;
}
// SAVE
write.WriteLine(
block.gameObject.tag + ","
+ block.transform.position.x + ","
+ block.transform.position.y + ","
+ block.transform.position.z + ","
+ health.x + ","
+ health.y + ","
+ block.transform.rotation.x + ","
+ block.transform.rotation.y + ","
+ block.transform.rotation.z
);
}
}
// Step 3 disable those GameObjects again that where not active before
foreach(var obj in objectWasNotActive)
{
obj.SetActive(false);
}
答案 1 :(得分:0)
现在,很难在不看代码的情况下调试它,但是请先检查一下。
input:focus::-webkit-input-placeholder { /* Chrome/Opera/Safari */
color: transparent !important;
}
input:focus::-moz-placeholder { /* Firefox 19+ */
color: transparent !important;
}
input:focus:-ms-input-placeholder { /* IE 10+ */
color: transparent !important;
}
input:focus:-moz-placeholder { /* Firefox 18- */
color: transparent !important;
}
是否已正确初始化且没有错误,有时会无提示地失败。write
吗?尝试将您的代码更新为此,只是检查它到底在哪里失败
BlockControl
通过这种方式,您可以找出导致问题的if (block.tag == "WoodBlock" || block.tag == "WoodSteps" || block.tag == "WoodRamp" || block.tag == "GlasBlock" || block.tag == "WoodDoor")
{
Debug.Log(block.name);
Debug.Log(block.GetComponent<BlockControl>());
Debug.Log(block.GetComponent<BlockControl>().GetHealth());
// SAVE
write.WriteLine(block.tag + "," + block.transform.position.x + "," + block.transform.position.y + "," + block.transform.position.z + "," + block.GetComponent<BlockControl>().GetHealth().x + "," + block.GetComponent<BlockControl>().GetHealth().y + "," + block.transform.rotation.x + "," + block.transform.rotation.y + "," + block.transform.rotation.z);
}
,以及问题出在组件或block
函数上。