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?
I have a button in my Unity2D game that the user can click and the scene will start over. On my button, I have a script attached with this code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class Restart : MonoBehaviour
{
public void PlayAgain()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
Debug.Log("Play Again Works");
}
}
I know that the button is working and the Play Again function is working because the Debug.Log is working. However, when I click the button the scene doesn't restart. When I click the button, in the Unity hierarchy, next to the scene name it very briefly shows "(not loaded)". My scene is showing up in the Build settings. Does anyone know what could be causing this? Thanks for your help.
First check that you have added the scene in your build settings. If that is not your problem try following code.
SceneManager.LoadScene (SceneManager.GetActiveScene().name);
I am making a simple VR Tour in Unity, and I want to move the camera to the next sphere (or at all at this point) when I click on a sprite that is hovering in the air. Right now, when I run this code, I get the "Sprite Clicked" message in the console, but the camera doesn't move at all. Any help is greatly appreciated!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DebugOnClick : MonoBehaviour {
// Use this for initialization
void Start () {
}
void OnMouseDown () {
Debug.Log("Sprite Clicked");
Camera.main.transform.position = new Vector3(5.0f, 5.0f, 5.0f);
}
}
It doesn't let me comment (not enough rep) so I must pop this in as an answer.
If you're using some given VR scripts already, it could be possible that they're syncing the camera position constantly to where they should be relative to the player's headset position.
Meaning that after this move via script, the camera will be moved back instantly.
If that is the case, you need to move the player avatar themselves to the correct position rather than the camera.
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'm making an Android app with Unity3D and it works with click detection already, but not with touch. I need touch though for multitouch detection.
What I want: I have my player and 2 images of arrows. One arrow points right and one left. When I touch the left arrow the player should start moving left, when I touch the right arrow the player should start moving right.
But how do I detect which arrow is touched (and held)? All the code I found on Google is too old and not working anymore.
I'm working with C# scripts and it's a 2D game.
Klausar, what you're looking for is .........
A BUTTON (!!!)
it's that easy!
click "add Canvas". (You very likely want "scale to screen size" - select that option.)
click "add Button".
there is no "three" .. go drinking.
In your code, have a routine like this for the right-side button
public void UserClickedRight()
{
Debug.Log("click right whoo!");
}
and have a similar routine for the left-side button.
1. Go to your Button in the editor.
2. Simply drag the script to it and select UserClickedRight !!
You actually do not have to program buttons from scratch :)
This is a basic mechanism of Unity - drag a game object to a "slot" for it in the Editor.
(The game object you drag, has the script in question on it.)
You DO NOT need to go to the level of touch handling to achieve a button!
Now you ask, what about "when holding down on the button"?
It's very easy, you just need to know a couple of things about the Unity "event" system.
In Button, Unity have done all the work for "OnClick":
Since "click" is common, they put that one right in the Inspector panel for you for convenience.
The good news is that Button has many more events you can use.
http://docs.unity3d.com/ScriptReference/UI.Button.html
My guess is you want to use OnPointerDown and OnPointerUp in your case.
To use the other events (which Unity did not bother putting in the Inspector panel) is very simple, you just
1, make a script that references the events you want,
and,
2, you put that script ON the button in question ...
it's that easy.
Step by step explanation:
You're going to be using Unity's event system, so:
using UnityEngine.EventSystems;
Next. You know that a script normally starts like this...
public class FancyButton:MonoBehaviour
The "MonoBehaviour" part just means that it's a c# script which will be "driving a GameObject".
In this case we have to further alert the engine that you will be using those click events. So you add this.
,IPointerDownHandler,IPointerUpHandler
So far we have this
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class FancyButton:MonoBehaviour,IPointerDownHandler,IPointerUpHandler
{
Now the easy part.
You just type the two routines which Unity will run for you, when, those things happen.
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class FancyButton:MonoBehaviour,IPointerDownHandler,IPointerUpHandler
{
public void OnPointerDown(PointerEventData data)
{
Debug.Log("holy! someone put the pointer down!")
}
public void OnPointerUp(PointerEventData data)
{
Debug.Log("whoa! someone let go!")
}
}
Now all you have to do is drop that script on the Button. Done!
You can put that script on any button, where, you need that functionality.
Next, click on Obi-wan to see where we're at so far!
Finally, it sounds like you want to do something "when the button is being held down". That's just a general programming issue - you'd have a boolean which you turn on and off as the button goes up and down. Let's do it.
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class FancyButton:MonoBehaviour,IPointerDownHandler,IPointerUpHandler
{
[System.NonSerialized] public bool mouseIsDownRightNow;
public void OnPointerDown(PointerEventData data)
{
mouseIsDownRightNow = true;
}
public void OnPointerUp(PointerEventData data)
{
mouseIsDownRightNow = false;
}
}
You could access that variable from another script, or whatever you want.
Add the following if you want to run a routine while the button is down:
void Update()
{
if (buttonIsDownRightNow) WhileButtonIsDown();
}
private void WhileButtonIsDown()
{
Debug.Log("THE BUTTON IS DOWN! WHOA!");
}
Try that and watch the console as you hold the button down and up.
Here's an example of something like continually increasing a value while the button is down:
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
public class FancyButton:MonoBehaviour,IPointerDownHandler,IPointerUpHandler
{
[System.NonSerialized] public bool buttonIsDownRightNow;
private int countSomething;
public void OnPointerDown(PointerEventData data)
{
buttonIsDownRightNow = true;
}
public void OnPointerUp(PointerEventData data)
{
buttonIsDownRightNow = false;
}
private void WhileButtonIsDown()
{
++countSomething;
}
void Update()
{
if (buttonIsDownRightNow) WhileButtonIsDown();
Debug.Log("value is now " +countSomething.ToString());
}
}
That's all there is to it. Once you really understand events in Unity, there is not much more to learn about Unity.
The only other important topics are Mecanim, shader writing, touch, coroutines, threading, PhysX, native plugins, sprites, networking, dynamic mesh, navigation, VR, AR, animation, inverse kinematics, particles, terrain, IAP, lighting, baking, shadows, MMP, character controllers, and audio. Enjoy!
You should firsty read this.
What you are trying to do is actually simple:
foreach (Touch touch in Input.touches) {
if (touch.phase == TouchPhase.Moved || touch.phase == TouchPhase.Stationary)
if (guiTexture1.HitTest(touch.position)) {
// Maybe move left
}
if (guiTexture2.HitTest(touch.position)) {
// Maybe move right
}
}
}
Edit 1: this code now checks which image is being pressed
Edit 2: Added multitouch support