我有两个代码在理论上做同样的事情,但在实践中表现得非常不同,我想知道为什么/如何解决它。
void BlockPlacer(){ //Places breakable objects
BlockType BlockKind = BlockType.Hard;
GameObject Block = ReturnBlock (BlockKind);
while(true){
for(int j = 1; j < 4; j++){
for(float i = -width; i < width; i++){
GameObject created = Instantiate (Block, new Vector3 (i, height - j, 10), Quaternion.Euler (0, 0, 0));
print (created.transform.position);
}
}
break;
}
}
正如你所看到的那样,我实例化了一个在我的两个for循环之外创建的GameObject,它可以像你期望的那样工作,在另一个例子中
void BlockPlacer(){ //Places breakable objects
BlockType BlockKind = BlockType.Hard;
while(true){
for(int j = 1; j < 4; j++){
for(float i = -width; i < width; i++){
GameObject created = Instantiate (ReturnBlock (BlockKind), new Vector3 (i, height - j, 10), Quaternion.Euler (0, 0, 0));
print (created.transform.position);
}
}
break;
}
}
我做同样的事情,但这次我在循环中设置我的GameObject,程序只实例化一次(我已经检查了我的代码,所有内容都被调用并以我的方式返回想要它,只实例化不会表现得如此)
我从测试中得出的理论是GameObject是在循环的每次传递中创建的,但它会在下一次传递中被删除并再次创建,这不可能是真的,但是现在,我没有更好的东西。所有GameObject都是从同一个Prefab创建的,因此可能存在一些继承问题。这是返回我的GameObject的代码
GameObject ReturnBlock(BlockType Type){
if (Type == BlockType.Soft) {
GameObject SoftBlock = Resources.Load("GameBorderPrefab") as GameObject;
SoftBlock.name = "SoftBlock";
SoftBlock.tag = "Soft"; //Sets a tag for that gameobject
SoftBlock.AddComponent<HitCounter>();
string TextureName = "";
for (int i = 0; i < GameManager.Bricks.Count; i++) {
if (GameManager.Bricks [i].ID == "Soft") {
TextureName = GameManager.Bricks [i].TextureName;
SoftBlock.GetComponent<HitCounter> ().HP = System.Int32.Parse(GameManager.Bricks [i].HitPoints);
}
}
SoftBlock.GetComponent<Renderer> ().material = Resources.Load (TextureName) as Material;
return SoftBlock;
}if (Type == BlockType.Medium) {
GameObject MediumBlock = Resources.Load("GameBorderPrefab") as GameObject;
MediumBlock.name = "MediumBlock";
MediumBlock.tag = "Medium";
MediumBlock.AddComponent<HitCounter>();
string TextureName = "";
for (int i = 0; i < GameManager.Bricks.Count; i++) {
if (GameManager.Bricks [i].ID == "Medium") {
TextureName = GameManager.Bricks [i].TextureName;
MediumBlock.GetComponent<HitCounter> ().HP = System.Int32.Parse(GameManager.Bricks [i].HitPoints);
}
}
MediumBlock.GetComponent<Renderer> ().material = Resources.Load (TextureName) as Material;
return MediumBlock;
}else{//if (Type == BlockType.Hard) {
GameObject HardBlock = Resources.Load ("GameBorderPrefab") as GameObject;
HardBlock.name = "HardBlock";
HardBlock.tag = "Hard";
HardBlock.AddComponent<HitCounter> ();
string TextureName = "";
for (int i = 0; i < GameManager.Bricks.Count; i++) {
if (GameManager.Bricks [i].ID == "Hard") {
TextureName = GameManager.Bricks [i].TextureName;
HardBlock.GetComponent<HitCounter> ().HP = System.Int32.Parse (GameManager.Bricks [i].HitPoints);
}
}
HardBlock.GetComponent<Renderer> ().material = Resources.Load (TextureName) as Material;
return HardBlock;
}
}
经过进一步测试,我编写了这段代码,其行为就像我提出的第一个代码一样,希望我能看到三条不同的对象线被创建。只有第一个Instantiate按预期工作,其他人没有做任何事情,但我所有的打印功能都按预期工作
BlockType BlockKind = BlockType.Hard;
GameObject Block = ReturnBlock (BlockKind);
int j = 1;
for(float i = -width; i < width; i++){
GameObject created = Instantiate (Block, new Vector3 (i, height - j, 10), Quaternion.Euler (0, 0, 0));
print (created.transform.position);
}
j = 2;
BlockKind = BlockType.Soft;
Block = ReturnBlock (BlockKind);
for(float i = -width; i < width; i++){
GameObject created = Instantiate (Block, new Vector3 (i, height - j, 10), Quaternion.Euler (0, 0, 0));
print (created.transform.position);
}
j = 3;
BlockKind = BlockType.Medium;
Block = ReturnBlock (BlockKind);
for(float i = -width; i < width; i++){
GameObject created = Instantiate (Block, new Vector3 (i, height - j, 10), Quaternion.Euler (0, 0, 0));
print (created.transform.position);
}
答案 0 :(得分:-1)
解决方案在于Unity不能将实例化的内容和作为资源文件夹中的空预制件保存的内容分开,这就是为什么实例化函数会在第二次调用ReturnBlock时出错( )功能。我通过从头开始为我的每一个块类型创建一个新的预制件来修复我的错误,它是否已经优化没有,这是一个很好的做法没有,但是现在它完成工作。
TL; DR Don不使用一个预制件来实例化多个对象,否则继承会启动,你就会遇到麻烦。