- Home /
The question is answered, right answer was accepted
What is Wrong With The Logic in My Variable?
I am working on creating my In-Game Currency. I have two variables.. one to represent what "gem count" is for the current game session and also what is displayed when you get to the "Game Over" scene; the other is for the overall Bank of gems that I am putting in my store. What is wrong with my logic in my "GameOverManager" script that explains why my overall Bank of gems is not increasing after every game session?
Snippet of my GameOverManager script below:
All of my StoreManager script so far below:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class StoreManager : MonoBehaviour
{
public Text gemCountText;
private int storeGemCount;
void Start ()
{
storeGemCount = PlayerPrefs.GetInt("PLAYERPREFS_GemScore_GameOver"); //storeGemCount is equal to this Playerprefs that I set in GameOverManager
}
void Update ()
{
gemCountText.text = "Gem Count:" + " " + storeGemCount; //This displays the value of storeGemCount
}
}
If you need more information or something else please let me know
You need to provide more information. $$anonymous$$ainly we need to see what the GameOver$$anonymous$$anager script looks like (and not an image please). If the script is too large you can use a service like PasteBin to place it.
@$$anonymous$$avina here is the link: http://pastebin.com/Wu5r0QHG
I'd say probably 90% of that script is irrelevant to my problem, but I won't be the judge on that. I think you might need to see my AfterCollisionWithItems script; that is where the logic is regarding after a character collides with the gems. Here is the link as well: http://pastebin.com/kymxNncq
Answer by TBruce · Nov 07, 2016 at 10:49 PM
In AfterCollisionWithItems
you do this
void Start ()
{
count = 0;
}
void Update ()
{
PlayerPrefs.SetInt ("PLAYERPREF_GemCount", count);
}
and then in GameOverManager
you do this
void Start ()
{
gemScore = PlayerPrefs.GetInt ("PLAYERPREF_GemCount");
gemBankForStore += gemScore;
}
gemScore
will be zero by the time you do this
gemScore = PlayerPrefs.GetInt ("PLAYERPREF_GemCount");
Personally I do not no the reason why you feel the need to have three classes to handle these values. But This should remedy your problem
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class AfterCollisionWithItems : MonoBehaviour
{
public Text countText;
public int count;
private static AfterCollisionWithItems instance;
void Awake ()
{
instance = this;
}
public static AfterCollisionWithItems Instance
{
get
{
return instance;
}
}
public int count;
void Start ()
{
count = 0;
SetCountText (PlayerPrefs.GetInt ("PLAYERPREF_GemCount", 0)); // defaults to 0 if key does not exist
}
void OnTriggerEnter (Collider item)
{
if (item.gameObject.tag == "Sapphire")
{
item.gameObject.SetActive (false);
SetCountText(1, false); // change false to true if you want to update PLAYERPREF_GemCount
}
else if (item.gameObject.tag == "Ruby")
{
item.gameObject.SetActive(false);
SetCountText(2, false); // change false to true if you want to update PLAYERPREF_GemCount
}
else if (item.gameObject.tag == "Diamond")
{
item.gameObject.SetActive (false);
SetCountText(3, false); // change false to true if you want to update PLAYERPREF_GemCount
}
}
void SetCountText (int value, bool updatePlayerPrefs)
{
count += value;
countText.text = "" + count.ToString ();
if (updatePlayerPrefs)
{
PlayerPrefs.SetInt ("PLAYERPREF_GemCount", count);
}
}
}
Getting error CS1501 "No overload for method 'SetCountText' takes '1' arguments" on line 30 in AfterCollisionWithItems. I will be able to test it out in the editor once I debug this error. @$$anonymous$$avina
$$anonymous$$y apologies, this
SetCountText (PlayerPrefs.GetInt ("PLAYERPREF_GemCount", 0));
should be this
SetCountText (PlayerPrefs.GetInt ("PLAYERPREF_GemCount", 0), false);
I originally had created two methods but removed one of the when seeing it was irrelivent.
Here is the updated script (tested - no errors)
using UnityEngine; using UnityEngine.UI; using System.Collections;
public class AfterCollisionWithItems : $$anonymous$$onoBehaviour { public Text countText;
public int count;
private static AfterCollisionWithItems instance;
void Awake ()
{
instance = this;
}
public static AfterCollisionWithItems Instance
{
get
{
return instance;
}
}
void Start ()
{
count = 0;
SetCountText (PlayerPrefs.GetInt ("PLAYERPREF_GemCount", 0), false); // defaults to 0 if key does not exist
}
void OnTriggerEnter (Collider item)
{
if (item.gameObject.tag == "Sapphire")
{
item.gameObject.SetActive (false);
SetCountText(1, false); // change false to true if you want to update PLAYERPREF_GemCount
}
else if (item.gameObject.tag == "Ruby")
{
item.gameObject.SetActive(false);
SetCountText(2, false); // change false to true if you want to update PLAYERPREF_GemCount
}
else if (item.gameObject.tag == "Diamond")
{
item.gameObject.SetActive (false);
SetCountText(3, false); // change false to true if you want to update PLAYERPREF_GemCount
}
}
void SetCountText (int value, bool updatePlayerPrefs)
{
count += value;
countText.text = "" + count.ToString ();
if (updatePlayerPrefs)
{
PlayerPrefs.SetInt ("PLAYERPREF_GemCount", count);
}
}
}
That got rid of the error perfectly. I was stumped on that but now I know that using the arguments inside Playerprefs are totally separate than any other arguments set in previous methods. @$$anonymous$$avina Unfortunately what you have helped me with so far has not fixed my problem. The storeGemCount I see in my Store $$anonymous$$enu is always the same as the gemCount that I get after I die. It is not being added game session after game session (Like you adding money into your bank account).
Okay I am totally lost on this error now.. On line 53 you created SetCountText with 2 arguments... On line 30 I call SetCountText and that also has 2 arguments, not just 1 like the error is implying. All the research I have done on this error were easy fixes, but I am lost on this one. @$$anonymous$$avina I think PlayerPrefs.GetInt is conflicting with what you set SetCountText as on line 53. Am I wrong? :)
@$$anonymous$$avina I just got the chance to try it out and that works perfectly. That is my remedy! Thank you so much. Now that I got the main backbone of the logistics worked out, I am going to merge them into one class as @jmgek kindly explained to me. Thank you so much again :)
Answer by jmgek · Nov 07, 2016 at 09:59 PM
I am just going by what I currently see Right off the bat I can sort of see a problem. For proper design I would suggest using a different approach:
class PlayerPrefs
{
//Static so you don't need to instance a playerPrefs class to refrence the one int
static int GemScore_GameOver = 0;
//Logic to populate GemScore
}
public class StoreManager : MonoBehaviour
{
private int storeGemCount;
void StoreManager()
{
//You don't have to do this if you only reference it once. **Also this only sets the store GemCount at START so you will not be able to update it at runtime. Meaning soreGemCount ONLY grabs the playerPref on the Start of this class, once.**
storeGemCount = PlayerPrefs.GemScore_GameOver;
}
void Update ()
{
//You don't need to assign storeGemCount if you are just refrencing it once. This will grab gemscore from the static var on playerPrefs and update properly
gemCountText.text = "Gem Count:" + " " + PlayerPrefs.GemScore_GameOver;
}
}
Let me know if this makes sense to you, this is a important design practice.
That definitely look a whole lot cleaner! :) $$anonymous$$y only question in this (and I have yet to test it in the editor I am just deciphering what you posted) : How is this pulling from the gemScore found in my GameOver$$anonymous$$anager? @jmgek
So, to me I think you need to understand how classes work (It's not a problem we all start some where)
When we create a class we can instance it,
PlayerPrefs myPlayerPref = new PlayerPrefs();
This holds a object of Class PlayerPrefs, think of it like a holder for all the data for that class (in another class). If you wanted to make any number of instances you can make them to store difrent data, what if you wanted to have 2 PlayerPrefs, you can make:
PlayerPrefs myPlayerPref = new PlayerPrefs();
PlayerPrefs myPlayerPref2 = new PlayerPrefs();
myPlayerPref.GemScore_GameOver = 2;
myPlayerPref2.GemScore_GameOver = 4;
each instance has two values for GemScore that you can access.
if I wanted to do this:
PlayerPrefs myPlayerPref = new PlayerPrefs();
myPlayerPref.GemScore_GameOver = 2;
We are instancing a holder of type PlayerPrefs as myPlayrPref and then setting the GemScore to 2. myPlayerPref is instanced IN THAT CLASS that you create it in. You will be able to access any public (variables, Functions) you have in PlayerPrefs. If you wanted to call a function it would look like this:
class PlayerPrefs
{
public void Some$$anonymous$$ethod()
{
print ("You called a method");
}
}
class $$anonymous$$yOtherClass
{
PlayerPrefs myPlayerPref = new PlayerPrefs();
myPlayerPref.Some$$anonymous$$ethod();
}
So if we wanted to get or set (Properties) of the GemScore all we need to do is call it:
int someRandomInt = myPlayerPref.GemScore_GameOver;
Because I set your GemScore_GameOver in PlayerPrefs to public static, you don't need to create a instance of PlayerPrefs to access it.
That makes a good amount of sense to me, but not 100%. I will just have to sleep on it and keep reviewing it to fully understand. Thank you! Due to me already having multiple other PlayerPrefs stored (in matter completely unassociated with the gemScore), I cannot use your method right now because I would have to change all those other PlayerPrefs as well. I want to get the logistics of my problem figured out, then I will take the time to integrate your cleaner, and more efficient, way of handling PlayerPrefs. :) @jmgek I know your method will also benefit others who come across this question.