is there a way to find if an object in an array has been destroyed? [duplicate] - c#

I'm creating a game and i want to show a panel when the player is dead
I've tried different approaches but none seems to do what I want
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DeadOrAlive : MonoBehaviour
{
public GameObject Player;
public GameObject deadPanel;
void Update()
{
if (!GameObject.FindWithTag("Player"))
{
deadPanel.SetActive(true);
}
}
}

To check if a object has been destroyed, you should use MonoBehavior's OnDestroy like so:
// Attach this script to the player object
public class DeadOrAlive : MonoBehaviour
{
public GameObject deadPanel;
void OnDestroy()
{
deadPanel.SetActive(true);
}
}
You can also instead of destroying the player object, set it to active/inactive, but to check if the player is dead or alive this way, you will need a separate object which checks the active state:
//Attach this to a object which isn't a child of the player, maybe a dummy object called "PlayerMonitor" which is always active
public class DeadOrAlive : MonoBehaviour
{
public GameObject deadPanel;
void Update()
{
if (!GameObject.FindWithTag("Player"))
{
deadPanel.SetActive(true);
}
}
}
Haven't used unity in a while and forgot how weird it could get.

Thanks to #VincentBree this is how I did it
void Update()
{
if (!Player.activeSelf)
{
deadPanel.SetActive(true);
}
}

Related

Can't access variable from another script

Assets\Scripts\Wood.cs(32,9): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement
Well I'm trying to take the bool hasTorch and put it in the script Wood.cs to know if the player has a torch or not.
(I'm new so it's probably easy to fix, I just don't know :c)
Script 1 (Chest.cs):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Chest : MonoBehaviour
{
public Sprite openChest;
public GameObject chest1;
public GameObject chestBox;
public GameObject torch;
public bool hasTorch = false;
public GameObject darkness;
public GameObject chatBox;
private void OnTriggerEnter2D(Collider2D other)
{
chest1.GetComponent<SpriteRenderer>().sprite = openChest;
torch.SetActive(true);
chatBox.SetActive(true);
darkness.SetActive(false);
chestBox.SetActive(false);
hasTorch = true;
}
public void Close()
{
chatBox.SetActive(false);
}
}
Script 1 (Wood.cs):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Wood : MonoBehaviour
{
public GameObject chestScript;
public Chest script;
public GameObject chatBox;
private void OnTriggerEnter2D(Collider2D other)
{
if (script.hasTorch == true)
{
chatBox.SetActive(true);
}
if (script.hasTorch == true)
{
chatBox.SetActive(true);
}
}
public void Close()
{
chatBox.SetActive(false);
}
void Start(){
chestScript.GetComponentInChildren<Chest>().hasTorch;
}
}
This line does not do anything (not a valid statement, as the error suggests):
chestScript.GetComponentInChildren<Chest>().hasTorch;
you could Log it or set it to true/false like this (a valid assignment):
chestScript.GetComponentInChildren<Chest>().hasTorch = false;
You have created a variable of type Chest but have not told Unity which Chest instance you want to access. Imagine you had a couple of GameObjects, all with this script attached, each with a different value for hasTorch. Unity wouldn't know which instance you have in mind, that is why you have to specifically assign the value.
All you have to do is to add this line into the Start() method:
script = someKindOfaGameObject.GetComponent<Chest>();
From now on you should be able to access all the public variables in the Chest script using script.variable syntax.

Hide all tagged GameObjects upon button click

Trying to combine these two:
https://answers.unity.com/questions/1171111/hideunhide-game-object.html
Show/ hide Unity 3D elements
I got this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Modify_Menu_Button_Handler : MonoBehaviour
{
void Start()
{
GameObject[] buttons_in_create_menu;
buttons_in_create_menu = GameObject.FindGameObjectsWithTag("CreateMenu");
}
public void ChangeMenu()
{
foreach (GameObject button in buttons_in_create_menu)
{
button.SetActive(false);
}
}
}
But, the foreach line is red-underlined, saying the buttons_in_create_menu doesn't exist in the current context.
Coming from Javascript, I'm not sure how scope works in C# and especially within Unity's game loop. Thought the Start() function would be called upon the scene loading, based on the Unity docs: link
You must define the variable globally in the class.
Like this:
public class Modify_Menu_Button_Handler : MonoBehaviour
{
public GameObject[] buttons_in_create_menu;
void Start()
{
buttons_in_create_menu = GameObject.FindGameObjectsWithTag("CreateMenu");
}
public void ChangeMenu()
{
foreach (GameObject button in buttons_in_create_menu)
{
button.SetActive(false);
}
}
}

Is there a way to check if a GameObject has been destroyed?

I'm creating a game and i want to show a panel when the player is dead
I've tried different approaches but none seems to do what I want
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DeadOrAlive : MonoBehaviour
{
public GameObject Player;
public GameObject deadPanel;
void Update()
{
if (!GameObject.FindWithTag("Player"))
{
deadPanel.SetActive(true);
}
}
}
To check if a object has been destroyed, you should use MonoBehavior's OnDestroy like so:
// Attach this script to the player object
public class DeadOrAlive : MonoBehaviour
{
public GameObject deadPanel;
void OnDestroy()
{
deadPanel.SetActive(true);
}
}
You can also instead of destroying the player object, set it to active/inactive, but to check if the player is dead or alive this way, you will need a separate object which checks the active state:
//Attach this to a object which isn't a child of the player, maybe a dummy object called "PlayerMonitor" which is always active
public class DeadOrAlive : MonoBehaviour
{
public GameObject deadPanel;
void Update()
{
if (!GameObject.FindWithTag("Player"))
{
deadPanel.SetActive(true);
}
}
}
Haven't used unity in a while and forgot how weird it could get.
Thanks to #VincentBree this is how I did it
void Update()
{
if (!Player.activeSelf)
{
deadPanel.SetActive(true);
}
}

How could i fix an error (cs0120) in unity?

In unity, I'm trying to make a press of a button increase the speed of the player. However, each time I run it. It gives me:
Error CS0120: An object reference is required for the non-static
field, method, or property 'PlayerController.speed'
I've already tried changing order of the code, so what could I do?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Upgrader1 : MonoBehaviour
{
void Start()
{
GameObject Player = GameObject.Find("Player");
PlayerController PlayerController = Player.GetComponent<PlayerController>();
}
public void Upgrade1()
{
PlayerController.speed++;
}
}
public class Upgrader1 : MonoBehaviour
{
PlayerController PlayerController; //It should be member variable
void Start()
{
GameObject Player = GameObject.Find("Player");
PlayerController = Player.GetComponent<PlayerController>();
}
public void Upgrade1()
{
PlayerController.speed++;
}
}
it's always a good thing to use proper naming conventions.
PlayerController _PlayerController;
void Start() {
GameObject Player = GameObject.Find("Player");
_PlayerController = Player.GetComponent<PlayerController>();
}
public void UpgradeSpeed() // I changed the name according to its functionality
{
_PlayerController.speed++;
}
With this, you won't put PlayerController class reference again by mistake.

animation.Play() doesn't work

I'm pretty sure that
animation.Play("DoorOpen");
Would play the animation "DoorOpen", but when i'm trying to put it in my code, it just giving me an error message:
The Animation attached to this GameObject (null if there is none attached).
using UnityEngine;
using System.Collections;
public class DoorPhysics : MonoBehaviour {
int Open = 0;
// Update is called once per frame
void Update() {
if (Open == 0) {
if (Input.GetKeyDown("e")) {
animation.Play("DoorOpen");
}
}
}
}
You need to show location of gameobjects in unity, they do not know eachother, you have to always use :
GameObject.GetComponent<T>()
GetComponentInParent<T>()
GetComponentInChildren<T>()
best practice is to get object references at Start()
also you should attach IMPORTANT!!! Animation component to the object this script it attached to
public class DoorPhysics : MonoBehaviour {
public Animation animation;
int Open = 0;
void Start()
{
animation=GameObject.GetComponent<Animation>(); //if your have derived type change Animation to good class DoorAnimation for example
}
void Update()
{
if (Open == 0) {
if (Input.GetKeyDown("e")) {
this.animation.Play("DoorOpen");
}
}
}
}
if that code wont work, you will need show me your GameObject hierarchy
And if your just start your trip with it learn MonoBehaviour call order
and life cycles of events

Categories