boolean not updating with code in Unity - c#

I have a script that changes the score randomly. A and B. I want the scores to change the button type from false to true depending on the condition. For some reason it won't change.
Unless the scores are even, the last script should continually change the true or false. I also only want these to last until the next button is pushed.
I have printed out the information, so I know the scores are being pulled in they just don't seem to be calculating.
public static bool yayButton = false;
public static bool booButton = false;
ScoreManager.scoreDisplayA;
ScoreManager.scoreDisplayB;
if(ScoreManager.scoreDisplayA > ScoreManager.scoreDisplayB){
yayButton = true;
}
if(ScoreManager.scoreDisplayB > ScoreManager.scoreDisplayA){
yayButton = true;
}

You set yayButton to true in both condition, So this is your first mistake.
With this code once one of your variable become true, it always will be true so I think you need to turn other variable to false.
And this code must be in Update() or FixedUpdate() method to detect new change of ScoreManager.
Your final code should be something like this:
public static bool yayButton = false;
public static bool booButton = false;
ScoreManager.scoreDisplayA;
ScoreManager.scoreDisplayB;
void Start()
{
// define the ScoreManager.scoreDisplayA and B here.
// Something like this:
// ScoreManager.scoreDisplayA = GameObject.Find("ScoreManager").GetComponent<scoreDisplayA>();
}
void Update()
{
if(ScoreManager.scoreDisplayA > ScoreManager.scoreDisplayB){
yayButton = true;
booButton = false;
}
if(ScoreManager.scoreDisplayB > ScoreManager.scoreDisplayA){
yayButton = false;
booButton = true;
}
}

Related

Unable to get coroutine to start and stop when button is down

I am working on the walking sounds for my game, I am wanting it to play a sound and then wait and play the next. As it is walking I only want it to do this when w is pressed. I have been trying to use an Enumerator to do so but I am having issues where it will not start the function.
private IEnumerator audioPlayCoroutine;
public AudioSource[] steps;
public AudioSource[] cabinSteps;
private bool running;
void Start()
{
running = false;
audioPlayCoroutine = AudioPlay();
}
void Update()
{
if (Input.GetKey("w"))
{
if (running == false)
{
running = true;
}
}
if (running == true)
{
StartCoroutine(audioPlayCoroutine);
}
else if (running == false)
{
StopCoroutine(audioPlayCoroutine);
}
}
IEnumerator AudioPlay()
{
int ran = Random.Range(0, 4);
steps[ran].Play();
yield return new WaitForSeconds(2);
}
Okay, there are multiple reasons why it doesn't work:
For one running is never set to false. Once your player pressed w once, it will stay true.
Instead write
if (Input.GetKey("w"))
running = true;
else
running = false;
Additionally you start and stop your Coroutine multiple times.
Instead you should either check, whether the running status either changed or you should just check running in your coroutine.
It could then look like this:
void Start() {
running = false;
audioPlayCoroutine = AudioPlay();
StartCoroutine(audioPlayCoroutine);
}
void Update() {
if (Input.GetKey("w"))
running = true;
else
running = false;
}
IEnumerator AudioPlay()
{
while (true) {
if(!running)
yield return new WaitForSeconds(0);
int ran = Random.Range(0, 4);
steps[ran].Play();
// if you want it to play continuously, you can use the clip length for
// the sleep. This way it will start playing the next clip right after
// this one is done. If you don't want that, go with your code
yield return new WaitForSeconds(steps[ran].clip.length);
}
}
If your clip is actually 2 seconds long, you might also want to interrupt it from playing once your user stops pressing the button.

Unity 3d Animation

I m a newbie to Unity3d and was just playing with unity animation, i was trying to implement 2 Main UI Button such as when either of them is pressed it should check the condition whether a animation is already played before by 2nd button available if yes then remove those gameobject from scene using reverse animation else play the default animation attach to the particular button.
Problem is out of 6 case only 4 are getting operational 2 of them are not executing (marked in the code as Case Not Operational)
Animation anim;
private bool isOpen = false;
private bool open = false;
// Start is called before the first frame update
void Start()
{
anim = GetComponent<Animation>();
//isOpen = false;
//open = false;
}
// Update is called once per frame
void Update()
{
}
void OnGUI()
{
isOpen = GUI.Toggle(new Rect(50, 50, 200, 100), isOpen, "IsOpen");
open = GUI.Toggle(new Rect(65, 65, 200, 100), open, "Open");
}
public void ButtonControl()
{
string name = EventSystem.current.currentSelectedGameObject.name;
if (name == "Main Button 1")
{
if (isOpen == false && open == false)
{ Debug.Log("False False 1");
Anim1();
isOpen = true;
}
else if (isOpen == false && open == true) // case not operational
{ Debug.Log("False True 2");
ReverseAnim_2();
open = false;
Anim1();
isOpen = true;
}
else if(isOpen == true)
{
Debug.Log("True 3");
ReverseAnim_1();
isOpen = false;
}
}
else if (name == "Main Button 2")
{
if (open == false && isOpen == false)
{ Debug.Log("False False 4");
Anim2();
open = true;
}
else if(open == false && isOpen == true) // case not operational
{ Debug.Log("False True 5");
ReverseAnim_1();
isOpen = false;
Anim2();
open = true;
}
else if(open == true)
{
Debug.Log("True 6");
ReverseAnim_2();
open = false;
}
}
}
void ReverseAnim_1()
{
anim["1"].speed = -1;
anim["1"].time = anim["1"].length;
anim.Play();
}
void Anim1()
{
anim["1"].speed = 1;
anim.Play();
}
void Anim2()
{
anim["2"].speed = 1;
anim.Play();
}
void ReverseAnim_2()
{
anim["2"].speed = -1;
anim["2"].time = anim["2"].length;
anim.Play();
}
The problem is that you have two Main_B2 scripts and they are each tracking their own values for the isOpen and open fields.
One solution for this could be to make the fields static so that they are in common across all instances of Main_B2.
Animation anim;
private static bool isOpen = false;
private static bool open = false;
If you do this, your code should work as intended - each instance of Main_B2 would then be referring to the same fields whenever they reference isOpen or open.
With that said, static fields can get kind of sloppy if you ever want to try and re-use code so a better option might be to have only one instance of Main_B2 somewhere else such as the Canvas, instead of one on each button.
Then you could have in it public GameObject fields that you can drag the button objects into, and private Animation fields for the animations.:
public GameObject button1
public GameObject button2
private Animation anim1
private Animation anim2
Then in Start:
anim1 = button1.GetComponent<Animation>();
anim2 = button2.GetComponent<Animation>();
And then wherever you referred to anim you would refer to anim1 or anim2 instead:
void ReverseAnim_1()
{
anim1.["1"].speed = -1;
anim1.["1"].time = anim1["1"].length;
anim1.Play();
}
void Anim1()
{
anim1["1"].speed = 1;
anim1.Play();
}
void Anim2()
{
anim2["2"].speed = 1;
anim2.Play();
}
void ReverseAnim_2()
{
anim2["2"].speed = -1;
anim2["2"].time = anim2["2"].length;
anim2.Play();
}
Your scripts 'anim' variable is an Animation. Normally to adjust animation parameters you set them on an Animator, not Animation. But perhaps your solution can work.
For clarity. An animator organizes how animations play out, when, for how long and how they transition.
I would personally advise you to use an animator with behaviour patterns and transitionings between animations. Instead of the current approach.
Either that or use one of the many Tweening asset packs from the asset store. They are specifically made to create UI effects like what you describe.
At least consider these solutions if you keep being stuck :-)

Using same Boolean with multiple objects in Unity 2D

I have four game objects with the same script and the same bool, when one of them get hit by ray the bool state is true, but the function will not start because the other three game objects is set to false.
What I tried:
the code works fine with the last object being instantiated
if I disabled the script on the first object and re-enabled it again the function works fine on this object only
public bool selected;
void Start(){
selected = false;
}
void Update(){
showRange ();
}
public void showRange(){
if (selected == true) {
for (int i = 0; i < tileRange.Count; i++) {
tileRange [i].GetComponent<SpriteRenderer> ().enabled = true;
}
} else {
for (int i = 0; i < tileRange.Count; i++) {
tileRange [i].GetComponent<SpriteRenderer> ().enabled = false;
}
}
}
Simply use a static variable: What is the use of static variable in C#? When to use it? Why can't I declare the static variable inside method?
You would have:
public static bool selected;
Try using gamemanager.
public static gamemanager Instance;
public bool selected;
private void Awake()
{
Instance = this;
}
Your gamemanager can have a public bool variable "selected".
New start method:
void Start() {
gamemanager.Instance.selected = false;
}
New showRange function
public void showRange(){
if (gamemanager.Instance.selected) {
for (int i = 0; i < tileRange.Count; i++) {
tileRange [i].GetComponent<SpriteRenderer> ().enabled = true;
}
} else {
for (int i = 0; i < tileRange.Count; i++) {
tileRange [i].GetComponent<SpriteRenderer> ().enabled = false;
}
}
}
I am sure this code can be improved. Let me know if it helps.
The problem isn't in the selected bool, but it's in showRange() method. If the ray hit one object it will be selected and the other three will remain unselected ((that's because I use a list that stores the last hitted object, then the code works only for the object inside this list))
showRange() will not work with the selected object, because the method want all the four object to be selected, then it works (stupid method, I was unable to sleep because of it).
I managed to fix showRange() problem, using a new script that turns off all game objects script component and turns on the selected one script, this will make showRange() method unable to check the bool state of the other three objects.
For (Guilherme, misher and Josep) thank you for your help, I really appreciate it, but as it is shown above the problem wasn't in the Boolean.
For (Muhammad Farhan Aqeel) I believe your code should work, but I didn't manage to get it work maybe because I'm still new to programming.

How can I save the playerprefs of a boolean variable?

I am trying to code a mute button, and it works, however the setting of that button is not saved.
public void Mute (){
AudioListener.volume = 0;
sound.enabled = false;
sound.image.enabled = false;
noSound.enabled = true;
noSound.image.enabled = true;
}
public void UnMute (){
AudioListener.volume = 1;
sound.enabled = true;
sound.image.enabled = true;
noSound.enabled = false;
noSound.image.enabled = false;
}
I have 2 methods here, and I need it to save the state of which one was clicked using playerprefs. I was thinking something along the lines of a boolean, but I'm stumped, and and I can't wrap my head around how I would do that.
Yes you can do that with the help of a boolean variable as like the following:
public bool isMuted = false;
public void Do_muteOperation()
{
if (isMuted)
{
UnMute();
isMuted = false;
}
else
{
Mute();
isMuted = true;
}
}

How can I check if the level is loaded in Unity3D

I've started learning C# and Unity3D this year and I've come across a problem. I'm loading a new level and the player object gets initialized before the the level has finished loading.
I think I only need to check whether the level is loaded or not before initializing the object. I don't know if I could use LoadLevelAsync. I'm using Unity3D Personal Edition.
My current code:
MasterClient.cs
void Update(){
if(SceneUpdateRequired)
{
Application.LoadLevel(SceneUpdateID);
if (Application.isLoadingLevel == false)
{
SceneUpdateRequired = false;
SceneUpdateCompleted = true;
}
}
}
void CharacterLoginUpdate(){
if (SceneUpdateCompleted == true)
{
GameObject networkPlayerObj = (GameObject)Instantiate(NPlayerObj, PlayerLoginUpdatePosition, PlayerLoginUpdateRotation);
NPlayer networkPlayer = networkPlayerObj.GetComponent<NPlayer>();
networkPlayer.UpdatePlayerInstantiateCompleted(PlayerLoginUpdateNetworkID, PlayerLoginUpdateHP, PlayerLoginUpdateClass, PlayerLoginUpdateLevel, PlayerLoginUpdateName, PlayerLoginUpdatePosition);
PlayerLoginUpdateRequired = false;
}
}
The problem with your code is your are loading level in update where if you dont control the task with booleans you are going to end up with big problems.
your update code should be as follows
void Update(){
if(SceneUpdateRequired)
{
Application.LoadLevel(SceneUpdateID);
SceneUpdateRequired = false;
}
if (Application.isLoadingLevel == false)
{
SceneUpdateRequired = false;
SceneUpdateCompleted = true;
}
}
This way the scene code will try to load level only when you request it to and not every time in update loop as loading levels is heavy.
Another thing is you might encounter one more problem if you need to use
SceneUpdateRequired,SceneUpdateCompleted variables somewhere else the
if (Application.isLoadingLevel == false)
{
SceneUpdateRequired = false;
SceneUpdateCompleted = true;
}
the above part which is in update loop will reset the variables everytime whenever its not loading the level. To prevent this you will have to introduce another boolean flag to stop its update happening everytime. So your code will end up looking like this if you want to prevent everyframe update
void Update() {
if(SceneUpdateRequired){
Application.LoadLevel(SceneUpdateID);
SceneUpdateRequired = false;
}
if (Application.isLoadingLevel == false && StartCheckingLoadLevel){
SceneUpdateRequired = false;
SceneUpdateCompleted = true;
StartCheckingLoadLevel = false;
}
}
void StartLoad() {
SceneUpdateRequired = true;
SceneUpdateCompleted = false;
StartCheckingLoadLevel = true;
}
void CharacterLoginUpdate(){
if (SceneUpdateCompleted == true) {
Debug.Log("Do Something after load");
} else {
Debug.Log("Scene not yet loaded");
}
}
Hope this helps.

Categories

Resources