Reseting a level in unity when exit to menu is hit - c#

I have a pause screen in my game having two buttons : resume game and exit to main menu
The main menu have only 1 button wish is play,
when i click on exit to main menu the main menu level is loaded,if then i click Play My game level scene is not restarting but continuing everything,having all it's pre created prefabs and all its game object.
How should I fix this particular bug and restarting the game when exit to main menu is clicked
Exit to Menu Button :
void OnMouseDown() {
PauseGame.isPause=false;
Application.LoadLevel("MainMenu");
}
Play button :
void OnMouseDown() {
spriteRenderer.sprite = s2;
Application.LoadLevel("Game");
}
I have three Prefabs:
Turret :
using UnityEngine;
using System.Collections;
public class Turret : MonoBehaviour {
// Use this for initialization
double LastBallTime=0.0;
double LastTurretMovingTime=0.0;
public double spawnballTime=1.5;
public double StartTurretMovingTime=35.0;
public double BallCount=2;
public bool IsRed=false;
public GameObject BallPrefab;
public GameObject RedBallPrefab;
Vector2 v ;
void Start () {
}
// Update is called once per frame
void Update () {
if (Time.time > LastBallTime + spawnballTime) {
LastBallTime=Time.time;
int rand= Random.Range(1,6);
if(rand>=1 && rand<=4)
Instantiate(BallPrefab, transform.position, transform.rotation) ;
else{
Instantiate(RedBallPrefab, transform.position, transform.rotation) ;
}
}
if (Time.time > LastTurretMovingTime + StartTurretMovingTime) {
LastTurretMovingTime=Time.time;
int x = Random.Range (-2,3);
int y = Random.Range (-3,3);
v = new Vector3 (x, y,0);
gameObject.transform.position=v;
}
}
void OnBecameInvisible ()
{
Destroy(gameObject);
}
}
BALL :
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class Ball : MonoBehaviour {
// Use this for initialization
public static double Killed=0;
public Text ScoreTextPrefab;
GameObject ParentCanvas;
void Start () {
ParentCanvas = GameObject.Find ("Canvas");
}
void OnMouseDown() {
if (!PauseGame.isPause) {
Text t = Instantiate (ScoreTextPrefab, transform.position, transform.rotation) as Text;
t.transform.SetParent (ParentCanvas.transform, false);
if (gameObject.name.Contains ("RedBall")) {
t.text = "O o P s";
RedKilled++;
} else {
Killed++;
}
Object.Destroy (gameObject);
}
}
// Update is called once per frame
void Update () {
}
void OnBecameInvisible ()
{
Destroy(gameObject);
}
}
TurretBall manager wish is assigned for the main camera of the game scene :
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class TurretBallManager : MonoBehaviour {
// Use this for initialization
public GameObject TurretPrefab;
public double turretSpawnTime=35;
public double LastTurretTime=0;
public double MaxTurret=10;
int currentTurretCount=1;
public Text Killedtxt;
Vector2 v;
void Start () {
v = new Vector2(0,2);
Instantiate (TurretPrefab, v, Quaternion.identity);
}
void CreateTurret()
{
if (Time.time > LastTurretTime + turretSpawnTime) {
LastTurretTime=Time.time;
currentTurretCount++;
if(currentTurretCount>1)
v.x=TurretPrefab.transform.position.x-currentTurretCount/2;
if(currentTurretCount<=MaxTurret){
Instantiate(TurretPrefab,v,Quaternion.identity);
}
}
}
// Update is called once per frame
void Update () {
Killedtxt.text = "Kill : " + Ball.Killed;
CreateTurret ();
}
}

Related

OnTriggerExit2D getting called unnecessarily

I hope you all are doing well. I have been following a Unity tutorial for a rhythm game and I have found this bug that I could not get past. Essentially, my OnTriggerExit2D is getting called too early. I'll include a picture in the conclusion of this post. I have tried logging the game object and it seems that all of my button objects suffer the same fate. I have included a link of the tutorial that I have been following in the conclusion. Any help towards figuring this out would be helpful.
Tutorial Link: https://www.youtube.com/watch?v=PMfhS-kEvc0&ab_channel=gamesplusjames
What my game looks like, the missed shows up when I've hit it.
Debug Output
GameManager
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public AudioSource theMusic;
public bool startPlaying;
public BeatScroller theBS;
public static GameManager instance;
public int currentScore;
public int scorePerNote = 100;
public int scorePerGoodNote = 125;
public int scorePerPerfectNote = 150;
public int currentMultiplier;
public int multiplierTracker;
public int [] multiplierTresholds;
public Text scoreText;
public Text multiText;
// Start is called before the first frame update
void Start()
{
instance = this;
scoreText.text = "Score: 0";
multiText.text = "Multiplier: x1";
currentMultiplier = 1;
}
// Update is called once per frame
void Update()
{
if(!startPlaying){
if(Input.anyKeyDown){
startPlaying = true;
theBS.hasStarted = true;
theMusic.Play();
}
}
}
public void NoteHit(){
Debug.Log("Note Hit On Time");
if(currentMultiplier-1 < multiplierTresholds.Length){
multiplierTracker++;
if(multiplierTresholds[currentMultiplier-1] <= multiplierTracker){
multiplierTracker = 0;
currentMultiplier++;
}
}
multiText.text = "Multiplier: x"+currentMultiplier;
//currentScore += scorePerNote * currentMultiplier;
scoreText.text = "Score: "+currentScore;
}
public void NormalHit(){
currentScore += scorePerNote * currentMultiplier;
NoteHit();
}
public void GoodHit(){
currentScore += scorePerGoodNote * currentMultiplier;
NoteHit();
}
public void PerfectHit(){
currentScore += scorePerPerfectNote * currentMultiplier;
NoteHit();
}
public void NoteMissed(){
Debug.Log("MISSED!");
multiText.text = "Multiplier: x1";
}
}
BeatScroller
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BeatScroller : MonoBehaviour
{
public float beatTempo;
public bool hasStarted;
// Start is called before the first frame update
void Start()
{
beatTempo = beatTempo / 60f;
}
// Update is called once per frame
void Update()
{
if(!hasStarted){
}else{
transform.position -= new Vector3(0f, beatTempo*Time.deltaTime, 0f);
}
}
}
ButtonController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ButtonController : MonoBehaviour
{
// Start is called before the first frame update
private SpriteRenderer theSR;
public Sprite defaultImage;
public Sprite pressedImage;
public KeyCode keyToPress;
void Start()
{
theSR = GetComponent<SpriteRenderer>();
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(keyToPress))
{
theSR.sprite = pressedImage;
}
if(Input.GetKeyUp(keyToPress))
{
theSR.sprite = defaultImage;
}
}
}
noteObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class noteObject : MonoBehaviour
{
public bool canBePressed;
public KeyCode KeyToPress;
public GameObject hitEffect, goodEffect, perfectEffect, missedEffect;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyToPress))
{
if(canBePressed)
{
gameObject.SetActive(false);
if(Mathf.Abs(transform.position.y) > 0.25){
GameManager.instance.NormalHit();
Debug.Log("Normal Hit!");
Instantiate(hitEffect,transform.position, hitEffect.transform.rotation);
}else if(Mathf.Abs(transform.position.y) > 0.05f){
GameManager.instance.GoodHit();
Debug.Log("Good Hit!!");
Instantiate(goodEffect,transform.position, goodEffect.transform.rotation);
}else{
GameManager.instance.PerfectHit();
Debug.Log("PERFECT HIT!!!");
Instantiate(perfectEffect,transform.position, perfectEffect.transform.rotation);
}
}
}
}
private void OnTriggerEnter2D(Collider2D other)
{
if(other.tag == "Activator")
{
canBePressed = true;
}
}
private void OnTriggerExit2D(Collider2D other)
{
if(other.tag == "Activator")
{
Debug.Log("Exited collider on game object: "+ other.gameObject.name);
canBePressed = false;
GameManager.instance.NoteMissed();
Instantiate(missedEffect,transform.position, missedEffect.transform.rotation);
}
}
}
EffectObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EffectObject : MonoBehaviour
{
public float lifeTime = 1f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
Destroy(gameObject, lifeTime);
}
}
Hmm ... You say that OnTriggerExit2D is called to early? I assume it's called when the elements are still inside one another? If that's the case I guess your bounding boxes don't have the right size, or the right shape. I see arrows, do they have a rectangular bounding box or a polygon one that follows their shape? Are all your bounding boxes the right size?
I figured out what was wrong thanks to AdrAs's comment.
Turns out I had to check the y position of my arrow and collider were well enough below the height of my button box collider. In addition to that, I reshaped my colliders. I found that this code did the trick for me. Thank You All For the Nudges in the right direction.
noteObject -> new OnTriggerExit2D
private void OnTriggerExit2D(Collider2D other)
{
if(other.tag == "Activator" && transform.position.y < -0.32)
{
Debug.Log("Exited collider on game object: "+ other.gameObject.name);
canBePressed = false;
GameManager.instance.NoteMissed();
Instantiate(missedEffect,transform.position, missedEffect.transform.rotation);
}
}

Function in Script not working in editor while calling function of One Script in Another Script but console returns the correct values

The function IncreaseRadius in OrbitFireball script attached to CircleMovementTarget GameObject when called from editProperties Script attached to Radius (+) GameObject does not return the change in values in editor or the original script i.e. OrbitFireball (see on the right in the script OribtFireball, OrbitDistance = 0.1) even when the Console returns the changes just fine (see the console the values increase on hitting the Radius (+) icon).
Unity Version Used: 2017.2.1f1
...
using HoloToolkit.Unity.InputModule;
using UnityEngine;
using System.Collections;
public class OrbitFireball : MonoBehaviour, IInputClickHandler {
public Transform target;
public float orbitDistance = 0.1f;
public float orbitDegreesPerSec = 90.0f;
public GameObject Ball;
// Use this for initialization
void Start () {
}
void Orbit()
{
if(target != null)
{
// Keep us at orbitDistance from target
transform.position = target.position + (transform.position - target.position).normalized * orbitDistance;
transform.RotateAround(target.position, Vector3.back, orbitDegreesPerSec * Time.deltaTime);
// Ball up and down
Ball.transform.position = new Vector3(transform.position.x, transform.position.y, target.position.z);
}
}
// Update is called once per frame
void Update () {
Orbit();
}
public void increaseRadius()
{
if (orbitDistance <= 0.3f)
{
orbitDistance += 0.1f;
Debug.Log(orbitDistance);
}
}
public void OnInputClicked(InputClickedEventData eventData)
{
throw new System.NotImplementedException();
}
}
...
using System.Collections;
using System.Collections.Generic;
using HoloToolkit.Unity.InputModule;
using UnityEngine;
public class editProperties : OrbitFireball, IInputClickHandler {
public void OnInputClicked(InputClickedEventData eventData)
{
if (gameObject.tag == "RadiusPlus")
{
increaseRadius();
}
}
}

Creating a target system

I'm making a target in Unity that looks like a dartboard with three different levels of scoring depending on where you shoot. The issue is that the Score Text wont change when I shoot on the target. I'm a novice and I "translated" below code from Javascript and wondering if you experts could see
if there is any issues with the code?
GlobalScore (attached this to an empty gameObject. I draged the text 'ScoreNumber' to ScoreText slot in Unity)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GlobalScore : MonoBehaviour {
public static int CurrentScore;
public int InternalScore;
public GameObject ScoreText;
void Update () {
InternalScore = CurrentScore;
ScoreText.GetComponent<Text>().text = "" + InternalScore;
}
}
ZScore25 (created 3 scripts (ZScore25, ZScore50, ZScore100) which I attached to the three cylinder gameObject I created)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ZScore25 : MonoBehaviour
{
void DeductPoints(int DamageAmount)
{
GlobalScore.CurrentScore += 25;
}
}
HandgunDamage Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HandGunDamage : MonoBehaviour {
public int DamageAmount = 5;
public float TargetDistance;
public float AllowedRange = 15.0f;
void Update () {
if (GlobalAmmo.LoadedAmmo >= 1) {
if (Input.GetButtonDown("Fire1"))
{
RaycastHit Shot;
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out Shot))
{
TargetDistance = Shot.distance;
if (TargetDistance < AllowedRange)
{
Shot.transform.SendMessage("DeductPoints", DamageAmount, SendMessageOptions.DontRequireReceiver);
}
}
}
}
}
}
Debug.Log (or breakpoints) help you to see where the problem lies. I tested your case with minor changes and the score text value was changing.
I replaced ZScore25,50,100 scripts with a single ZScore script that has score as public field which you can set in the editor.
public class ZScore : MonoBehaviour {
public int Score;
public void DeductPoints() {
Debug.Log("CurrentScore += " + Score);
GlobalScore.CurrentScore += Score;
}
}
..and then I used raycast (the example script below was attached to camera):
void Update () {
if (Input.GetMouseButtonDown(0)) {
var lookAtPos = Camera.main.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane));
transform.LookAt (lookAtPos);
RaycastHit Shot;
if (Physics.Raycast(transform.position, transform.forward, out Shot))
{
Debug.Log ("Raycast hit");
var score = Shot.transform.GetComponent<ZScore> ();
if (score != null) {
Debug.Log ("Hit ZScore component");
score.DeductPoints ();
}
}
}
}

Call function from another script only once in Update

I'm having trouble with some countdown timer functionality. In my GameManager script I'm checking the scene name and checking for idle usage (no mouse movement/no clicking) and kicking off a function in my CountdownTimer script that is counts down the amount of idle time using the function StartPreCountTimer(). Once that timer reaches zero it then instantiates a countdown dialog and kicks off IEnumerator RunTimer() that the user can either cancel to continue playing or let reach zero, at which point the game resets and returns to the intro screen.
The problem I'm having is at the precount step. The GameManager script keeps calling StartPreCountTimer() every frame which obviously prevents the countdown from ever completing because it restarts every frame. How do I fix this? How do a call the function only once from Update?
GameManager Script
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public static GameManager gameManagerInstance = null; // Create Singleton
public GameObject loader;
public GameObject countdownTimer;
public Color defaultBackgroundColor;
public Object startingScene;
public GameObject timeOutWarningDialog;
public float countdownLength;
public float countdownDelay;
private Vector3 prevMousePosition;
private CountdownTimer countdownInstance;
private Scene currentScene;
private GameObject gameManager;
private GameObject canvas;
public static string animalDataFilePathJSON;
public static string animalDataFilePathTex;
void Awake()
{
if (gameManagerInstance == null)
gameManagerInstance = this;
else if (gameManagerInstance != null)
Destroy(gameObject);
DontDestroyOnLoad(gameObject);
gameManager = GameObject.FindGameObjectWithTag("GameManager");
// get and store JSON and Tex filepaths defined in Loader script
animalDataFilePathJSON = GameObject.FindGameObjectWithTag("Loader").GetComponent<Loader>().animalDataFilePathJSON;
animalDataFilePathTex = GameObject.FindGameObjectWithTag("Loader").GetComponent<Loader>().animalDataFilePathTex;
}
void Start()
{
prevMousePosition = Input.mousePosition;
currentScene = SceneManager.GetActiveScene();
countdownInstance = countdownTimer.GetComponent<CountdownTimer>(); // Create an instance of CountdownTimer
}
void Update()
{
currentScene = SceneManager.GetActiveScene();
if (currentScene.name != startingScene.name)
{
countdownInstance.StartPreCountTimer(); // Start Pre-count Timer
if (Input.GetMouseButtonDown(0) || Input.mousePosition != prevMousePosition)
{
countdownInstance.StartPreCountTimer(); // Start Pre-count Timer
if (timeOutWarningDialog != null)
timeOutWarningDialog.SetActive(false);
}
prevMousePosition = Input.mousePosition;
}
}
}
CountdownTimer Script
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class CountdownTimer : MonoBehaviour {
public GameObject timeOutWarningDialog;
public float countdownLength;
public float countdownDelay;
public Object startingScene;
private float countdownInterval = 1;
private GameObject countdownTimer;
private IEnumerator counter;
private Button stopCountButton;
private Text timerTextField;
private GameObject timerInstance;
private GameObject canvas;
// GAME TIMER
public void StartPreCountTimer()
{
CancelInvoke();
if (GameObject.FindGameObjectWithTag("Timer") == null)
Invoke("ShowRestartWarning", countdownDelay);
}
void ShowRestartWarning()
{
canvas = GameObject.FindGameObjectWithTag("Canvas");
timerInstance = Instantiate(timeOutWarningDialog); // instantiate timeout warning dialog
timerInstance.transform.SetParent(canvas.transform, false);
timerInstance.SetActive(true);
Text[] textFields = timerInstance.GetComponentsInChildren<Text>(true); // get reference to timer textfields
timerTextField = textFields[2]; // access and assign countdown textfield
stopCountButton = timerInstance.GetComponentInChildren<Button>(); // get reference to keep playing button
stopCountButton.onClick.AddListener(StopTimer); // add button listener
if (timerInstance.activeSelf == true)
{
counter = RunTimer(countdownLength); // create new reference to counter, resets countdown to countdownLength
StartCoroutine(counter);
}
}
IEnumerator RunTimer(float seconds)
{
float s = seconds;
while (s > -1)
{
if (timerTextField != null)
timerTextField.text = s.ToString();
yield return new WaitForSeconds(countdownInterval);
s -= countdownInterval;
}
if (s == -1)
{
RestartGame();
}
}
void StopTimer()
{
StopCoroutine(counter);
Destroy(timerInstance);
}
void RestartGame()
{
SceneManager.LoadScene(startingScene.name);
}
}

Basic purchase system in Unity3d

In my game exists a opportunity to obtain a COIN, with a certain amount it is possible to release new skins.
Currently the coin score, are being stored correctly.
I have UI canvas where there skins options, I want to know how to do to be purchased these skins if the player has enough coins, or that nothing happens if it does not have enough.
Follow the codes below.
CoinScore
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class BeeCoinScore: MonoBehaviour
{
public static BeeCoinScore instance;
public static int coin = 0;
public int currentCoin = 0;
string highScoreKey = "totalCoin";
Text CoinScore; // Reference to the Text component.
void Awake ()
{
// Set up the reference.
CoinScore = GetComponent <Text> ();
}
void Start(){
//Get the highScore from player prefs if it is there, 0 otherwise.
coin = PlayerPrefs.GetInt(highScoreKey, 0);
}
public void AddBeeCoinScore (int _point) {
coin += _point;
GetComponent<Text> ().text = "Bee Coins: " + coin;
}
void Update ()
{
// Set the displayed text to be the word "Score" followed by the score value.
CoinScore.text = "Bee Coins: " + coin;
}
void OnDisable(){
//If our scoree is greter than highscore, set new higscore and save.
if(coin>currentCoin){
PlayerPrefs.SetInt(highScoreKey, coin);
PlayerPrefs.Save();
}
}
}
Script to add points to CoinScore
using UnityEngine;
using System.Collections;
public class BeeCoin : MonoBehaviour {
public int point;
private float timeVida;
public float tempoMaximoVida;
private BeeCoinScore coin;
AudioSource coinCollectSound;
void Awake() {
coin = GameObject.FindGameObjectWithTag ("BeeCoin").GetComponent<BeeCoinScore> () as BeeCoinScore;
}
// Use this for initialization
void Start () {
coinCollectSound = GameObject.Find("SpawnControllerBeeCoin").GetComponent<AudioSource>();
}
void OnCollisionEnter2D(Collision2D colisor)
{
if (colisor.gameObject.CompareTag ("Bee")) {
coinCollectSound.Play ();
coin.AddBeeCoinScore (point);
Destroy (gameObject);
}
if (colisor.gameObject.tag == "Floor") {
Destroy (gameObject, 1f);
}
}
}
My UI canvas SHOP It's pretty basic, it has 4 images related skins, with price: 100, 200, 300 and 400 coins, 4 buttons to buy below each image, and a button to leave.
C# if possible.
I solve my problem.
On the "buy" button have attached the script BuySkin
And the script BeeCoinScore i added TakeBeeScore,
deleted: if (coin> current Coin) {}, into the void OnDisable
Now it is working perfectly.
BuySkin Script.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class BuySkin : MonoBehaviour {
public int price;
public void OnClick()
{
if (BeeCoinScore.coin >= price) {
BeeCoinScore.coin -= price;
Debug.Log ("New skin added");
}
if (BeeCoinScore.coin < price) {
Debug.Log ("Need more coins!");
}
}
}
BeeCoinScore script.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class BeeCoinScore: MonoBehaviour
{
public static BeeCoinScore instance;
public static int coin = 0;
public int currentCoin = 0;
string totalCoinKey = "totalCoin";
Text CoinScore; // Reference to the Text component.
void Awake ()
{
// Set up the reference.
CoinScore = GetComponent <Text> ();
}
public void Start(){
//Get the highScore from player prefs if it is there, 0 otherwise.
coin = PlayerPrefs.GetInt(totalCoinKey, 0);
}
public void AddBeeCoinScore (int _point) {
coin += _point;
GetComponent<Text> ().text = "Bee Coins: " + coin;
}
public void TakeBeeCoinScore (int _point) {
coin -= _point;
GetComponent<Text> ().text = "Bee Coins: " + coin;
}
void Update ()
{
// Set the displayed text to be the word "Score" followed by the score value.
CoinScore.text = "Bee Coins: " + coin;
}
void OnDisable(){
PlayerPrefs.SetInt(totalCoinKey, coin);
PlayerPrefs.Save();
}
}

Categories