Within my, if function, the Input.GetKey("t") command does not work.
The Restart method is called when I remove the contents from the if function and place them outside.
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
bool gameHasEnded = false;
public float restartDelay = 2f;
public GameObject LevelFailedUI;
public GameObject LevelCompleteUI;
public void CompleteLevel ()
{
if (LevelFailedUI == true)
{
LevelCompleteUI.SetActive(true);
}
}
public void EndGame ()
{
if (gameHasEnded == false)
{
gameHasEnded = true;
LevelFailedUI.SetActive(true);
if (Input.GetKey("t")) //nothing happens when "t" is pressed.
{
Invoke("Restart", restartDelay);
}
}
}
void Restart ()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
LevelFailedUI.SetActive(false);
}
}
It won't work because unity has to be inside the function and also hasn't reached the check before reaching the if statement and you press the button during one frame which is basically impossible. You have to check for input constantly that is why it is done inside the Update function.
void Update() {
if (Input.GetKey(KeyCode.T) && gameHasEnded) {
Invoke("Restart", restartDelay);
}
}
public void EndGame() {
if (gameHasEnded == false) {
gameHasEnded = true;
LevelFailedUI.SetActive(true);
}
}
Related
So I have two scripts one to press a button which changes between two objects, and what I want to do is be able to switch out the second avatar with others when I hit e when near another object. the scripts are working, but I have no clue how to get it to switch
here are the trigger script and the switch script
`
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SwitchCharacterScript : MonoBehaviour
{
private const string ButtonName = "E";
// references to controlled game objects
public GameObject avatar1, avatar2;
// variable contains which avatar is on and active
int whichAvatarIsOn = 1;
// Use this for initialization
void Start()
{
// anable first avatar and disable another one
avatar1.gameObject.SetActive(true);
avatar2.gameObject.SetActive(false);
}
// public method to switch avatars by pressing the UI button
public void SwitchAvatar()
{
// processing whichAvatarIsOn variable
switch (whichAvatarIsOn)
{
// if the first avatar is on
case 1:
// then the second avatar is on now
whichAvatarIsOn = 2;
// disable the first one and enable the second one
avatar1.gameObject.SetActive(false);
avatar2.gameObject.SetActive(true);
break;
// if the second avatar is on
case 2:
// then the first avatar is on now
whichAvatarIsOn = 1;
// disable the second one and enable the first one
avatar1.gameObject.SetActive(true);
avatar2.gameObject.SetActive(false);
break;
}
}
void Update()
{
if (Input.GetKeyDown(KeyCode.LeftAlt))
{
SwitchAvatar();
}
}
}
`
`
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
public class Trigger : MonoBehaviour
{
public SwitchCharacterScript player;
[SerializeField] private bool triggerActive = false;
public GameObject GameObject;
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "Player")
{
triggerActive = true;
}
}
void OnTriggerExit2D(Collider2D other)
{
if (other.gameObject.tag == "Player")
{
triggerActive = false;
}
}
private void Update()
{
if (triggerActive && Input.GetKeyDown(KeyCode.E))
{
SomeCoolAction();
}
}
public void SomeCoolAction()
{
}
}
`
In the somecoolaction is where I don't know what to do to be able to switch them; if you could not tell, I am new at this both coding and using StackOverflow.
I could not find anything on how to do something similar, or I did not know what to search for and could not find if anyone had a way to do it or a video or something.
Instead of bools I would rather store the actual reference:
public class Trigger : MonoBehaviour
{
private SwitchCharacterScript player;
void OnTriggerEnter2D(Collider2D other)
{
if (other.TryGetComponent<SwitchCharacterScript>(out var switchCharacer))
{
player = switcCharacter;
}
}
void OnTriggerExit2D(Collider2D other)
{
if (player.gameObject == other.gameObject)
{
player = null;
}
}
private void Update()
{
if (player && Input.GetKeyDown(KeyCode.E))
{
player.SwitchAvatar();
}
}
}
In general to be a bit more dynamic I would rather use an array for the characters and do e.g.
public class SwitchCharacterScript : MonoBehaviour
{
// references to controlled game objects
public GameObject[] avatars;
// variable contains which avatar is on and active
private int whichAvatarIsOn = -1;
// Use this for initialization
private void Start()
{
foreach(var avatar in avatars)
{
avatar.SetActive(false);
}
SwitchAvatar();
}
// public method to switch avatars by pressing the UI button
public void SwitchAvatar()
{
if(whichAvatarIsOn > 0 && whichAvatarIsOn < avatars.Length)
{
avatars[whichAvatarIsOn].SetActive(false);
}
whichAvatarIsOn = (whichAvatarIsOn + 1) % avatars.Length;
avatars[whichAvatarIsOn].SetActive(true);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AnimFlyertransportationController : MonoBehaviour
{
public GameObject JetFlame;
public bool turnOffOn = false;
public bool land = false;
private Animator[] animators;
// Start is called before the first frame update
void Start()
{
TurnAllAnimtorsOff(transform, turnOffOn);
if (turnOffOn)
{
JetFlame.SetActive(true);
}
else
{
JetFlame.SetActive(false);
}
}
private void TurnAllAnimtorsOff(Transform root, bool onOff)
{
animators = root.GetComponentsInChildren<Animator>(true);
foreach (Animator a in animators)
{
if (onOff)
{
a.enabled = true;
}
else
{
a.enabled = false;
}
}
}
private void OnValidate()
{
TurnAllAnimtorsOff(transform, turnOffOn);
if(land == true && turnOffOn)
{
animators[0].Play("Anim_Flyer_Land");
TurnAllAnimtorsOff(transform, false);
JetFlame.SetActive(false);
turnOffOn = false;
land = false;
}
else if(land == false && turnOffOn)
{
animators[0].Play("Anim_Flyer_Takeoff");
}
if (JetFlame) JetFlame.SetActive(turnOffOn);
}
}
// Anim_Flyer_Takeoff
// Anim_Flyer_Land
At this place I need to check if the "Anim_Flyer_Land" animation finished playing then set everything to false :
if(land == true && turnOffOn)
{
animators[0].Play("Anim_Flyer_Land");
TurnAllAnimtorsOff(transform, false);
JetFlame.SetActive(false);
turnOffOn = false;
land = false;
}
Now it's setting everything to false before the animation has finished playing.
The main goal is to use two flags or one is even better when true set everything to true the animators and the flame the default state machine state is the Anim_Flyer_Takeoff then when setting the flag to false first play the land animation and then turn off disable everything and then if flag is true again first enable everything and play the take off.
Screenshot of the animator controller :
The idea is to make a flag for take off/land
I tried this the checking script if the animation still playing :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CheckAnimationEnd : MonoBehaviour
{
public GameObject _animator;
public string animStateName;
private Animator _ani;
// Start is called before the first frame update
void Start()
{
_ani = _animator.GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (animStateName != null && animStateName != "" && _ani != null)
IsPlayingAnimation();
}
public bool IsPlayingAnimation()
{
bool IsOffLand = false;
if (_ani != null)
{
if (!_ani.GetCurrentAnimatorStateInfo(0).IsName(animStateName))
{
IsOffLand = true;
}
else
{
IsOffLand = false;
}
}
return IsOffLand;
}
}
And then :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AnimFlyertransportationController : MonoBehaviour
{
public GameObject JetFlame;
public CheckAnimationEnd checkAnimEnd;
public bool turnOffOn = false;
private Animator[] animators;
// Start is called before the first frame update
void Start()
{
TurnAllAnimtorsOff(transform, turnOffOn);
if (turnOffOn)
{
JetFlame.SetActive(true);
}
else
{
JetFlame.SetActive(false);
}
}
private void TurnAllAnimtorsOff(Transform root, bool onOff)
{
animators = root.GetComponentsInChildren<Animator>(true);
foreach (Animator a in animators)
{
if (onOff)
{
a.enabled = true;
}
else
{
a.enabled = false;
}
}
}
private void OnValidate()
{
TurnAllAnimtorsOff(transform, turnOffOn);
if (JetFlame) JetFlame.SetActive(turnOffOn);
Land();
TakeOff();
}
private void Land()
{
if (turnOffOn == false)
{
checkAnimEnd.animStateName = "Anim_Flyer_Takeoff";
animators[0].Play("Anim_Flyer_Land");
if (checkAnimEnd.IsPlayingAnimation())
{
TurnAllAnimtorsOff(transform, false);
JetFlame.SetActive(false);
turnOffOn = false;
}
}
}
private void TakeOff()
{
if(turnOffOn)
{
checkAnimEnd.animStateName = "Anim_Flyer_Land";
animators[0].Play("Anim_Flyer_Takeoff");
if (checkAnimEnd.IsPlayingAnimation())
{
TurnAllAnimtorsOff(transform, true);
JetFlame.SetActive(true);
turnOffOn = true;
}
}
}
}
but everything is messed now. when I set the TurnOffOn to be true the spacecraft start from up and land and then when set it false it's taking off and everything turn on/off the animators and fire I messed all the flags and both scripts.
you can add (animation event) at the end of the animation state then put all the commands that you want on the animation event's function.
I cannot figure out the issue, I deleted then remade the PlayTab object, but it no longer works... It is telling me it has not been assigned, but it has to my knowledge. Relatively new to Unity programming, any help would be great, the script below.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.Audio;
public class MainMenu : MonoBehaviour {
public GameObject Buttons;
public GameObject CreditsPanel;
public GameObject QuitPanel;
public GameObject Options;
public GameObject PlayTab;
public Slider audiosl;
public Slider graphicsl;
public Toggle fullscreen;
public string SceneName;
void Start (){
QualitySettings.SetQualityLevel (100);
//(int)PlayerPrefs.GetFloat("Quality")
AudioListener.volume = 100;
//PlayerPrefs.GetFloat("Volume");
int qualityLevel = QualitySettings.GetQualityLevel();
audiosl.value = AudioListener.volume;
graphicsl.value = qualityLevel;
}
void Update (){
Debug.Log ("Update");
AudioListener.volume = audiosl.value;
QualitySettings.SetQualityLevel ((int)graphicsl.value);
}
public void InGame(bool a){
if (a == true) {
Application.LoadLevel (SceneName);
} else {
//continue
}
}
public void Play(bool a){
Debug.Log ("Inside Play Function");
if (a == true) {
Debug.Log ("Inside If Statment");
PlayTab.SetActive(a);
Buttons.SetActive(!a);
Animation pl = PlayTab.GetComponent<Animation>();
pl.Play("EnterPlayMenu");
}else {
Debug.Log ("Else'd");
PlayTab.SetActive(a);
}
}
public void ShowMenu(bool a){
}
public void Option(bool a){
if (a == true) {
Options.SetActive(a);
Buttons.SetActive(!a);
Animation Opt = Options.GetComponent<Animation>();
Opt.Play("OptionEnter");
}if (a == false) {
Animation d = Buttons.GetComponent<Animation> ();
d.Play ("mainbuttonenter");
Options.SetActive (false);
}
}
public void Credits(bool a){
if (a == true) {
CreditsPanel.SetActive(a);
Buttons.SetActive(!a);
Animation cr = CreditsPanel.GetComponent<Animation>();
cr.Play("EnterCredits");
}else {
CreditsPanel.SetActive(a);
}
}
public void Quit(bool a){
if (a == true) {
QuitPanel.SetActive(a);
Buttons.SetActive(!a);
Animation q = QuitPanel.GetComponent<Animation>();
q.Play("EnterQuit");
}else {
QuitPanel.SetActive(a);
}
}
public void Exit(bool a){
if (a == false) {
Option(false);
Buttons.SetActive(true);
CreditsPanel.SetActive(false);
QuitPanel.SetActive(false);
Options.SetActive(false);
PlayTab.SetActive(false);
saveSettings();
}
if (a == true) {
Application.Quit();
}
}
public void saveSettings(){
PlayerPrefs.SetFloat ("Quality", QualitySettings.GetQualityLevel ());
PlayerPrefs.SetFloat ("Volume", AudioListener.volume);
}
public void FullScreen(bool a){
if (Screen.fullScreen == a) {
Screen.fullScreen = !a;
} else {
Screen.fullScreen = a;
}
}
}
As far as I see, you have only defined the playTab variable, but not assigned it.
EDIT:
Try displaying it at start, then automatically hiding it via code. Probably Unity don't initialize objects that are not visible on scene from the start.
I'm stuck on this one. I have two buttons that are each associated with a respective pop-up that I would like to show when the buttons are clicked and then hide when the buttons are clicked again and so on. I know I need to invert the boolean using '!' but I'm not exactly sure how to implement it in my code below. What is the correct way that my PaletteState function should be written? Thanks!
using UnityEngine ;
using System.Collections ;
using UnityEngine.UI ;
public class ShowHidePalettes : MonoBehaviour
{
public Button changeColorButton ;
public GameObject colorPalette ;
public Button brushSizeButton ;
public GameObject brushSizePalette ;
void Awake ()
{
changeColorButton.onClick.AddListener (() => PaletteState (colorPalette, true)) ;
brushSizeButton.onClick.AddListener (() => PaletteState (brushSizePalette, true)) ;
}
void Start ()
{
PaletteState (colorPalette, false) ;
PaletteState (brushSizePalette, false) ;
}
public void PaletteState (GameObject _palette, bool _visible)
{
_visible = !_visible ;
if (_visible == true)
{
_palette.SetActive (true) ;
} else
{
_palette.SetActive (false) ;
}
}
}
You need two boolean variables for each Button since each Button control two different UI/popup. You flip the respective boolean variable when the Button is clicked with the '!'. You can then pass in the boolean variable to the SetActive function.
Also, you need a way to determine which Button is pressed. You can use two different functions for that but using one and passing the Button instance is better.
You should also remove listener with RemoveListener in the OnDisable function since you subscribed to one.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class ShowHidePalettes : MonoBehaviour
{
public Button changeColorButton;
public GameObject colorPalette;
bool showColorPalette = false;
public Button brushSizeButton;
public GameObject brushSizePalette;
bool showSizeButton = false;
void Start()
{
colorPalette.SetActive(false);
brushSizePalette.SetActive(false);
}
void buttonCallBack(Button buttonClicked)
{
//Change Color Palette Button clicked
if (buttonClicked == changeColorButton)
{
showColorPalette = !showColorPalette;//Flip
colorPalette.SetActive(showColorPalette);
}
//Change Brush Size Button Button clicked
if (buttonClicked == brushSizeButton)
{
showSizeButton = !showSizeButton;//Flip
brushSizePalette.SetActive(showSizeButton);
}
}
void OnEnable()
{
changeColorButton.onClick.AddListener(() => buttonCallBack(changeColorButton));
brushSizeButton.onClick.AddListener(() => buttonCallBack(brushSizeButton));
}
void OnDisable()
{
changeColorButton.onClick.RemoveListener(() => buttonCallBack(changeColorButton));
brushSizeButton.onClick.RemoveListener(() => buttonCallBack(brushSizeButton));
}
}
Try this:
Remove the bool _visible parameter from PaletteState method.
Then alternate GameObject state by itself.
public void PaletteState (GameObject _palette)
{
_palette.SetActive (!palette.activeSelf) ;
}
Your code should be something like this :
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class ShowHidePalettes : MonoBehaviour
{
public Button changeColorButton;
public GameObject colorPalette;
public Button brushSizeButton;
public GameObject brushSizePalette;
private bool colorPalleteVisibility = false;
private bool brushSizePalleteVisibility = false;
public void PaletteState(PaleteType type)
{
if (type == PaleteType.ColorPalette)
{
colorPalleteVisibility = !colorPalleteVisibility;
colorPalette.SetActive(colorPalleteVisibility);
}
else if (type == PaleteType.BrushSizePalette)
{
brushSizePalleteVisibility = !brushSizePalleteVisibility;
colorPalette.SetActive(brushSizePalleteVisibility);
}
}
}
public enum PaleteType
{
ColorPalette, BrushSizePalette
}
So, my script that I've written isn't working fully. I have A pause button and when I press it, it triggers my bool and shows that its working properly but when I'm "Paused" my UI doesn't pop up and my game doesn't stop in the back ground. I hope you can understand clearly. I am a beginner!
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class PauseManager : MonoBehaviour {
public GameObject pauseMenu;
public bool paused = false;
public void start()
{
pauseMenu.SetActive(false);
}
public void update()
{
if(Input.GetButtonDown("escape"))
{
paused = !paused;
}
if (paused)
{
pauseMenu.SetActive(true);
Time.timeScale = 0;
}
if (!paused)
{
pauseMenu.SetActive(false);
Time.timeScale = 1;
}
}
public void Resume()
{
paused = false;
}
public void pauseButton()
{
paused = true;
}
}
Advice you change your code to this:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class PauseManager : MonoBehaviour {
public GameObject pauseMenu;
bool paused = false;
void Start()
{
pauseMenu.SetActive(false);
}
void Update()
{
if(Input.GetButtonDown("escape"))
{
paused = !paused;
}
if (paused)
{
PauseGame();
}
if (!paused)
{
ResumeGame();
}
}
void PauseGame(){
pauseMenu.SetActive(true);
Time.timeScale = 0f;
}
void ResumeGame(){
pauseMenu.SetActive(false);
Time.timeScale = 1f;
}
public void Resume()
{
ResumeGame();
}
public void pauseButton()
{
PauseGame();
}
}
I think the problem is on that when you pause button pressed, timescale be 0, and update does not work.