The game I am creating is a tutorial of Brackeys called Sunnyland with a few twists and challenges for myself. One particular problem I'm facing is the music functionality. There are a few scenes for menus, each can be accessed from the main menu, a scene for the level and a winning scene after you finish it.
I want one audio file to play in the menu scenes, one for the level and one for the ending.
So far, I have solved the issue of changing scenes without stopping the audio but every time I come back to the main menu, the audio plays again while the previous record is not stopping. Then, when I press the "Start" button to play the level, it keeps playing along with the level soundtrack. And of course, it keeps playing on the winning scene.
So to summarize: my problems right now are:
audio playing multiple times in the menu sections
menu audio goes into the level and winning scenes (only if multiple records were activated)
Here is the code I'm using to play the audio through the menu scenes:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MusicControl : MonoBehaviour
{
private AudioSource music;
private void Awake()
{
DontDestroyOnLoad(transform.gameObject);
music = GetComponent<AudioSource>();
}
public void PlayMusic()
{
if (music.isPlaying) return;
{
music.Play();
}
}
public void StopMusic()
{
music.Stop();
}
}
Use DontDestroyOnLoad(gameObject) In the Awake() function of the music GameObject.
DontDestroyOnLoad() keeps objects between scenes and doesn't destroy the object.
And just stop the menu audio when you go into another scene?
Related
So, i want play music all time.
when the scene is reloaded, the music starts from the beginning, but I want it to continue from the same moment
using UnityEngine;
public class MusicBack : MonoBehaviour
{
private void Awake()
{
GameObject[] objs = GameObject.FindGameObjectsWithTag("Music");
if (objs.Length > 1)
{
Destroy(gameObject);
}
DontDestroyOnLoad(gameObject);
Debug.Log("correct");
}
}
I think that you'll need a custom script, like suggested here: https://answers.unity.com/questions/1260393/make-music-continue-playing-through-scenes.html
The idea with that answer is to use DontDestroyOnLoad to keep the audio source the same throughout scenes. So if you move from Scene 1 to Scene 2, the audiosource is still Scene 1's, if I interpreted taht correctly.
Then there's just some logic for not playing the audio in scenes where it shouldn't be played.
Probably this could have been found with a quick google search though.
Enable the loop option in AudioSource. If the music plays in the whole scene, 2D it as well.
This is the current script that I have. I have a ball that is player, and I want a collision with my game object tagged as "pit" to end the game. When the game ends I want my game over canvas to pop up. The current script detects the hit when the player rolls over the pit, however, currently, nothing else happens. Both my player and pit have rigidbodies and colliders attached to them. I would really appreciate any help with how to get my code to work properly.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Trigger : MonoBehaviour
{
public GameObject GameManager;
private void OnTriggerEnter(Collider other)
{
Debug.Log("hit detected")
if(other.gameObject.tag == "pit")
{
GameManager.GetComponent<Game_Manager>().EndGame();
}
}
}
My EndGame code is in my GameManager script. The is the part of that script that deals with ending the game.
public void EndGame ()
{
player.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezePosition;
hasGameStarted = true;
inMenuUI.gameObject.SetActive(false);
inGameUI.gameObject.SetActive(false);
gameOverUI.gameObject.SetActive(true);
}
If I'm correct in interpreting your question, your script successfully detects player death already. If you want a game over screen you have a couple of options:
You can create a UI canvas with a panel on it that obscures the whole screen and put the words Game Over.
Or, probably the better option is to create an entirely new Unity scene and make the Game Over canvas there. When you want to trigger the game over screen you simply use:
Scene manager.LoadScene("Scene name");
You have to add "using UnityEngine.SceneManagement;" at the top of your script. Also note you have to add your Game Over scene to the list of scenes in you game. I believe this can be done by navigating to File>Build settings>scenes and then pressing add open scenes assuming the game over scene is open.
Good day everyone,
how can I make another scene after scanning the image target? So far I can only do the buttons which are the basics and am currently working with c#, visual studio, unity and vuforia.Iv'e done the main menu screen which has the buttons scan and exit. Whenever you click the scan button it will automatically go to the AR camera and my question is how can I make a AR camera which you can scan an image and go to the another scene. No animation or whatsoever, just scan the image and go to another scene. Does someone has an idea of how to make it happen?
so far this is what iv'e coded:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MainMenu : MonoBehaviour {
public void System()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex +1);
}
public void Back()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex -1);
}
public void Exit()
{
Debug.Log("You have exited the app");
Application.Quit();
}
}
In your case you can just create a gameobject as a child of your image target, attach a script, lets say sceneloader.cs and put in the start() method your load-scene-code....but this are total basics. Did you even read the documentation how image targets work?
I have created a game with a main menu in a scene and I have a second scene that has the actual game in it. When the user taps the play button on main menu scene it loads the actual game scene but the problem is that it takes too much time. What should i do?
Here is the code I'm using:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MainMenu : MonoBehaviour {
public void PlayGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
}
public void QuitGame()
{
Debug.Log("Ho gaya....! Mera Ho gya");
Application.Quit();
}
}
You can use LoadSceneAsync to load the level in advance, but not activate it, you get a callback when the load is done, and than you can simply activate the scene when the user presses the button which should be instant
Alternatively to the above, you could also wait until said button press to call SceneManager.LoadSceneAsync, but display a curtain (aka loading screen) while the actual game scene loads. Coroutines are you friend here, as you can wait for the completion of an AsyncOperation by yield returning it from a Coroutine IE
var curtain = Instantiate(CurtainPrefab);
DontDestoryOnLoad(curtain);
yield return SceneManager.LoadSceneAsync(gameSceneIndex);
// Don't allow unload to clean up this object or it'll stop the coroutine before destroying the curtain!
DontDestroyOnLoad(gameObject);
yield return SceneManager.UnloadSceneAsync(mainMenuSceneIndex);
Destroy(curtain);
// Do this last or the Coroutine will stop short
Destroy(gameObject);
I am trying to program a script that when you hit an enemy it plays a sound, problem is I can't get it to play the sound it sees the audio source but my script won't pass the clip to it.
Here is the code I currently have:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
public class makeanoise : MonoBehaviour
{
public AudioClip hurtSound;
public AudioSource soundSource;
private void Update()
{
if (!soundSource.isPlaying)
{
soundSource.clip = hurtSound;
soundSource.Play();
}
}
}
how do you get the audio source to play the sound? because not even my team mates know to do it
I am trying to program a script that when you hit an enemy it plays a
sound
Use collision detection + collider instead of the Update function to detect the hit then play audio:
void OnCollisionEnter(Collision collision)
{
soundSource.Play();
}
If 2D game, use OnCollisionEnter2D instead.
I can't get it to play the sound it sees the audio source but my
script won't pass the clip to it.
There are just many reasons why Audio many not play in Unity. Your sound won't play not because you put it in the Update function.The reason it's not the Update function like some mentioned is because you protected it with if (!soundSource.isPlaying) so it will only play again only when the first one is doe playing.
Reasons why audio won't play in Unity: (From likely to unlikely)
1.The AudioClip is not assigned.
This is your AudioClip
public AudioClip hurtSound;
If hurtSound not assigned or initialized in the Editor or via code, Unity won't throw any error. It simply won't play.
Simply drag the audio to your hurtSound slot and you should hear the sound. Sometimes, the audio reference is lost so simply repeat this step again to recreate the reference.
2.Editor is muted. If the Editor is muted no sound will be coming out of it but the build should have a sound. Check and disable the mute on the Editor.
3.Playing the sound every frame. This mistake is not uncommon and it causes the AudioSource not have time to play the audio over and over again.
Example of this mistake:
private void Update()
{
soundSource.Play();
}
Possible fix:
Check the Audio is playing first before playing it.(Did this in the code from this question which is correct!)
private void Update()
{
if (!soundSource.isPlaying)
{
soundSource.Play();
}
}
4.The GameObject the AudioSource is attached to has been destroyed.
This is also common. If the GameObject the AudioSource has been attached to is destroyed, the Audio would not play.
The fix is to attach the AudioSource to GameObject that doesn't destroy. An empty GameObject is fine.
Or you can play the Audio, wait for it to finish playing then destroy it:
IEnumerator playAudio()
{
//Play Audio
soundSource.Play();
//Wait until it's done playing
while (soundSource.isPlaying)
yield return null;
//Now, destroy it
Destroy(gameObject);
}
5.The GameObject the AudioSource is attached to has been deactivated.
If the GameObject that has the Audiosource is deactivated, the audio would also stop. Don't deactivate the AudioSource GameObject. See #4 for possible workarounds.
6.The code is not even executing.
You must make sure that the Play code is even executing. A simple Debug.Log function call is enough to determine this.
private void Update()
{
if (!soundSource.isPlaying)
{
soundSource.clip = hurtSound;
soundSource.Play();
Debug.Log("Played");
}
}
If you can't see that log in the Console tab then the code is not executing.
A.Script is not attached to a GameObject. Attach it to a GameObject:
B.The GameObject the script is attached to is not Active. Activate it from the Editor:
C.The script is not enabled. Enable it:
7.The AudioSource is muted or volume is 0.
8.The AudioListener component is not present. This is very unlikely since it is automatically attached to your camera. Check if it is deleted by mistake then re-attach it to the camera. It must be attached to the camera not to any other object.
9.Bad Audio. Replace with another Audio.
10.Bug. Go to the Help ---> Report a Bug.. menu and file for a bug report.
This is what to do if everything above has failed. This is unlikely the problem but could happen when there is a big OS update.
You need to have a AudioListener in the scene and also check the 3D sounds settings, the most usual thing is having the AudioListener attached to the main camera.
Check if in the scene is there any AudioListener and the Settings of your AudioSource
One more thing that can cause that it the Pitch settings - i had mine on 0 - i could see the audio playing in the mixer - but no sound would be heard - moved pitch back to 1 - and everything worked well.
Just to help anyone else out, the pitch settings like ash a mentioned actually can cause some strange bugs, the pitch of my audio source was set to -1 as I have a mechanic where points increase the sfx pitch by clicking on things in succession. using AudioSource.PlayClip at point allowed the sound to play but I then removed AudioSource.PlayClipAtPoint to use the cached AudioSource, made sure the pitch initialized at 1f when I wanted the GameOver sounds to play and all worked as expected.
I solved this by playing AudioSource.clip at the position of the main camera. Passing in a Vector3 with x, y, and z all equal to 0 played the sound, but it was quieter. I never got AudioSource.Play() to work.
AudioSource.PlayClipAtPoint(audioSource.clip, mainCamera.transform.position);