Reputation: 822
I am trying to move my player to destroy monsters and the first time I destroy a monster I have the following error:
MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object.
How can I make it to duplicate itself as a new GameObject?
This is my script:
using System.Collections.Generic;
using UnityEngine;
public class TimeMap: MonoBehaviour {
public GameObject selectedUnit;
public GameObject selectedMonster;
public TileType[] tileTypes;
try{
if(selectedMonster.GetComponent<Monster>().tileX == selectedUnit.GetComponent<Unit>().tileX && selectedMonster.getComponent<Monsters>().tileY == selectedUnit..GetComponent<Unit>())
Destroy(selectedMonster);
}
public void SpawnMon() {
if(counter % 5 == 0){
Debug.Log(" counter % 5 == 0");
Instantiate(selectedMonster.GetComponent<Monsters>().Monster, new Vector3(Random.Range(1,8), Random.Range(1,8), -1), Quaternion.identity);
}
}
}
So I try to create the same object or a clone of it every 5 moves, but I am having errors while doing it.
Upvotes: 0
Views: 1060
Reputation: 7615
Problems:
You are trying to access your monsters like this:
selectedMonster.GetComponent<Monster>()
It means if you have in your scene more than one GameObject of type Monster, Unity will not be sure which one you are referring to.
Also when you instantiate a monster, you use just
Instantiate(selectedMonster.GetComponent<Monsters>().Monster, new Vector3(Random.Range(1,8), Random.Range(1,8), -1), Quaternion.identity);
So you will not be able to distinguish one instance from another in your scene.
Solutions:
In case you wanted to continue with this approach, where you check if tileX and tileY of monster match with your Unit (which I assume is your hero or similar), you should have all monsters inside an array so you can iterate them all in a way you refer easily to the one you want to destroy.
You could try FindObjectsOfType and there pass your Monster type:
Monster [] monsters= FindObjectsOfType(typeof(Monster )) as Monster [];
Then you iterate
foreach (Monster thisMonster in monsters){
//check things here
}
Another option is to store the monsters in an array when you instantiate them
//Define as global variable a list of Monsters
List<GameObject> monsterList = new List<GameObject>();
//Then you instantiate then like
monsterList .add((GameObject)Instantiate(selectedMonster.GetComponent<Monsters>().Monster, new Vector3(Random.Range(1,8), Random.Range(1,8), -1), Quaternion.identity));
And you iterate them using the foreach as before
Better Solution (From my point of view)
However, since your main goal, correct me if I am wrong, is to detect when the position of a Unit match with the position of a monster, to later destroy that particular monster. I would use colliders instead. And in the GameObject you call Unit I would add a TriggerEnter
. Since you use the TileX and TileY I suspect you are creating a 2D game, so it would be something like this:
void OnTriggerEnter2D(Collider2D other) {
Destroy(other.gameObject);
}
With this you destroy any monster that touches your "Unit" and you will not have reference problems.
Upvotes: 4