I am just trying to activate game over screen when the Player's activate is 'false'. There is no animation, just the
There are 3 objects that need to be active and i added the script to those 3 objects but the screen does not appear.
How can i fix?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameOverManager : MonoBehaviour
{
public GameObject _player;
void Start()
{
_player = GameObject.FindGameObjectWithTag("Player");
}
void Update()
{
if (_player.activeInHierarchy == false)
{
gameObject.SetActive(true);
}
else
{
gameObject.SetActive(false);
}
}
}
My suspicion is the following. Whenever a Gameobject is not enabled, its code does not run. Test this by adding a Debug.Log("test") message.
If no message appears you can be certain that this check is never evaluated. To work around this simply add a script that is bound to an active gameObject. Creat a new empty gameobject in the scene. And add something like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameOverManager : MonoBehaviour
{
public GameObject _player;
public GameObject _endscreen;
void Update()
{
if (_player.activeInHierarchy == false)
{
_endscreen.SetActive(true);
}
else
{
_endscreen.SetActive(false);
}
}
}
Assign the Variables in the Inspector by dragging the object to the empty fields. Never use GameObject.Find Methods.
If you need any further help tell me :)
What you're currently doing is to find a single GameObject and checking whether that is active or not.
It would make more sense, and be more optimized, if each player object adds himself to a list of all players when he spawns. You can then loop over that list instead to check all players.
An even better way would be if you only call that "GameOver" check after a player has died. So when you call whichever method kills him.
Based on Franz Answer, I did some modification in the code. You won't need any if else statement if you use a shortcut.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameOverManager : MonoBehaviour
{
public GameObject _player;
public GameObject _endscreen;
void Update()
{
_endscreen.SetActive(!_player.activeInHierarchy);
}
}
Related
I need to destroy an object, in my case is "Player2" witch is in the same scene as "Player1" and then after Player1 position.x is past "baraj".position.x reapear. Basically how can i make a temporarly destroy method.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class switchCameras2 : MonoBehaviour
{
public GameObject baraj;
public GameObject CameraOne;
public GameObject CameraTwo;
public GameObject Player1;
public GameObject Player2;
public void Start()
{
CameraOne.SetActive(true);
CameraTwo.SetActive(false);
}
void Update()
{
if (GameObject.Find("Player1").transform.position.x > GameObject.Find("baraj").transform.position.x)
{
CameraTwo.SetActive(true);
CameraOne.SetActive(false);
}
if (GameObject.Find("Player1").transform.position.x < GameObject.Find("baraj").transform.position.x)
{
Destroy(Player2);
}
if (GameObject.Find("Player1").transform.position.x > GameObject.Find("baraj").transform.position.x)
{
Destroy(Player1);
}
}
}
If you want to Destroy it then you should make a new one with Instantiate method. If you don't want to Destroy it, one alternative is to deactivate it with SetActive like this Player1.SetActive(false); and then enable it like this Player1.SetActive(true);
Try creating a new GameObject variable called "U". And then right before destroying or in the start do U = player2.gameObject;
Now let's say you destroyed it and want to spawn. To do that we do
player2 = U.gameObject;
Instantiate(player2);
That will spawn player 2.
But as mentioned in the other answer .SetActive(false); would make things easier. Anyway if you still want to use destroy then that is how to do that. Good luck
I've used this code to stop destroying a specific game object. The problem is when i change the scene that contain this object to another different scene ,the game object still showing even in different scene...
How to only show the game object in its scene.
I hope that I clearly specify my problem.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DontDestroy : MonoBehaviour {
void Awake() {
DontDestroyOnLoad(this.gameObject);
if(FindObjectsOfType(GetType()).Length > 1) {
Destroy(gameObject);
}
}
}
You can try doing something like this:
m_Scene = SceneManager.GetActiveScene();
sceneName = m_Scene.name;
//Do logic by checking the specific scene you want
if (sceneName == YOUR_SCENE) {
this.gameObject.SetActive(false); //Set false to hide, true to show
}
I am working on a 3D game on Unity but recently a problem occurred. I can't access a variable from another prefab's script. I tried it before when the object which has to be accessed wasn't a prefab and it worked correctly.
This is the script which tries to access the "slashtime" variable, but when I run it gives back 0 though in the other script the variable is changing continuously.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class collision : MonoBehaviour
{
public GameObject sword;
public float slashtime;
private void Update()
{
slashtime=sword.GetComponent<movement>().slashtime;
}
private void OnTriggerEnter(Collider collider)
{
if (collider.tag == "sword" && slashtime+1f > Time.time)
{
Destroy(gameObject);
}
}
}
You can use this. It is also working.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class collision : MonoBehaviour
{
public GameObject sword;
public float slashtime;
private void OnTriggerEnter(Collider collider)
{
sword = collider.gameObject;
slashtime=sword.GetComponent<movement>().slashtime;
if (collider.tag == "sword" && slashtime+1f > Time.time)
{
Destroy(gameObject);
}
}
}
Reason for your code is not working because when you write some code in update then it calls every frame. so when your object is destroyed, update call that code and it shown error.
Reworking your code a bit, with explanations below:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class collision : MonoBehaviour
{
[SerializeField]
private GameObject _sword;
private float _slashTime;
private void Start()
{
_slashTime = GameObject.Find("Movement").GetComponent<Movement>().GetSlashTime();
}
private void OnTriggerEnter(Collider collider)
{
if (collider.CompareTag("sword") && _slashTime + 1f > Time.time)
{
Destroy(gameObject); // What is gameObject in this context? the _sword? something else?
}
}
}
Use private properties. Why? Because it increases modularity and protects the object(s) you're working with from accidentally having their values overwritten.
In conjunction to this, use public methods to obtain/change the values in other objects. Public methods are your API.
It's convention to begin the names of private properties with an underscore.
Like I said in my comment above, you first need to Find() your desired object before you can attempt to GetComponent<T>().
Like others have said, attempting to GetComponent<T>() in Update() is computationally expensive. It's better to get that component at Start() and then talk to it as necessary (in this case, during collision).
CompareTag() is the more modern/accepted way to check a tag.
EDIT:
[SerializeField] will keep the property private while also making it available to the Unity editor. It's good for debugging and linking objects.
I try to create a shop system where you can buy a character to play with. When I buy a character in the Shop Scene, the bool value in the Inventory script is set to true. When I switch to the Level1 Scene, my character is not spawned. I suppose there is a bug in my GameManager script but I can not find it. Can you please help me? I do not know any more.
GameManager script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public GameObject Joli;
public GameObject Ninn;
public GameObject Spaci;
public GameObject Woodie;
public GameObject Plumbt;
public GameObject canvasObject;
public Inventory myInventory;
// Start is called before the first frame update
void Start()
{
myInventory = GameObject.FindObjectOfType<Inventory>();
if (myInventory.GetNinn() == true)
{
GameObject Ninnnew = Instantiate(Ninn, Ninn.transform.position, Quaternion.identity) as GameObject;
Ninnnew.transform.SetParent(canvasObject.transform, false);
}
if (myInventory.GetSpaci() == true)
{
GameObject Spacinew = Instantiate(Spaci, Spaci.transform.position, Quaternion.identity) as GameObject;
Spacinew.transform.SetParent(canvasObject.transform, false);
}
}
}
There is currently not enough information / code in your question, but when you change scene, your objects are destroyed by default, and new ones are isntantiated, effectively resetting any values that are set in them.
You need to prevent your Inventory or any object holding data you need to keep that it should not be destroyed when switching scenes, by using DontDestroyOnLoad for instance :
https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html
The current error : NullReferenceException: Object reference not set to an instance of an object BackboardTrigger.OnTriggerEnter (UnityEngine.Collider altCollider) (at Assets/Scripts/BackboardTrigger.cs:10)
I believe my question is different from, What is a NullReferenceException, and how do I fix it?, because it requires a narrow answer. The other post provides a broad scope of what a NullReferenceException is while I need to know how to connect more than two triggers.
I'm a novice in C# and I'm attempting to recreate a simple basketball game. As of now I'm trying to trigger a score for when the ball hits the backboard first and sequentially enters the hoop. The tutorial currently teaches how to trigger a score for when the ball begins to enter the hoop and reaches near the bottom of it.
Right now when the ball enters the hoop through the first trigger(PrimaryTrigger) and sequentially through the second(SecondaryTrigger) a score is triggered.
I'm trying to cause a different scoring action for when the ball hits the backboard first.
My PrimaryTrigger Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PrimaryTrigger : MonoBehaviour {
void OnTriggerEnter(Collider collider)
{
SecondaryTrigger trigger = GetComponentInChildren<SecondaryTrigger>();
trigger.ExpectCollider(collider);
}
}
SecondaryTrigger Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SecondaryTrigger : MonoBehaviour {
Collider expectedCollider;
Collider possibleCollider;
public void ExpectCollider(Collider collider)
{
expectedCollider = collider;
}
public void PossibleCollider(Collider altCollider)
{
possibleCollider = altCollider;
}
void OnTriggerEnter(Collider otherCollider)
{
if(otherCollider == expectedCollider && otherCollider == possibleCollider)
{
ScoreKeeper scoreKeeper = FindObjectOfType<ScoreKeeper>();
scoreKeeper.IncrementScore(1);
}
else if(otherCollider == expectedCollider)
{
ScoreKeeper scoreKeeper = FindObjectOfType<ScoreKeeper>();
scoreKeeper.IncrementScore(2);
}
}
}
BackboardTrigger Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BackboardTrigger : MonoBehaviour {
void OnTriggerEnter(Collider altCollider)
{
SecondaryTrigger newTrigger = GetComponent<SecondaryTrigger>();
newTrigger.PossibleCollider(altCollider);
}
}
Any form of help would be greatly appreciated. My first game in Unity.