Instantiating and destroying GameObject from an array - c#

I want to instantiate several instances of a prefab into an array each with their own index number but i keep getting the error code "object reference not set to an instance of an object. How can I get rid of this error and how can I destroy individual objects or retrieve the properties of each individual game object in the array?
using UnityEngine;
using System.Collections;
public class SpawnEnemy : MonoBehaviour {
private GameObject[] enemy;
public GameObject enemyPrefab;
// Use this for initialization
void Start () {
enemy[1] = (GameObject)Instantiate (enemyPrefab, new Vector3 (-119, 52, 483), transform.rotation);
}
// Update is called once per frame
void Update () {
if (Input.GetButtonDown ("Fire2")) {
Destroy (enemy[1]);
}
}
}

As DrUsh mentiones, you need to initialize the array, e.g. like this:
void Start()
{
// initialize array with a size of 5, all elements are empty
enemy = new GameObject[5];
// now you can work with this array, e.g. like you line:
enemy[1] = (GameObject)Instantiate (enemyPrefab, new Vector3 (-119, 52, 483), transform.rotation);
}
The downside of using arrays is that you will have a fixed number of elements (5 in my example). If you don't know the exact number of objects you want at max at the same time stored into your array, you are better of using a List<GameObject> which can be resized dynamically. This also needs to be initialized by putting enemy = new List<GameObject>().
Also, you probably don't want to access the array/list with hardcoded indices. I don't know if that was just for example and you have a better, automated way to create gameobject-index pairs though.

You have not instantiated the array before you set the value for enemy[1]. Also, the index should be 0, not 1, i.e. enemy[0] = ... because the index of a C# array starts from 0.
You can instantiate and set using the below.
enemy = new[]
{
(GameObject)Instantiate(enemyPrefab,
new Vector3 (-119, 52, 483), transform.rotation)
};

Related

Trying to cycle through objects in an array using keyboard input

I am attempting to implement some basic functionality in Unity using this script attached to an empty which has 6 child objects. I have tried various fixes in my code, but cant seem to achieve the desired result.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectSelector : MonoBehaviour
{
// This array stores the Prefabs
public GameObject[] ObjectArray;
// Integer for stepping through array Prefabs
private int selectedObject = 0;
// Location to instantiate the prefab
private Transform locator;
// Holds the currently instantiated Prefab in the scene
private GameObject tempMesh;
void Start()
{
// Instantiate initial Prefab
tempMesh = Instantiate(ObjectArray[selectedObject], locator.position, locator.rotation);
}
void Update()
{
if (Input.GetKeyDown(KeyCode.RightArrow))
{
// Step to next position in array
ObjectArray++;
// Remove previously instantiated prefab from hierarchy
Destroy(tempMesh);
// Instantiated next Prefab
tempMesh = Instantiate(ObjectArray[selectedObject], locator.position, locator.rotation);
// Print Counter for debug
print(ObjectArray);
// If Array count excedes Array index then go back to first position in array
if (ObjectArray >= ObjectArray.Length)
{
ObjectArray = 0;
}
}
}
}
You are incrementing an array, you need to increment your counter
void Update()
{
if (Input.GetKeyDown(KeyCode.RightArrow))
{
// Step to next position in array
selectedObject++;
// If Array count exceeds Array index then go back to first position in array
if (selectedObject >= ObjectArray.Length)
{
selectedObject = 0;
}
// Remove previously instantiated prefab from hierarchy
Destroy(tempMesh);
// Instantiated next Prefab
tempMesh = Instantiate(ObjectArray[selectedObject], locator.position, locator.rotation);
// Print Counter for debug
print(selectedObject);
}
}

How do I access a prefab and all of its instantiated clones in c# and unity?

I need a little help again please. I'm currently working on powerups and it's setup so that the powerup affectsthe prefab thats put into its prefab slot, so this is means it is currently only affecting one object (in my case, enemy). When the game starts I spawn about 20 enemies and if i pickup the powerup I want it to affect all those spawned enemies and not only the one that is dragged onto the script, does anyone have a solution or alternate method to do this please?
When instantiate them store them in a list and then iterate through all and update their value
In your case e.g.
// if enemies have a certain Component rather use that type here instead of GameObject
public GameObject enemyPrefab;
// and use the same type here instead of GameObject
private List<GameObject> enemyInstances = new List<GameObject> enemyInstances;
private void Start()
{
for(int i = 0; i < 20; i++)
{
var newEnemy = Instantiate(enemyPrefab);
enemyInstances.Add(newEnemy);
}
}
and then later
public void UpdateEnemies()
{
foreach(var enemy in enemyInstances)
{
// skip already destroyed objects
if(!enemy) continue;
// whatever to be done to the enemies
}
}
To get all game objects to an array you can use the Tag.
Just add an 'Enemy' tag to the prefab and use the code below:
public GameObject[] enemys;
void Start()
{
respawns = GameObject.FindGameObjectsWithTag("Enemy");
}
Full Unity documentation HERE

Own Class and List<> problems Unity C#

I need your help with things that are going to blow up my mind...(Don't know why but I can't write "Hello everybody!" at the start of the post. Forum hides it:)
I can't figure out why my List <'My Tile Class> is cleared by itself.
I have few prefabs (with box-collider) with no scripts attached to them and one script on the scene. The idea is to take random prefab, attach random value to it and initiate it. After that player clicks on prefab on the scene and gets its value.
public class Generate_Field : MonoBehaviour {
public class Tiles {
public GameObject My_Tile;
public int My_Value;
}
public List<Tiles> My_List;
private GameObject EmptyObj;
// ... other variables
void Start (){
List<Tiles> My_List = new List<Tiles> ();
// ... below some calculation (about 100 rows)
//Instantiate obj and give its reference to Emptyobj
EmptyObj = Instantiate (My_GameObj_To_Inst, new Vector3(My_X, My_Y, 0f), Quaternion.identity);
Tiles Tile1 = new Tiles ();
Tile1.My_Tile = EmptyObj;
Tile1.My_Value = 1; //
My_List.Add (Tile1); // Add Tile1 (with reference to Gameobj and value to List)
// If I put code inside Void Start () it works ok and print all values
foreach (Tiles SS in My_List) {
print (SS.My_Value);
}
The problem is when I put it to Void Update ().
My_List somehow "Suicide" to zero.count although it is public List. In that case I get error:
"NullReferenceException: Object reference not set to an instance of an object..."
void Update ()
{
if (Input.GetKeyDown (KeyCode.Mouse1)) {
print (My_List.Count);
}
}
You declare a new local list in Start and populate that one. If you mean to initialise the class member, remove the type from the line doing the initialisation.
void Start (){
My_List = new List<Tiles> (); // class member, not new variable.
As a usual guideline, it's better to initialise lists at the declaration point. There's usually no reason to replace the list at a later time.

Having trouble creating a duplicate of a game object with input.getkeydown(KeyCode.Space) in C# and Unity

kinda new to coding so help would be appreciated. I'm trying to duplicate this GameObject "cube" in unity and I'm having trouble with it. what im trying to do is duplicate the cube and get it to stack on top of each other over and over.
I know if i got this to work it would duplicte it in the same postion so you would only see it duplicate in the higharchy.
using System.Collections;
using UnityEngine;
public class cube : MonoBehaviour
{
public GameObject cube1;
public void update()
if(input.getKeyDown(KeyCode.Space))
{
instantiate cube1;
}
}
I assume you know the height of the cube, you are working with. In unity the default height is 1.0f(For the primitive cube).
Btw if your code is a pseudo code then its okey but if not, you need more training before writing such scripts, even tho this type of script is extremely easy to write.
(ps: i wrote this script in notepad++ hope it compiles :/)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// We start classes with capital letters in c# its a convention :)
public class Cube : MonoBehaviour
{
// Same applies to public class fields & Properties
// Marking a MonoBehaviour field as public will allow you to directly assign values to it
// inside the editor
public GameObject OriginalCube;
// Same can be achieved with private fields using the serializefield attribute
[SerializeField]
private float cubeHeight = 1.0f;
// In case you would like to store the duplicated cubes
public List<GameObject> Cubes = new List<GameObject>();
private void Awake()
{
// Adding the first cube to the list, i assume your cube is already in the scene
Cubes.Add(OriginalCube);
}
private void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
{
// We instantiate a new cube and add it to the list
Cubes.Add(Instantiate(Cubes[Cubes.Count - 1]);
// We ask the previous cube position (the one we copied)
Vector3 previousCubePosition = Cubes[Cubes.Count - 2].transform.position;
// then we assign a new position to our cube raised by "1 unit" on the y axis which is the up axis in unity
Cubes[Cubes.Count - 1].transform.position =
new Vector3(previousCubePosition.x, previousCubePosition.y + cubeHeight, previousCubePosition.z);
}
}
}
One way you can have your goal achieved, is to add to your newly instantiated object's y position a constant amount. This constant amount will be increased each time you create a new duplicate of your object.
public GameObject cube1;
private int instantiateCounter = 0;
public float PULL_UP_AMOUNT = 30f;
public void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
instantiateCounter++;
GameObject newCube = Instantiate(cube1);
newCube.transform.position = new Vector3(cube1.transform.position.x, cube1.transform.position.y + instantiateCounter * PULL_UP_AMOUNT, cube1.transform.position.z);
}
}
The constant amount we're talking about is PULL_UP_AMOUNT.
Keep in mind, you can access your new duplicate's properties by saving the result of Instantiate method inside a new GameObject, just like I did.

Cannot apply indexing[] to an expression of type GameObject

I've got 3 empty Gameobjects in my scene that im trying to spawn objects on, i've written this script to have a RNG value between the spawners for the object to spawn.
I've run into a problem and im not too sure how to resolve it
public class Spawns : MonoBehaviour
{
public GameObject SpawnedObject;
public bool StopSpawn = false;
public float SpawnTime;
public float SpawnDelay;
public GameObject[] SpawnPoints;
int Randomint;
// Start is called before the first frame update
void Start()
{
InvokeRepeating("SpawnObjects", SpawnTime, SpawnDelay);
}
public void SpawnObjects()
{
Randomint = Random.Range(0, SpawnPoints.Length);
Instantiate(SpawnedObject[Randomint], transform.position, transform.rotation);
if (StopSpawn)
{
CancelInvoke("SpawnObjects");
}
}
}
You are trying to use an index on a single GameObject reference.
Since you pick the random value using SpawnPoints.Length and following your description you actually rather want to get an element of the array SpawnPoints instead.
Further you say
I've got 3 empty Gameobjects in my scene that im trying to spawn objects on
but that's not what your code would do.
You probably rather wanted to use
Instantiate(SpawnedObject, transform.position, transform.rotation, SpawnPoints[Randomint].transform);
See Instantiate and in your specific case the overload
public static Object Instantiate(Object original, Vector3 position, Quaternion rotation, Transform parent);
The first parameter is the original prefab/object to spawn, the last parameter is the optional parent Transform where to spawn to.
You also might want to rethink your provided values for position and rotation .. do you really want to spawn the object at the position and rotation of the object your script is attached to? Would you not rather want them to get spawned at the position and rotation of the according spawn point? ;)

Categories

Resources