Array index is out of range? also my clone stars disappear once i click reset need help
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;
public class Reset : MonoBehaviour {
public static bool reset = false;
public Transform[] startingLocation;
public GameObject[] whatToSpawnPrefab;
public GameObject[] whatToSparnClone;
public GameObject Player;
public GameObject oldstar;
public GameObject oldstar1;
public GameObject oldstar2;
public GameObject oldstar3;
public Rigidbody2D P1;
public Text Sc;
public void RestartButtonClicked()
{
// reset
reset = true;
//reset score
ScoreManager.Score = 0;
Destroy (this.oldstar);
Destroy (this.oldstar1);
Destroy (this.oldstar2);
Destroy (this.oldstar3);
//reset player
P1.velocity = Vector2.zero;
P1.angularVelocity = 0;
Player.transform.position = new Vector2 (0f, 0.4f);
Player.transform.eulerAngles = Vector3.zero;
//reset stars
whatToSparnClone[0] = Instantiate(whatToSpawnPrefab[0], startingLocation[0].transform.position, Quaternion.Euler(0.505f,0.417f,0)) as GameObject;
whatToSparnClone[1] = Instantiate(whatToSpawnPrefab[1], startingLocation[1].transform.position, Quaternion.Euler(-0.497f,0.417f,0)) as GameObject;
whatToSparnClone[2] = Instantiate(whatToSpawnPrefab[2], startingLocation[2].transform.position, Quaternion.Euler(0.007f,0.815f,0)) as GameObject;
whatToSparnClone[3] = Instantiate(whatToSpawnPrefab[3], startingLocation[3].transform.position, Quaternion.Euler(0.007f,0.017f,0)) as GameObject;
reset = false;
}
// Update is called once per frame
void Update ()
{
}
}
Answer by TBruce · Jan 06, 2017 at 09:01 PM
You do not give much to go on. Since all I have is your script and I do not even know where exactly you are getting errors at here is what I have done
Changed
whatToSparnClone
from anArray
to aList
.Changed
Player.transform.position = new Vector2 (0f, 0.4f);
toPlayer.transform.position = new Vector3 (0f, 0.4f, 0);
. Though you are creating a 2D game, the position is still a Vector3.To remove the possibility of an error and add some range checking I created the function
SpawnObject
which takes the two array indexes and the Quaternion values for parameters. If the indexes are within range of their prospective arrays then the object is instantiated, else a an error message is sent to the console.using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;
public class Reset : MonoBehaviour {
public static bool reset = false; public Transform[] startingLocation; public GameObject[] whatToSpawnPrefab; public List<GameObject> whatToSparnClone = new List<GameObject>(); public GameObject Player; public GameObject oldstar; public GameObject oldstar1; public GameObject oldstar2; public GameObject oldstar3; public Rigidbody2D P1; public Text Sc; public void RestartButtonClicked() { // reset reset = true; //reset score ScoreManager.Score = 0; Destroy (this.oldstar); Destroy (this.oldstar1); Destroy (this.oldstar2); Destroy (this.oldstar3); //reset player P1.velocity = Vector2.zero; P1.angularVelocity = 0; Player.transform.position = new Vector3 (0f, 0.4f, 0); Player.transform.eulerAngles = Vector3.zero; //reset stars whatToSparnClone.Clear(); SpawnObject(0, 0, Quaternion.Euler(0.505f,0.417f,0)); SpawnObject(1, 1, Quaternion.Euler(-0.497f,0.417f,0)); SpawnObject(2, 2, Quaternion.Euler(0.007f,0.815f,0)); SpawnObject(3, 3, Quaternion.Euler(0.007f,0.017f,0)); reset = false; } void SpawnObject (int prefabIndex, int locationIndex, Quaternion quaternion) { if (prefabIndex < whatToSpawnPrefab.Length) { if (locationIndex < startingLocation.Length) { whatToSparnClone.Add(Instantiate(whatToSpawnPrefab[prefabIndex], startingLocation[locationIndex].transform.position, quaternion) as GameObject); } else { Debug.LogError("Starting location index ( " + locationIndex + " ) need to be less than " + startingLocation.Length); } } else { Debug.LogError("Spawn prefab index ( " + prefabIndex + " ) need to be less than " + whatToSpawnPrefab.Length); } } // Update is called once per frame void Update () { } }
The script above is tested with no errors. Note: I had to comment out this line to test
ScoreManager.Score = 0;
hi thank for this info :) the trouble i am having is that once i click the reset but im trying to delete the oldstars in which are in the current scene then replace them with newstars(prefab) so like a scene reset but when i click the reset the newstar appear and the oldstar just move slightly because of the box collider attached even though they should be destroyed on every reset clicked.
i have just tried your script and it has solved the main issue of making my newstars appear in there location which is great and thanks.
however if all the stars are on the screen and i click reset i get 4 stars on each click of the reset, but once one of the stars are destroyed in the runtime i get the error message "the object of the Gameobject has been destroyed but you are still tring to access it" when i click the reset and no extra stars appear and im left with the 3 of the oldstars in whatever position they were left in.
however if all the stars are on the screen and i click reset i get 4 stars on each click of the reset.
thanks for the help much appreciated
I did not know what oldstar, oldstar1, oldstar2 & oldstar3
were or what they were used for as there was no other reference to them other than the Destroy()
calls.
Try the following updated script. It removes the oldStar
references and if the list was previously populated with stars it will destroy the stars in the list, which basically destroys them on the screen, then it clears the list and then repopulates it.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Reset : $$anonymous$$onoBehaviour {
public static bool reset = false;
public Transform[] startingLocation;
public GameObject[] whatToSpawnPrefab;
public List<GameObject> whatToSparnClone = new List<GameObject>();
public GameObject Player;
public Rigidbody2D P1;
public Text Sc;
public void RestartButtonClicked()
{
// reset
reset = true;
//reset score
Score$$anonymous$$anager.Score = 0;
//reset player
P1.velocity = Vector2.zero;
P1.angularVelocity = 0;
Player.transform.position = new Vector3 (0f, 0.4f, 0);
Player.transform.eulerAngles = Vector3.zero;
//reset stars
if (whatToSparnClone.Count > 0)
{
for (int i = 0; i < whatToSparnClone.Count; i++)
{
if (whatToSparnClone[i] != null)
{
Destroy(whatToSparnClone[i]);
}
}
}
whatToSparnClone.Clear();
SpawnObject(0, 0, Quaternion.Euler(0.505f,0.417f,0));
SpawnObject(1, 1, Quaternion.Euler(-0.497f,0.417f,0));
SpawnObject(2, 2, Quaternion.Euler(0.007f,0.815f,0));
SpawnObject(3, 3, Quaternion.Euler(0.007f,0.017f,0));
reset = false;
}
void SpawnObject (int prefabIndex, int locationIndex, Quaternion quaternion)
{
if (prefabIndex < whatToSpawnPrefab.Length)
{
if (locationIndex < startingLocation.Length)
{
whatToSparnClone.Add(Instantiate(whatToSpawnPrefab[prefabIndex], startingLocation[locationIndex].transform.position, quaternion) as GameObject);
}
else
{
Debug.LogError("Starting location index ( " + locationIndex + " ) need to be less than " + startingLocation.Length);
}
}
else
{
Debug.LogError("Spawn prefab index ( " + prefabIndex + " ) need to be less than " + whatToSpawnPrefab.Length);
}
}
// Update is called once per frame
void Update ()
{
}
}
with this script im getting the error "destroying assets is not permitted to avoid data loss. and then the same message when 1 of the stars has been destroyed in runtime to reset about accessing a gameobject which has been destroyed
I am sorry that you are still having issues with this.
Looking at the current script there should be no problems. Destroy()
is only called if
if (whatToSparnClone[i] != null)
and i
must be valid because it is in the for
loop. Even if the object whatToSparnClone[i]
was destroyed somewhere else the if
statement makes sure that it is valid before it tries to destroy it.
whatToSparnClone
is a public variable, are you doing anythingYou say you are getting the error
destroying assets is not permitted to avoid data loss
and then when one of your stars are destroyed - could you look at the console and see exactly what class file and line the error(s) occur on?
Remember, I removed oldstar, oldstar1, oldstar2 & oldstar3
from the Reset
class so if they were being used somewhere else then you need to make changes so that they are no longer referred to.
You could also provide the script file that used oldstar, oldstar1, oldstar2 & oldstar3
.
Hi Tbruce you are a greast help i spent a couple of hours getting my head around your amendments and they all make sence and has giving me a better understanding to what i need and how i should approach this in the future when needed :), the reference to oldstar was only in this script as i didnt have a full understanding on how i should do a reset but making a clone and destroying that make so much more sence than destroying the origanal what a noob.
for the destroying assets issue i was reading the error code and it said about changing it to DestroyImmediate ins$$anonymous$$d of Destroy so that doesnt seem to be an issue popping up so it looks like this :-
if (whatToSpawnClone[i] != null)
{
DestroyImmediate(whatToSpawnClone[i],true);
}
}
}
but still not sure if that has solved that issue and created another with destroying all the stars on reset!!!!
however im getting an issue on line 61:- whatToSpawnClone.Add(Instantiate(whatToSpawnPrefab[prefabIndex], startingLocation[locationIndex].transform.position, quaternion) as GameObject);
with accessing a destroyed gameobject any suggestion?
i did post it as another question as its a different problem to the origanal question!!
thanks for your help again!!!!!
Hi @lux-trails, You should not be using DestroyImmediate()
, especially in a loop. You should use Destroy()
ins$$anonymous$$d (see the docs on DestroyImmediate). DestroyImmediate
is should be used in editor code.
In the meantime could you please be so kind as to click the "Accept" button above to accept the answer if you found this answer helpful? Thank you!
@TBruce. you have been a great help and thanks for putting me on the right path i will take the DesroyImmediate out i was just trialing it when the error code first came up and yeah wasn't the answer.
however still getting that error about accessing a destroyed game object on line 61 which is below:-
whatToSpawnClone.Add(Instantiate(whatToSpawnPrefab[prefabIndex], startingLocation[locationIndex].transform.position, quaternion) as GameObject);
Hi @lux-trails,
Is this happening the first time Reset
is called or does this happen on subsequent calls? What prefabIndex/locationIndex does this error occur at?
From only having this one script and not seeing the rest of your project I can only assume one of the following
whatToSpawnPrefab[prefabIndex]
does not have a valid prefab object and is null/empty. The array is withing bounds but the index needs to be set in the inspector.Somewhere along the line
whatToSpawnPrefab[prefabIndex]
was deleted/destroyed.
Here is a modified version of my last script, I put the rotations
in an array and added some extra debugging (as always this compiles by itself)
it happens on the first reset when all stars are on the screen but when i destroy one in runtime i get the message trying to access a destroyed object.
iv attacted a picture of the attachment for this script probly that is whats wrong like you said!!! i am a noob :/
thanks again
I see what the problem is, you need to set/default the size of whatToSparnClone
zero.