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.
Related
So apparently, i was working on my games dialogue and of course, i have to put the text in the text slot for my code. I tried putting it in the slot but it didnt work. I tried changing the "Text" to "TextMesh" but still, didnt work.
this is my code that i tried for the game.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Goose : MonoBehaviour
{
public GameObject dialoguePanel;
public TextMesh dialogueText;
public string[] dialogue;
private int index;
public float wordSpeed;
public bool playerIsClose;
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyCode.E) && playerIsClose)
{
if(dialoguePanel.activeInHierarchy)
{
zeroText();
}
else
{
dialoguePanel.SetActive(true);
StartCoroutine(Typing());
}
}
}
public void zeroText()
{
dialogueText.text = "";
index = 0;
dialoguePanel.SetActive(false);
}
IEnumerator Typing()
{
foreach(char letter in dialogue[index].ToCharArray())
{
dialogueText.text += letter;
yield return new WaitForSeconds(wordSpeed);
}
}
public void NextLine()
{
if(index < dialogue.Length - 1)
{
index++;
dialogueText.text = "";
StartCoroutine(Typing());
}
else
{
zeroText();
}
}
private void OnTriggerEnter2D(Collider2D other)
{
if(other.CompareTag("Player"))
{
playerIsClose = true;
}
}
private void OnTriggerExit2D(Collider2D other)
{
if(other.CompareTag("Player"))
{
playerIsClose = false;
zeroText();
}
}
}
I think what you need is public TMP_Text dialogueText
I had a script that controlled my main menu that was on a GameObject and moved it to another gameobject and reconnected all the loose ends. now for some reason none of my buttons work, even with highlighting.
just had two gameobjects and moved the script between them using the editor
the script itself doesnt do much, just this:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class MainMenu : MonoBehaviour
{
public GameObject mainMenu;
public GameObject optionsMenu;
public GameObject modeMenu;
public Dropdown resolutionDropdown;
private Resolution[] resolutions;
public Toggle fullscreenToggle;
public void StartGameLocal()
{
SceneManager.LoadScene("Local2P");
}
public void StartGameAI()
{
SceneManager.LoadScene("AI2P");
}
public void MenuToOptions()
{
mainMenu.SetActive(false);
optionsMenu.SetActive(true);
}
public void OptionsToMenu()
{
mainMenu.SetActive(true);
optionsMenu.SetActive(false);
}
public void MenuToMode()
{
mainMenu.SetActive(false);
modeMenu.SetActive(true);
}
public void ModeToMenu()
{
mainMenu.SetActive(true);
modeMenu.SetActive(false);
}
public void ExitGame()
{
Application.Quit();
}
void Start()
{
resolutions = Screen.resolutions;
resolutionDropdown.ClearOptions();
List<string> options = new List<string>();
int currentResolutionIndex = 0;
for (int i = 0; i < resolutions.Length; i++)
{
string option = resolutions[i].width + " x " + resolutions[i].height;
options.Add(option);
if (resolutions[i].width == Screen.width && resolutions[i].height == Screen.height)
currentResolutionIndex = i;
}
resolutionDropdown.AddOptions(options);
resolutionDropdown.value = currentResolutionIndex;
resolutionDropdown.RefreshShownValue();
if (Screen.fullScreen == true)
{
fullscreenToggle.isOn = true;
}
}
public void SetResolution(int resolutionIndex)
{
Resolution resolution = resolutions[resolutionIndex];
Screen.SetResolution(resolution.width,
resolution.height, Screen.fullScreen);
PlayerPrefs.SetInt("ResolutionPreference", resolutionDropdown.value);
}
public void SetFullscreen(bool isFullscreen)
{
Screen.fullScreen = isFullscreen;
if (isFullscreen)
{
PlayerPrefs.SetInt("FullscreenPreference", 1);
}
else
{
PlayerPrefs.SetInt("FullscreenPreference", 0);
}
}
void Update()
{
if (Input.GetKey(KeyCode.Escape))
{
if (optionsMenu.activeSelf)
{
OptionsToMenu();
}
else if (optionsMenu.activeSelf)
{
ModeToMenu();
}
else
{
Application.Quit();
}
}
}
}
i dont know how to fix this and why my buttons just stopped working, even after reconnecting everything, but please help!
p.s. havent checked the update code to see if it worked, if yall have suggestions let me know
Your buttons likely pointed to the functions in this script in their OnClick handlers. If you moved the location of the script, you need to go to each of the buttons and hook those handlers back up.
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);
}
}
Or maybe to make the variables static and get reference to them in the editor.
This script sit in my Game scene.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class SceneFader : MonoBehaviour
{
#region FIELDS
public GameObject fadeOutUIGameobjectImage;
public float fadeSpeed = 0.8f;
public bool loaded = false;
private static Image fadeOutUIImage;
private void Start()
{
}
public enum FadeDirection
{
In, //Alpha = 1
Out // Alpha = 0
}
#endregion
#region FADE
public static IEnumerator Fade(FadeDirection fadeDirection)
{
fadeOutUIGameobjectImage.SetActive(true);
float alpha = (fadeDirection == FadeDirection.Out) ? 1 : 0;
float fadeEndValue = (fadeDirection == FadeDirection.Out) ? 0 : 1;
if (fadeDirection == FadeDirection.Out)
{
while (alpha >= fadeEndValue)
{
SetColorImage(ref alpha, fadeDirection);
yield return null;
}
fadeOutUIGameobjectImage.SetActive(false);
}
else
{
fadeOutUIGameobjectImage.SetActive(true);
while (alpha <= fadeEndValue)
{
SetColorImage(ref alpha, fadeDirection);
yield return null;
}
}
}
#endregion
#region HELPERS
public static IEnumerator FadeAndLoadSceneNewGame(FadeDirection fadeDirection, string sceneToLoad)
{
yield return Fade(fadeDirection);
loaded = false;
SceneManager.LoadScene(sceneToLoad);
}
public static IEnumerator FadeAndLoadSceneLoadGame(FadeDirection fadeDirection, string sceneToLoad)
{
yield return Fade(fadeDirection);
loaded = true;
SceneManager.LoadScene(sceneToLoad);
var saveLoad = GameObject.Find("Save System").GetComponent<SaveLoad>();
saveLoad.Load();
}
private static void SetColorImage(ref float alpha, FadeDirection fadeDirection)
{
if(fadeOutUIImage == null)
{
fadeOutUIImage = fadeOutUIGameobjectImage.GetComponent<Image>();
}
fadeOutUIImage.color = new Color(fadeOutUIImage.color.r, fadeOutUIImage.color.g, fadeOutUIImage.color.b, alpha);
alpha += Time.deltaTime * (1.0f / fadeSpeed) * ((fadeDirection == FadeDirection.Out) ? -1 : 1);
}
#endregion
}
Now the variables in the tope are public but not static so I can't use them in the rest of the script and if I make them static I can't reference to them in the editor I tried to use Find in the Start when they are static but they are null.
And this script sit in my Main Menu scene I thought make the two methods in the Game scene public static will be easier to call them from the Main Menu scene :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEditor;
using Cinemachine;
using UnityStandardAssets.Characters.ThirdPerson;
public class MenuController : MonoBehaviour
{
#region Default Values
[Header("Default Menu Values")]
[SerializeField] private float defaultVolume;
[SerializeField] private int defaultSen;
[SerializeField] private bool defaultInvertY;
[Header("Levels To Load")]
public string _newGameButtonLevel;
private string levelToLoad;
public GameObject player;
private int menuNumber;
#endregion
#region Menu Dialogs
[Header("Main Menu Components")]
[SerializeField] private GameObject menuDefaultCanvas;
[SerializeField] private GameObject GeneralSettingsCanvas;
[SerializeField] private GameObject graphicsMenu;
[SerializeField] private GameObject soundMenu;
[SerializeField] private GameObject controlsMenu;
[SerializeField] private GameObject confirmationMenu;
[Space(10)]
[Header("Menu Popout Dialogs")]
[SerializeField] private GameObject noSaveDialog;
[SerializeField] private GameObject newGameDialog;
[SerializeField] private GameObject loadGameDialog;
#endregion
#region Slider Linking
[Header("Menu Sliders")]
[SerializeField] private Text controllerSenText;
[SerializeField] private Slider controllerSenSlider;
public float controlSenFloat = 2f;
[Space(10)]
[SerializeField] private Text volumeText;
[SerializeField] private Slider volumeSlider;
[Space(10)]
[SerializeField] private Toggle invertYToggle;
#endregion
#region Initialisation - Button Selection & Menu Order
private void Start()
{
menuNumber = 1;
}
#endregion
//MAIN SECTION
public IEnumerator ConfirmationBox()
{
confirmationMenu.SetActive(true);
yield return new WaitForSeconds(2);
confirmationMenu.SetActive(false);
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
if (menuNumber == 2 || menuNumber == 7 || menuNumber == 8)
{
GoBackToMainMenu();
ClickSound();
}
else if (menuNumber == 3 || menuNumber == 4 || menuNumber == 5)
{
GoBackToOptionsMenu();
ClickSound();
}
else if (menuNumber == 6) //CONTROLS MENU
{
ClickSound();
}
}
}
private void ClickSound()
{
GetComponent<AudioSource>().Play();
}
#region Menu Mouse Clicks
public void MouseClick(string buttonType)
{
if (buttonType == "Controls")
{
controlsMenu.SetActive(true);
menuNumber = 6;
}
if (buttonType == "Graphics")
{
GeneralSettingsCanvas.SetActive(false);
graphicsMenu.SetActive(true);
menuNumber = 3;
}
if (buttonType == "Sound")
{
GeneralSettingsCanvas.SetActive(false);
soundMenu.SetActive(true);
menuNumber = 4;
}
if (buttonType == "Exit")
{
Debug.Log("YES QUIT!");
Application.Quit();
}
if (buttonType == "Options")
{
menuDefaultCanvas.SetActive(false);
GeneralSettingsCanvas.SetActive(true);
menuNumber = 2;
}
if (buttonType == "LoadGame")
{
menuDefaultCanvas.SetActive(false);
loadGameDialog.SetActive(true);
menuNumber = 8;
}
if (buttonType == "NewGame")
{
menuDefaultCanvas.SetActive(false);
newGameDialog.SetActive(true);
menuNumber = 7;
}
}
#endregion
public void VolumeSlider(float volume)
{
AudioListener.volume = volume;
volumeText.text = volume.ToString("0.0");
}
public void VolumeApply()
{
PlayerPrefs.SetFloat("masterVolume", AudioListener.volume);
Debug.Log(PlayerPrefs.GetFloat("masterVolume"));
StartCoroutine(ConfirmationBox());
}
public void ControllerSen()
{
controllerSenText.text = controllerSenSlider.value.ToString("0");
controlSenFloat = controllerSenSlider.value;
}
#region ResetButton
public void ResetButton(string GraphicsMenu)
{
if (GraphicsMenu == "Audio")
{
AudioListener.volume = defaultVolume;
volumeSlider.value = defaultVolume;
volumeText.text = defaultVolume.ToString("0.0");
VolumeApply();
}
if (GraphicsMenu == "Graphics")
{
controllerSenText.text = defaultSen.ToString("0");
controllerSenSlider.value = defaultSen;
controlSenFloat = defaultSen;
invertYToggle.isOn = false;
}
}
#endregion
#region Dialog Options - This is where we load what has been saved in player prefs!
public void ClickNewGameDialog(string ButtonType)
{
if (ButtonType == "Yes")
{
newGameDialog.SetActive(false);
StartCoroutine(SceneFader.FadeAndLoadSceneNewGame(SceneFader.FadeDirection.In, _newGameButtonLevel));
}
if (ButtonType == "No")
{
GoBackToMainMenu();
}
}
public void ClickLoadGameDialog(string ButtonType)
{
if (ButtonType == "Yes")
{
newGameDialog.SetActive(false);
StartCoroutine(SceneFader.FadeAndLoadSceneLoadGame(SceneFader.FadeDirection.In, _newGameButtonLevel));
}
if (ButtonType == "No")
{
GoBackToMainMenu();
}
}
#endregion
#region Back to Menus
public void GoBackToOptionsMenu()
{
GeneralSettingsCanvas.SetActive(true);
graphicsMenu.SetActive(false);
soundMenu.SetActive(false);
VolumeApply();
menuNumber = 2;
}
public void GoBackToMainMenu()
{
menuDefaultCanvas.SetActive(true);
newGameDialog.SetActive(false);
loadGameDialog.SetActive(false);
noSaveDialog.SetActive(false);
GeneralSettingsCanvas.SetActive(false);
graphicsMenu.SetActive(false);
soundMenu.SetActive(false);
menuNumber = 1;
}
public void ClickQuitOptions()
{
GoBackToMainMenu();
}
public void ClickNoSaveDialog()
{
GoBackToMainMenu();
}
#endregion
}
In this script I have two events :
ClickNewGameDialog and ClickLoadGameDialog that I'm calling them from OnClick buttons in the main menu.
I created this script and added it to an empty GameObject in the Game scene :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class NewGame : MonoBehaviour
{
// Here you store the actual instance
private static NewGame _instance;
// Public read-only access property
public static NewGame Instance
{
get
{
// if already set simply return directly
if (_instance) return _instance;
// Otherwise try to find it in the scene
_instance = FindObjectOfType<NewGame>();
if (_instance) return _instance;
// Otherwise create it now
_instance = new GameObject(nameof(NewGame)).AddComponent<NewGame>();
return _instance;
}
}
private bool _gameStarted;
public static bool GameStarted => Instance._gameStarted;
private void Awake()
{
if (_instance && _instance != this)
{
// There already exist another instance
Destroy(this.gameObject);
return;
}
// Otherwise this is the active instance and should not be destroyed
_instance = this;
DontDestroyOnLoad(this.gameObject);
SceneManager.sceneLoaded += OnSceneLoaded;
// update it once now
_gameStarted = SceneManager.GetActiveScene().buildIndex != 0;
}
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
_gameStarted = scene.buildIndex != 0;
}
}
but when I tried to use it for exmaple in the Game scene like this :
if(NewGame.GameStarted != true)
GameStarted is all the time true never false so it's all the time staring a new game even if the player clicked the Load Game button.
Use Singletone Design Pattern. Create a static variable that refers to your script like this:
public static YourCodeBehaviour Instance;
Then in Awake method you just check if it null and set it if true, like this.
private void Awake() {
if(Instance == null)
Instance = this;
else {
Destroy(gameObject);
}
}
Then you got an Instance that you can access from your static methods, cause Instance is static and got the actual alive instance.
Good luck!
In Unity:
Could anybody tell me what I did wrong. I wanted to pop up a dialogue after you are nearby a charecter but somehow my code doesn't really work.
public class Interactable : MonoBehaviour {
[HideInInspector]
public NavMeshAgent playerAgent;
private bool hasInteracted;
public virtual void MoveToIneraction(NavMeshAgent playerAgent)
{
hasInteracted = false;
this.playerAgent = playerAgent;
playerAgent.stoppingDistance = 2.3f;
playerAgent.destination = this.transform.position;
Interact ();
}
void Update()
{
if (!!hasInteracted && playerAgent != null && playerAgent.pathPending)
{
if(playerAgent.remainingDistance <= playerAgent.stoppingDistance)
{
Interact();
hasInteracted = true;
}
}
}
public virtual void Interact()
{
Debug.Log("Interacted");
}
}
!!hasInteracted
It should be !hasInteracted, I guess