I am making a restart button in unity to restart the game, but the problem is that the button won't appear again after I have hidden it during the game.
Here is the code of the button:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class restartButtonScript : MonoBehaviour
{
public GameObject Player;
public Button restartButton;
public GameObject restartButtonObject;
// Start is called before the first frame update
void Start()
{
gameObject.SetActive(false);
}
// Update is called once per frame
void Update()
{
if (Player.GetComponent<playerScript>().playerEliminated == true)
{
gameObject.SetActive(true);
}
else if (Player.GetComponent<playerScript>().playerEliminated == false)
{
gameObject.SetActive(false);
}
}
}
If Game Object is inactive, its update won't be called, that's why you aren't seeing your button appear.
Turn off buttons graphics instead of disabling whole gameObject.
Alternatively you can can create an empty parent to your button, attach restartButtonScript to it, and turn off just child gameObject with button. gameObject with script will be active, so its update will be running as well.
Also, you could make it active from another script, but that's not needed there.
Related
I've been using Unity to create a simple 2D game but the problem is that even when the game object "player" gets destroyed, the gameobject "isDead" (text) doesn't appear.
This is my script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class youDied_Text : MonoBehaviour
{
private Transform player;
private Text isDead;
// public static bool isDead;
// Start is called before the first frame update
private void Start() {
isDead = GetComponent<Text>();
}
void checkForDeath()
{
if (player==false)
{
isDead.gameObject.SetActive(true);
}
else
{
isDead.gameObject.SetActive(false);
}
}
// Update is called once per frame
void Update()
{
player = GameObject.FindWithTag("Player").transform;
checkForDeath();
}
}
This script is attached in the text which I need to display in UI element.
As was noted currently you would get a NullReferenceException which is definitely not what you want.
There is absolutely no need / redundancy going through Transform at all actually. Simply store the GameObject reference instead
You are currently setting the object to inactive which has the Text attached ... which is the same object your component is attached to as well!
=> As soon as you end up in the second case once you set it to inactive => from now on Update is never called anymore!
In general as it sounds like this should only happen once anyway I would use a more event driven approach and have a component on your player like e.g.
public class Player : MonoBehaviour
{
public UnityEvent onDied;
private void OnDestroy ()
{
onDied.Invoke();
}
}
And then simply attach a listener/callback to that event once without poll checking states. You can do this either via the Inspector directly (just like in e.g. Button.onClick) or via code like e.g.
public class youDied_Text : MonoBehaviour
{
// Already reference things via the Inspector if possible!
[SerializeField] private GameObject player;
[SerializeField] private Text isDead;
private void Awake()
{
if(!isDead) isDead = GetComponent<Text>();
isDead.gameObject.SetActive(false);
// If you want to rather set it via the Inspector remove all the rest here
//if(!player) player = GameObject.FindWithTag("Player"). GetComponent<Player>();
// or even simpler
if(!player) player = FindObjectOfType<Player>();
player.onDied.AddListener(OnPlayerDied);
}
// If you want to rather set it via the Inspector make this public
private void OnPlayerDied()
{
isDead.gameObject.SetActive(true);
}
}
Currently, my code allows the player to go to the next scene by clicking. I want to, however, make the fade out into the next scene animation automatic after 4 seconds. How can I do this?
I've tried looking up information, but nothing seems to work.
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;
public class LevelChanger : MonoBehaviour
{
// Start is called before the first frame update
float timer = 4f;
public Animator animator;
private int levelToLoad;
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Invoke("FadeToLevel(1)", 2f);
}
}
public void FadeToLevel (int levelIndex)
{
levelToLoad = levelIndex;
animator.SetTrigger("FadeBlack");
}
public void OnF`enter code here`adeComplete()
{
SceneManager.LoadScene(levelToLoad);
}
}
The code works as intended, but I want the animation to happen automatically.
If I understood correctly, what you are aiming is to make an animation to play automatically when the player enters the new scene.
If that's the case, then you are looking for the sceneLoaded() method from SceneManager
Also, this discussion may be useful
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);
}
}
I'm doing an android 2d platformer. In the Animator everything is set up. On applicaton start does everything right but when I click on the button the bool parameter does not change so my animation won't play backwards. But when I tick the bool parameter in the animator the animation plays right as it should. No console errors. Here is my script.
I was using this tutorial and from it I just needed the first part (the "Start game" animation part). I followed every step. Probably I'm missing something.
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine.UI;
using UnityEngine;
public class UIManager : MonoBehaviour
{
public Animator optionsButton;
public void OpenSettings()
{
optionsButton.SetBool("isHidden", false);
}
}
My goal is to play the animation backward when the option button is pressed and I want to change the bool parameter through a script.
The problem was that the script was trying to change the bool on a canvas child element object. And there wasn't a bool. So I altered the existing script to get it. Worked perfectly.
public class UIManager : MonoBehaviour
{
public Animator optionsButton;
public bool hide;
private void Start()
{
//to find the parent element - canvas - which has a bool
optionsButton = GameObject.Find("MainMenu").GetComponent<Animator>();
}
public void OpenSettings()
{
hide = true;
optionsButton.SetBool("AnimOut", hide);
Debug.Log("I'm finaly working!");
}
}
How can I check if a specific animation has finished playing in Unity, then execute an action? [C#] I am not using an animator.
From: http://answers.unity3d.com/questions/52005/destroy-game-object-after-animation.html
To execute an action from the animation editor...
-Create a script with a simple public function that will destroy the object. e.g.
public class Destroyable : MonoBehaviour
{
public void DestroyMe()
{
Destroy(gameObject);
}
}
-Add that script to the animated object you want to destroy.
-In the animation editor, move the animation scrubber to the end of the animation.
-Use the 'Add Event' button in the animation toolbar
-Select 'DestroyMe' from the function drop-down in the Edit Animation Event dialog.
-Now your animation should play, run the 'DeleteMe' function, and destroy the object/do your action.
I've used this method a few times, comes in handy for certain things in animations :)
You should check Animation.IsPlaying value.
From the docs:
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
public Animation anim;
void Start() {
anim = GetComponent<Animation>();
}
void OnMouseEnter() {
if (!anim.IsPlaying("mouseOverEffect"))
anim.Play("mouseOverEffect");
}
}
Just as Andrea said in his post : Animation-IsPlaying is pretty much what you need since you don't use Animator. Check Animation to see other sweet stuff you can use.
using UnityEngine;
using UnityEngine.Collections;
public class ExampleClass : MonoBehaviour
{
Animation anim;
void Start()
{
anim = GetComponent<Animation>();
}
//In update or in another method you might want to check
if(!anim.isPlaying("StringWithAnimationClip") //or anim.clip.name
//Do Something
}
You can also force stop the animation with anim.Stop();
Now you commented that you don't want to use isPlaying() so if you can please elaborate I will edit my post.