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);
Related
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 want to play a death animation to my enemy. Basically, he has an idle animation and I would like to play the death animation when he dies, and after one or two seconds, the GameObject gets deleted. I'm new to coding, so a basic solution would be better :) .
Here's my coding:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyHealthManager : MonoBehaviour {
public int enemyHealth;
public GameObject deathEffect;
public int pointsOnDeath;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update ()
{
if (enemyHealth <= 0)
{
Instantiate (deathEffect, transform.position, transform.rotation);
ScoreManager.AddPoints (pointsOnDeath);
Destroy (gameObject);
}
}
public void giveDamage(int damageToGive)
{
enemyHealth -= damageToGive;
}
}
You can add a function called PlayAnimationAndDestroy() as a void and inside it put the Destroy (this.gameObject, 2f) and then animator.Play("deathAnim");
In the Destroy the number after the comma is the time Unity will wait to destroy the object so you need to check the duration of your animation in the timeline and put that duration in the Destroy ().
Another way to do this is to press the record button inside the animation at the end of it and change a public variable. In the script you will put a simple if() and If that variable has changed you destroy the object.
The third way is to use animation events (https://docs.unity3d.com/Manual/script-AnimationWindowEvent.html) but for your usage the first two options are easier :)
Welcome to Unity! Using an AnimatorController in your project and corresponding Animator components on your GameObject that you want to die is going to be your friend here as well.
You can check out a great tutorial by Unity about Animator Controllers here, but basically, it's a state machine. Based on what state your object is in, you can control which game object animations are active and you can set triggers in your game logic to trigger a transition to another state.
This is great for cases like triggering death animations.
In your case, you'd want one state for idle, and one state for death. You'd have a connection between your death and idle state.
You'd set a trigger named die. You'd make it so that the state idle only moves to state death when your die trigger is triggered in the game logic.
So, step 1:
You'd create a new AnimatorController Scriptable Object from the Editor, and then edit it in the Animator window. Make your desired state machine with the desired animations and that ScriptableObject will be saved in a project folder.
Step 2: Add an Animator component on your GameObject that you want to affect. It has an AnimatorController component - add your newly created controller here.
Step 3: In your game logic script, you'd have a reference to that Animator component:
...
public int enemyHealth;
public GameObject deathEffect;
public int pointsOnDeath;
public Animator animComponent;
...
Then when you hit your condition, you'd do something like this:
if (enemyHealth < 0){
animComponent.SetTrigger("die");
}
Then your AnimatorController will move from your previous state to death, and your animation that you set will play.
Best of luck.
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?
When I click ViewAR it Loads the next scene
SceneManager.LoadScene("scene2", LoadSceneMode.Additive);
In the second scene I am using ARkit to detect a plane and using UnityARHitTestExample I am placing an object on the detected plane.I cannot place the model it is stuck in the centre but if I use Loadscene.Single for the above code it works smoothly.
The reason I am using LoadSceneMode.Additive is that when I hit back button from the scene 2 it should go exactly where I left in scene 1.That is if my scene 1 contains two pages,at start if I hit next it reaches second page.In the second page I have ViewAR button which when clicked goes to scene 2.From scene 2 when I hit back button it should return to page 2 in scene 1.
If I use LoadSceneMode.AdditiveI cannot place the model using HittestExample.That is when a plane is detected I cannot place the gameobject on a detected plane.It is stuck at centre.
public void ViewAR()
{
PlayerPrefs.SetInt("Option", Buttonoption);
ProductDetails.SetActive(false);
ViewARbtn.SetActive(false);
StartCoroutine(Changescene());
StartCoroutine(LoadScene2());
// SceneManager.LoadScene("furnitres", LoadSceneMode.Additive);
}
IEnumerator Changescene()
{
SceneManager.UnloadSceneAsync("Home");
yield return new WaitForEndOfFrame();
}
IEnumerator LoadScene2()
{
AsyncOperation asyncLoad =SceneManager.LoadSceneAsync("furnitres", LoadSceneMode.Additive);
// Wait until the asynchronous scene fully loads
while (!asyncLoad.isDone)
{
yield return null;
}
}
The problem here is two scenes are interfering when I use Additive is what I think.I do not want to reload the first scene at the same time I cannot use LoadSceneMode.Additive .Any solution on how to get back to scene 1 when I hit back button in scene 2?I tried loading the scene 2 asynchronously.