Unity Respawning Setting Objects back active - c#

The project is made in Unity 2D.
I am working on a unity Project where I respawn my items, after the player ran through the level. When he does not have all the emeralds he will respawn at the start of the level and I want Items to respawn for him.
So for now I am using:
void OnCollisionEnter2D (Collision2D col)
{
if (col.gameObject.CompareTag("Life"))
{
col.gameObject.SetActive(false);
}
}
The Objects are inside an empty Object for clarification. I make them the child of the empty Object "Items".
if (ManagerVariables.IsRespawning)
{
if (item!= null)
{
for (int a = 0; a < item.transform.childCount; a++)
{
item.transform.GetChild(a).gameObject.SetActive(true);
}
}
else
{
Debug.LogError("No Objects Over Class defined");
}
I already checked for the variable IsRespawning and it
is set to true when the player respawns or dies, but the
objects do not reappear.
As well I want to ask about object with multiple child objects how to do that
e.g. Enemy with FirePoint attached

The code should be working generally.
My suggestion is to check whether item has a value. Maybe item is always null and your loop never gets executed.
If item is not null I would check the child count and make sure it is larger than 0.
Regarding your question with multiple child objects, you could either disable every child individually or disable the parent, then all the children also disabled.

Related

check list of gameobject has active gameobject and insert into other list

i have a list of gameobject and I would like to check if each of those is currently active in the scene. The following is my code.
foreach (GameObject hazard in SceneHazard)
{
//Check if hazard exist in the scene
Debug.Log(hazard.name);
if (hazard.activeInHierarchy)
{
Debug.Log(" is active");
allActiveHazard.Add(hazard);
}
else
{
Debug.Log(" is NOT active");
}
}
I also found other solution, which I've applied: https://stackoverflow.com/a/65934000/9425428 which would then be something like this:
allActiveHazard = SceneHazard.Where(obj => obj.activeInHierarchy).ToList();
but I still only get around two gameobjects inside the new list.
Variables assignment in inspector, the two list on the bottom are private
Active gameobjects in hierarchy
Console, somehow some gameobjects weren't checked?
Am I missing anything here? There are no other inactive parents from the screenshot provided
I added a few seconds delay before assigning the list. Probably somebody added animation to the GameObject.
StartCoroutine(Delay());
...
...
IEnumerator Delay()
{
yield return new WaitForSeconds(0.1f);
allActiveHazard = SceneHazard.Where(obj => obj.activeSelf).ToList();
}
Btw, I edited my code in response to #derHugo comment because I made some typos previously. Assigning inside the coroutine

Selecting random positions from array without duplicates

In my game, there are many enemies and have this script on it, where I am set their navmesh destination by randomly selecting an element from an array of positions. However, sometimes all enemies go at same position, so I am trying to skip previously generated array indices and find a new index. Any suggestions for this? I don't want to use the goto statement.
Here is code I have done so far:
void move_on_fired_positions()
{
navmesh.Resume ();
again:
new_position = Random.Range (0, firedpoints.Length);
if (prev_num != new_position) {
navmesh.SetDestination (firedpoints [new_position].position);
prev_num = new_position;
} else
{
goto again;
}
}
One thing you can try is keeping a dynamic list of available positions, rather than an array. (Don't worry - they're both serialized and modified the same way in the Unity editor interface.) This way, you can remove positions from the list as they are assigned to enemies, ensuring you never assign duplicates. Here's an idea of how that might look:
public List<Transform> firedpoints;
// Returns available firing position, if any
public Transform GetRandomFiringPosition()
{
if (firedpoints.Count > 0)
{
// Get reference to transform, then remove it from list
int newPositionIndex = Random.Range (0, firedpoints.Length);
Transform returnedPosition = firedpoints[newPositionIndex];
firedpoints.RemoveAt(newPositionIndex);
return returnedPosition;
}
else
{
// Or you can specify some default transform
return null;
}
}
// Makes firing position available for use
public void RegisterFiringPosition(Transform newPosition)
{
firedpoints.Add(newPosition);
}
This code should be in a script on a single object in the scene, which the enemies should have a reference to (or, you can change the code a little and make the class into a singleton, so its methods can be called without a direct reference). Whenever an enemy needs a new position, it can call GetRandomFiringPosition() and store the returned Transform in a variable for future reference.
You haven't determined what conditions make a position available for use again, but when you have, you can call RegisterFiringPosition() to get it back into the list. As a nice side effect, this also makes it possible to assign brand new positions to enemies, for example in response to player-triggered events.
Hope this helps! Let me know if you have any questions.

Enable object Parent in the hierarchy

How do I get an object in the hierarchy is enabled through scrip?
void OnCollisionEnter2D (Collision2D colisor)
{
if (colisor.gameObject.tag == "Floor") {
Destroy (gameObject, 0.6f);
} else {
if (colisor.gameObject.tag == "Bee") {
coinCollectSound.Play ();
heart = GameObject.FindGameObjectWithTag ("Hearts").GetComponent<Hearts> () as Hearts;
if (heart.TakeHeart ()) {
Destroy (gameObject);
} else {
//Here i want setActive(true) Object parent in hierarchy called "GameOver"
//And setActive(false) Object in hierarchy Called "Game"
}
}
}
}
I do not want to call a different scene for the Game Over, but now I just want to enable it.
You should access the GameOver using GameObject.Find("GameOver"), but if it's disabled you won't be able to do that. Instead, create a public GameObject variable on a enabled script that references the object you wanna SetActive. Then, find the object by type and access it's variable, enabling it.
Since this is a gameover object you could probably get away with simply calling
GameObject.Find("GameOver").SetActive(true);
GameObject.Find("Game").SetActive(false);
However this will have performance implications if there are many objects in your game.
To disable the parent of GameObject the script is attached:
transform.parent.gameObject.setActive(true);
To get specific GameObjects use a public variable and link them in the Inspector. To improve performance avoid using GameObject.Find.

Enabling Game objects

So I've been trying to access game objects in my scene (which are disabled), to enable them. But I'm getting an error: "Object reference not set to an instance of an object"
private List<Character> characters = new List<Character>();
private List<GameObject> characterGameObjects = new List<GameObject> ();
public void loadSceneCharacters(){
if (characters != null) {
for(int i = 0; i < characters.Count; i++){
characterGameObjects.Add(GameObject.Find(characters[i].CharacterName));
characterGameObjects[i].SetActive(true);
}
}
}
You can't find disabled gameobjects.
A solution is to either reference them in inspector or find them all first when they are enabled, then disable those you don't need.
I think your characters list is empty.
If you don't Instantiate GameObjects you can fill characters list with drag and drop so you can change code like this.
public List<Character> characters = new List<Character>(); ///Thanks to public
//you can see list in Unity Editor
private List<GameObject> characterGameObjects = new List<GameObject> ();
public void loadSceneCharacters(){
if (characters != null) {
for(int i = 0; i < characters.Count; i++){
characterGameObjects.Add(characters[i])); //get and add gameobject
characterGameObjects[i].SetActive(true);
}
}
}
If you have dynamically created GameObjects you can fill the list with GameObject.Find("CharacterName");
However, i dont suggest that find every gameobject with name.Instead of that, During the Instantiate state you can add new gameObject instance to your character list.
Even if the character list would be empty this code would not throw an exception.
The problem is probably that you can not find disabled gameobject using the find methods (at least that was my experience, correct me if i am wrong guys).
What i usually do as a workaround instead of searching is to add the gameobjects via drag and drop. If this is not possible you can either, search for the gameobjects in Awake or Start, add them to your list and disable them. Or do some sort of adding when you instanciate them... Basicly you have to somehow get the reference to the gameobjects before you disable them.
Hope this helps.
Something that can help you is to create an empty object, then put all your characters inside the empty object.. then by code do something like:
foreach(Character c in MyEmptyObject.GetComponentsInChildren(Character, true))//the true in this
//line indicates that it should search for inactive objects
{
c.gameObject.SetActive(true);
}
this assuming that your characters have an script called "Character"

how to delete only one clone of a game object

For example I have coin1(clone) and coin1(clone)(clone). If I click coin1(clone)(clone) it will be destroyed. But in my case, when I click coin1(clone)(clone), coin1(Clone) is deleted.
Codes I've been using
void NumberOfSelectedCoins()
{
Debug.Log (BlueCoinScript.b);
if(SelectedCoins.cntCoins%BlueCoinScript.b == 0)
{
for (int n=0;n<selectC.selectedNumCoins.Count; n++)
{
Destroy(selectC.selectedNumCoins[n]);
TotalSum.totalValue = 0;
SelectedCoins.breakPointsCount++;
}
breakpointsText.text = SelectedCoins.breakPointsCount.ToString ();
selectC.selectedNumCoins.Clear();
}
}
And also if you have 1 game object and you cloned it so that you can have 3 same game objects, how can you identify that when you clicked that game object, that game object is clone1 or clone2 or clone3?
You can for example identify GameObject instances by Object.GetInstanceID() or by Object.name. In the latter case though you have to take care that the object you search for is named and that this name is unique.
Further reference is found here.

Categories

Resources