Reputation: 581
I need help solving a problem I just find while scripting for Unity3D.
This is my case:
I have 5 cards on a table. One card will add a point to the score while the other 4 will take a life away. The right card is ramdomly choose on a script attached to a different object present on the scene.
In my first card I have this script attached
public void SelectCard()
{
switch (externalVariable)
{
case 1:
UnityEngine.Debug.Log("You win a point!");
Application.LoadLevel("Mini Game 1");
break;
case 2:
UnityEngine.Debug.Log("You lose a life!!!");
Application.LoadLevel("Mini Game 1");
break;
case 3:
UnityEngine.Debug.Log("You lose a life!!!");
Application.LoadLevel("Mini Game 1");
break;
case 4:
UnityEngine.Debug.Log("You lose a life!!!");
Application.LoadLevel("Mini Game 1");
break;
case 5:
UnityEngine.Debug.Log("You lose a life!!!");
Application.LoadLevel("Mini Game 1");
break;
}
}
As you can see, if the random number is one the player will score one point if he choose the first card, but if the random number is different and the player choose the first card, he will lose a life.
The random number is stored on a int variable. To acces it, I add this to the start() section of the script attached on the first card
externalVariable= externalObject.GetComponent<MiniGame1RightCard>().rightCard;
UnityEngine.Debug.Log("The right card is card number: " + externalVariable);
So, the first card will access the random number generated by the external script attached to a different object present on the same scene, store it, and then tell me by console output which one is the right card. Then, when the player clic the first card, the script will compare the random number stored on externalVariable to check if the first card is actually the right card or not. Either way, the last step is reload the same scene to start all over again.
The very fist time the scene is loaded everything runs perfect. My problem start with the second time the scene is loaded: externalVariable is always zero. Now for the tricky part, if I put the very same code on the Update() section instead of the Start() section, for one or two seconds the externalVariable stays at zero and then change for the random number generated.
My guess is, I'm doing something wrong when I reload the scene to start again, but I don't know what.
Any ideas about why the code works fine the very first time on the Start() section and every single time on the Update() section???
UPDATE UPDATE UPDATE UPDATE UPDATE.
The whole code attached to card1
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.IO;
using System;
using System.Threading;
public class Card1: MonoBehaviour
{
private string querySeleccionar = "SELECT Nivel FROM LevelAndDifficultyWHERE id=1;";
Text textoSilaba1;
public GameObject cardImage1;
public int level;
public int externalVariable;
public GameObject objetoExterno;
public void SeleccionarSilaba()
{
switch (externalVariable)
{
case 1:
UnityEngine.Debug.Log("You win a point!");
Application.LoadLevel("Mini Juego 1");
break;
case 2:
UnityEngine.Debug.Log("You lose a life!!!");
Application.LoadLevel("Mini Juego 1");
break;
case 3:
UnityEngine.Debug.Log("You lose a life!!!");
Application.LoadLevel("Mini Juego 1");
break;
case 4:
UnityEngine.Debug.Log("You lose a life!!!");
Application.LoadLevel("Mini Juego 1");
break;
case 5:
UnityEngine.Debug.Log("You lose a life!!!");
Application.LoadLevel("Mini Juego 1");
break;
}
}
public void OnMouseDown()
{
}
// Use this for initialization
void Start ()
{
//lot of database stuff
switch (level)
{
case 1:
//lots of cases
}
externalVariable= externalObject.GetComponent<MiniGame1RightCard>().rightCard;
UnityEngine.Debug.Log("The right card is card number: " + externalVariable);
}
// Update is called once per frame
void Update ()
{
}
}
The script that generate the random number
using UnityEngine;
using System.Collections;
public class MiniGame1RightCard: MonoBehaviour
{
public int rightCard;
// Use this for initialization
void Start ()
{
silabaCorrecta = UnityEngine.Random.Range(1, 5);
UnityEngine.Debug.Log("The right card is card number " + rightCard);
}
// Update is called once per frame
void Update ()
{
}
}
Upvotes: 0
Views: 114
Reputation: 963
As Neeraj already mentioned you are generating your randoms and trying to get it's values on the same game cycle (that runs just once per object creation) and Unity can execute them in any order (between both of them any can run first so if Unity runs your card script before your random generator it will not work cause you didn't created your random values yet).
The easily solution is to run your random generator logic at Awake() method instead of Start().
Also, you can take a look in some good programming practices, as I see you comment that there is a lot of cases in your conditional switches maybe you can apply a better modeling using polymorphism properly. (just google something like "changing switches for polymorphism" or somethink like this and research a little)
Upvotes: 1
Reputation: 967
This is a expected behavior in unity, because whenever scene loads then previous gameobjects and scripts always gets destroyed and recreated again. If you want to preserve the script file or gameobject which is generating random number, you have to make that class a persistent class, so it doesn't get destroyed on scene load.
here is example of generic persistent class using UnityEngine;
//This is the parent class of all the singlton classes
public class Persistent<T> : MonoBehaviour
where T : Component
{
private static T instance;
public static T Instance {
get {
if (instance == null) {
instance = FindObjectOfType<T> ();
if (instance == null) {
GameObject obj = new GameObject ();
//obj.hideFlags = HideFlags.HideAndDontSave;
instance = obj.AddComponent<T> ();
}
}
return instance;
}
}
public virtual void Awake ()
{
//DontDestroyOnLoad (this.gameObject);
if (instance == null) {
instance = this as T;
} else {
Destroy (gameObject);
}
}
}
now if you inherit any class from this class will not destroy on scene load. And this how you can inherit from this class.
public class MiniGame1RightCard : Persistent<MiniGame1RightCard>
Upvotes: 0