I created an Audiosource from an audio click on all button hits. However, it gets deleted when clicking a button that loads a new scene. I'm wondering if there is an easy way to fix this, like how to add "Dontdestroyonload()" to the audio source somehow.
Code is below:
private void PlaySound()
{
AudioSource.PlayClipAtPoint(buttonClick, Camera.main.transform.position);
}
public void LoadStartMenu()
{
PlaySound();
SceneManager.LoadScene(0);
}
U can try like this:
using UnityEngine;
public class ClassName : MonoBehaviour
{
private AudioSource _audioSource;
private void Awake()
{
_audioSource = GetComponent<AudioSource>();
DontDestroyOnLoad(transform.gameObject);
}
public void PlaySound()
{
if (_audioSource.isPlaying) return;
_audioSource.PlayClipAtPoint(buttonClick,Camera.main.transform.position);
}
}
Related
I have the below audiomanager for my project. Whenever I run a game from the "Play" button in Unity - I can change the volume via slider and the settings are being saved and they load when I exit and play again via Unity's "Play" button.
However can you please explain to me why I cannot do this when I go to the PlayGame and then I go back to the main menu via "restart" button in my game? When I do that - the slider is 100% charged and it doesn't save/load new setings.
Any comments / feedback is much appreciated!
public static AudioManager AMInstance;
[SerializeField] Slider volumeSlider;
private void Awake()
{
if (AMInstance != null && AMInstance != this)
{
Destroy(this.gameObject);
return;
}
AMInstance = this;
DontDestroyOnLoad(this);
}
private void Start()
{
if (!PlayerPrefs.HasKey("musicVolume"))
{
PlayerPrefs.SetFloat("musicVolume", 1);
Load();
}
else
{
Load();
}
}
public void ChangeVolume()
{
AudioListener.volume = volumeSlider.value;
Save();
}
public void Save()
{
PlayerPrefs.SetFloat("musicVolume", volumeSlider.value);
}
public void Load()
{
volumeSlider.value = PlayerPrefs.GetFloat("musicVolume");
}
}
You will need to call PlayerPrefs.Save() before you navigate to another scene. It does get called by default OnApplicationQuit, but since you are just setting a the float, you might need to explicitly call the Save function.
Unity's documentation for PlayerPrefs.Save
I'm new to events and delegates and I'm having trouble making the functional connection between things, specifically the events manager and how events get connected to specific buttons in my program. So far I've created a few delegates and then I have a class that should subscribe to those delegates but I don't get how this system actually gets connected to buttons on different scenes. I just need someone to help me make the connection so that I can see how everything functions. Thank you.
Here is my event manager class
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Event_Manager : MonoBehaviour
{
public static Event_Manager evt = null; // create singleton
public delegate void GoToStartingSceneDelegate();
public static GoToStartingSceneDelegate onGoToStartingSceneDelegate;
public delegate void GoToSelectionSceneDelegate();
public static GoToSelectionSceneDelegate onGoToSelectionSceneDelegate;
public delegate void GoToColoringSceneDelegate();
public static GoToColoringSceneDelegate onGoToColoringSceneDelegate;
public delegate void GoToCaveSceneDelegate();
public static GoToCaveSceneDelegate onGoToCaveSceneDelegate;
private void Awake()
{
if (evt == null)
evt = this;
else if (evt != null)
Destroy(gameObject);
DontDestroyOnLoad(gameObject);
}
public static void OnStartGameButtonClick()
{
Debug.Log("Start Game");
if (onGoToStartingSceneDelegate != null)
onGoToStartingSceneDelegate();
}
public static void OnStartOverButtonClick()
{
Debug.Log("Start Over");
if (onGoToSelectionSceneDelegate != null)
onGoToSelectionSceneDelegate();
}
public static void OnSendAnimalButtonClick()
{
Debug.Log("Send Animal");
if (onGoToCaveSceneDelegate != null)
onGoToCaveSceneDelegate();
}
public static void OnPlayAgainButtonClick()
{
Debug.Log("Play Again");
if (onGoToStartingSceneDelegate != null)
onGoToStartingSceneDelegate();
}
}
and this is the class that I'm wanting to subscribe to those events
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Collections;
using UnityEngine.UI.ProceduralImage;
public class LoadSceneButtonController : MonoBehaviour
{
[SerializeField] public Object startingScene;
[SerializeField] public Object selectionScene;
[SerializeField] public Object coloringScene;
[SerializeField] public Object caveScene;
GameObject transitionManager;
public GameObject touchToPlayButton;
public GameObject sendAnimalToForestButton;
public GameObject startOverButton;
private void OnEnable()
{
Event_Manager.onGoToStartingSceneDelegate += GoToStartingScene;
Event_Manager.onGoToSelectionSceneDelegate += GoToSelectionScene;
Event_Manager.onGoToColoringSceneDelegate += GoToColoringScene;
Event_Manager.onGoToCaveSceneDelegate += GoToCaveScene;
}
private void OnDisable()
{
Event_Manager.onGoToStartingSceneDelegate -= GoToStartingScene;
Event_Manager.onGoToSelectionSceneDelegate -= GoToSelectionScene;
Event_Manager.onGoToColoringSceneDelegate -= GoToColoringScene;
Event_Manager.onGoToCaveSceneDelegate -= GoToCaveScene;
}
void GoToStartingScene()
{
SceneManager.LoadScene(startingScene.name.ToString());
}
void GoToSelectionScene()
{
SceneManager.LoadScene(selectionScene.name.ToString());
}
void GoToColoringScene()
{
SceneManager.LoadScene(coloringScene.name.ToString());
}
void GoToCaveScene()
{
SceneManager.LoadScene(caveScene.name.ToString());
}
Your code is not working but the problem has nothing to do with your events or delegates.
The problem is how you declared your scene variables. Do not use UnityEngine.Object for that. If you do, you can only cast it to SceneAsset which is from the UnityEditor namespace. This means that your code will only work in the Editor with the AssetDatabase class.
Use UnityEngine.SceneManagement instead of UnityEngine.Object. You are currently passing Object.name to the SceneManager.LoadScene function and Object.name refers to the name of the Object not a scene name.
Replace all:
[SerializeField] public Object startingScene;
[SerializeField] public Object selectionScene;
[SerializeField] public Object coloringScene;
[SerializeField] public Object caveScene;
with
public Scene startingScene;
public Scene selectionScene;
public Scene coloringScene;
public Scene caveScene;
Here is a simple Unity tutorial for events and delegates. I don't think you need that since that part of your code looks fine.
As for connecting it to your buttons, it is very easy. Just subscribe to the onClick.AddListener button event and notify the Event_Manager event when there is a click.
public Button startingButton;
public Button selectionButton;
public Button coloringButton;
public Button CaveButton;
void OnEnable()
{
//Register Button Events
startingButton.onClick.AddListener(() => buttonCallBack(startingButton));
selectionButton.onClick.AddListener(() => buttonCallBack(selectionButton));
coloringButton.onClick.AddListener(() => buttonCallBack(coloringButton));
CaveButton.onClick.AddListener(() => buttonCallBack(CaveButton));
}
private void buttonCallBack(Button buttonPressed)
{
if (buttonPressed == startingButton)
{
Debug.Log("Clicked: " + startingButton.name);
Event_Manager.OnStartGameButtonClick();
}
if (buttonPressed == selectionButton)
{
Debug.Log("Clicked: " + selectionButton.name);
Event_Manager.OnStartOverButtonClick();
}
if (buttonPressed == coloringButton)
{
Debug.Log("Clicked: " + coloringButton.name);
Event_Manager.OnSendAnimalButtonClick();
}
if (buttonPressed == CaveButton)
{
Debug.Log("Clicked: " + CaveButton.name);
Event_Manager.OnSendAnimalButtonClick();
}
}
I am a beginner of Unity 3D. I am writing an android app, and my start menu has an exit button. My idea is just very simple: after users press the exit button, the application will close.
I know Application.Quit() for quiting an app. But I just dont know how to detect a touch from user on a button and return the application.quit() method. Should I use sth like button.onclick or input.getTouch?
This is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ExitButton : MonoBehaviour {
public Button exitButton;
void Start()
{
Button btn = exitButton.GetComponent<Button>();
btn.onClick.AddListener(TaskOnClick);
}
void TaskOnClick()
{
Application.Quit ();
Debug.Log("You touched this button.");
}
}
After I tried to play my app, I get this error:
NullReferenceException: Object reference not set to an instance of an object
ExitButton.Start()
And it seems that I cant get signal from user touching the button.
Can someone give me a help?
I have linked my button in inspector, but i am not able to find my function name:TaskOnClick()
Inspector
Put the following code into a script
public void QuitGame()
{
Application.Quit();
}
attach the script to a game object then assign the button to a method using the OnClick window at the bottom of the button component in the inspector.
Attach the game object to the OnClick and choose the QuitGame function.
Note. This will only work in the build of the game and not in the editor.
You are mixing up between two methods of using a button.
If you are following #Jack Foulkes's method then you don't need to assign the button externally. That means you don't need the following code:
public Button exitButton;
void Start()
{
Button btn = exitButton.GetComponent<Button>();
btn.onClick.AddListener(TaskOnClick);
}
If you use the above code, then you don't need to add OnClick event listener in inspector, as you are already adding it inside your code. Only your code will work. You are getting the null reference, because you haven't assigned the exitButton from inspector actually.
It should look like this in the inspector:
inspector
simple you have problem with access modifiers to fix this just type
public void TaskOnClick()
{
Application.Quit ();
}
check this video it's will help you create a professional gui.
How to make a professional GUI using unity
Create a script with the following contents and then attach it to the corresponding button click
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ExitButton : MonoBehaviour {
public void ExitGame()
{
print("Exiting...");
Application.Quit();
}
}
Hello,
All you need to do is to just make this function Public
like this:
public void TaskOnClick()
{
Application.Quit();
}
You Can Also make an if statement to make it much better :)
FOR EXAMPLE:
public void TaskOnClick()
{
if (Input.GetKeyDown(KeyCode.Escape) // You Can also change the key
{
Application.Quit();
}
}
And If you want to make it less effort MAKE a Function
TRY THIS:
public void ExitFunction()
{
if (Input.GetKeyDown(KeyCode.Escape) // Or Any Other Key
{
Application.Quit();
Debug.Log("exitgame");
}
}
Public void TaskOnClick()
{
ExitFunction();
}
And Also Here is the code if you want to make the same function but on the left Mouse Button Click
public void ExitFunction()
{
if (Input.GetMouseButtonDown(0))
{
Application.Quit();
Debug.Log("exitgame");
}
}
public void TaskOnClick()
{
ExitFunction();
}
If you want it with the Right Mouse Button
Here is the Answer:
public void ExitFunction()
{
if (Input.GetMouseButtonDown(1))
{
Application.Quit();
Debug.Log("quitgame");
}
}
public void TaskOnClick()
{
ExitFunction();
}
If you want it but with the middle buttonHere is the Answer:
public void ExitFunction()
{
if (Input.GetMouseButtonDown(2))
{
Application.Quit();
Debug.Log("quitgame");
}
}
public void TaskOnClick()
{
ExitFunction();
}
Full Best Code:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class ExitButton : MonoBehaviour
{
public void ExitFunction()
{
if (Input.GetMouseButtonDown(0))
{
Application.Quit();
Debug.Log("quitgame");
}
}
public void TaskOnClick()
{
ExitFunction();
}
}
Lesson Summary:
-- Sometimes Use public when we need it like when we use GameObjects and Transforms for example.
-- if () statement is used to make the I.D.E understands the very specific objects like Do an action when .... is pressed.
Thank you.
Hope This Helped
Eyad ,
A Professional Game Developer & Front End Web Developer
Do you link your button in inspector?
EDIT.
I think this should be changed also:
void TaskOnClick()
{
Debug.Log("You touched this button.");
Application.Quit ();
}
I want my OptionButton from MainMenu to Hide the MainMenuCanvas so I can use the OptionCanvas, is it Possible?
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class Director : MonoBehaviour {
private GameObject mainMenu, options;
void Awake (){
mainMenu = GameObject.Find ("MainMenuCanvas");
options = GameObject.Find ("OptionCanvas");
}
void Start () {
mainMenu.SetActive (true);
options.SetActive (false);
}
void Update () {
//should i put If.else here?
/* like
if (button.clicked){
mainMenu.SetActive (false);
options.SetActive (true);*/
}
}
}
It should be possible. Though I'd recommend using Canvas.enabled(https://docs.unity3d.com/ScriptReference/Behaviour-enabled.html) variable for consistency.
Just create a function in a script to handle the click. f.e.
void onOptionsClick(){
if(mainMenuCanvas.enabled){
mainMenuCanvas = false;
optionCanvas = true;
}
else{
mainMenuCanvas = true;
optionCanvas = false;
}
}
This function should do what you want. Then you simply select the button and choose this function as a onClick() of that button in the Inspector.
Let me know if that works as I cannot test it atm!
You simply need to register your OptionButton event to a function. When that Button is clicked, the registered function will be called. Button.onClick.AddListener is used to register the Button event. Button.onClick.RemoveAllListeners is used to un-register the Button event.
private GameObject mainMenu, options;
public Button OptionButton;
void Awake()
{
mainMenu = GameObject.Find("MainMenuCanvas");
options = GameObject.Find("OptionCanvas");
}
void Start()
{
mainMenu.SetActive(true);
options.SetActive(false);
}
void OnEnable()
{
//Register Button Event
OptionButton.onClick.AddListener(() => OptionButtonCallBack());
}
//Will be called when OptionButton is clicked
private void OptionButtonCallBack()
{
mainMenu.SetActive(false);
options.SetActive(true);
}
void OnDisable()
{
//Un-Register Button Event
OptionButton.onClick.RemoveAllListeners();
}
You can find complete step to setup your UI here.
I've been having problems with my code for unity. I'm using C Sharp and Unity 5.0.2f Personal Edition. Here's my code:
using UnityEngine;
using System.Collections;
public class ButtonEvent : MonoBehaviour {
public void LoadScene(int SceneToChangeTo){
Application.LoadLevel (SceneToChangeTo);
}
}
This should change the to an integer scene but when I go to the button.onclick() in the inspector and add the script nothing comes up about changing scene (Note: The script is under "_Manager" (An empty GameObject))
Add a listener for your button and make sure you put a value in numberOfLevel variable and assign your button to MyButton in the inspector or you will get a null reference exception
[SerializeField] private Button MyButton = null; // assign in the editor
public int numberoflevel;
void Start() { MyButton.onClick.AddListener(() => { changeScene(numberoflevel);});
}
public void LoadScene(int SceneToChangeTo){
Application.LoadLevel (SceneToChangeTo);
}
use this code:
using UnityEngine.SceneManagement;
///***///
public void LoadGameLevel(int SceneToChangeTo)
{ SceneManager.LoadScene(SceneToChangeTo);
}
//or
public void LoadGameLevel(string SceneName)
{ SceneManager.LoadScene(SceneName);
}
note: Worked in OnMouseDown() and Unity Ui and other