Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Am I right by adding a ",0" or is that redundant?

Discussion in 'Scripting' started by Calumniator, Jul 18, 2023.

  1. Calumniator

    Calumniator

    Joined:
    Jul 5, 2023
    Posts:
    24
    A friend of mine showed me his code and everytime he grabbed a PlayerPref the code looked like:
    checkCash = PlayerPrefs.GetInt("Cash");
    Every time I grab a PlayerPref my code looks like:
    checkSkull = PlayerPrefs.GetInt("Skull", 0);
    When I remembe correctly the the ,0 is added in case the PlayerPref isn't set already so it will be 0 instead of "nothing". Is that the correct way or am I wasting space because this is redundant?
     
  2. CodeRonnie

    CodeRonnie

    Joined:
    Oct 2, 2015
    Posts:
    280
    There's no such thing as a "nothing" value for an int, except in the special case of using nullable int types, but that's not what's happening here. The default value for int is 0, and without looking at source for PlayerPrefs.GetInt(string), I would assume that if the value is not found the default value of 0 would be returned. However, I would just test that with a value that you know has not been assigned, and that should tell you the value that will be returned by default. If the default value that is returned is 0, then specifying it is redundant. However, it's entirely possible that in the source code PlayerPrefs.GetInt(string) just calls directly into PlayerPrefs.GetInt(string, int) with a default value of 0. So, you could be skipping one method in the call stack by jumping directly to the final method that will ultimately be called in either case. However, I don't know that that's the case, it's just a possibility. I doubt it's causing any real issue, but in any case you should do a bit of testing to confirm what the default int value is when the key is not found. I'd be willing to bet it's 0. In which case it's "redundant," but not inherently wrong.
     
    Calumniator likes this.
  3. Calumniator

    Calumniator

    Joined:
    Jul 5, 2023
    Posts:
    24
    I'm somewhat new to coding but there has to be a way do do it "right". I mean thousands of people use PlayerPrefs so I'm pretty sure one way to use them is considered the "right" way.
     
  4. CodeRonnie

    CodeRonnie

    Joined:
    Oct 2, 2015
    Posts:
    280
    If PlayerPrefs.GetInt("SomeKeyThatDefinitelyDoesNotExist") returns 0, then it's probably more readable to just not write an expected default value of 0. The PlayerPrefs.GetInt(string, int) method is designed more for cases when your default value is not the default value for all int variables.

    However, issues like this where the behavior is essentially identical are more about preference and readability. If you asked a thousand developers you would not get one "right" answer from all of them. If the functionality of the code is nearly identical it's more important that you and your colleagues have a style you all agree on.
     
    Last edited: Jul 18, 2023
    Calumniator likes this.
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    This is engineering. There is no "right." Every way has tradeoffs, pros and cons.

    Your best bet is to try not to apply dogmatic "ALWAYS DO XXX!" methodologies.

    That approach will cripple and impair your learning and progress until you give it up.

    Instead, try to understand what you're doing and reason about the different ways of doing things.
     
    Sluggy, Calumniator and orionsyndrome like this.
  6. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,082
    Thousands of people use them but almost every one of them is using them incorrectly. PlayerPrefs is intended for storing player preferences with "player" in this case referring to the game runtime not the person playing. So if the "right" way is important to you the answer is to not store anything but preferences (eg resolution, volume, etc).

    Speaking of correct ways like @CodeRonnie mentioned you should test things you don't know as a test result is far more valuable than people guessing and for things like this most people are just going to guess rather than test for you. I was curious though so I ran a quick test. Here's my script and my results.

    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class NewBehaviourScript : MonoBehaviour
    4. {
    5.     void Start()
    6.     {
    7.         Debug.Log(PlayerPrefs.GetInt("Foo"));
    8.         Debug.Log(PlayerPrefs.GetFloat("Foo"));
    9.         Debug.Log(PlayerPrefs.GetString("Foo"));
    10.     }
    11. }
    upload_2023-7-18_12-23-25.png
     
    Last edited: Jul 18, 2023
  7. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,495
    It's not even possible, that's how it actually works.

    So the version without the default value is just for convenience. However in a lot of cases you usually want a default value. Like for the game volume or other game settings. That's what PlayerPref(erences) are made for.
     
  8. Calumniator

    Calumniator

    Joined:
    Jul 5, 2023
    Posts:
    24
    Thanks a lot for all your answers!

    But it seems there is one thing I need to know too. Some of you said it is "wrong" to store anything apart from game settings in PlayerPrefs. May I ask why? I mean it's a pretty easy way to store something (like a score) between scenes for example. Why is it a bad idea to use PlayerPrefs for something like that? I'm really wondering because pretty much every tutorial out there tells you to do so.
    Thanks in advance.
     
  9. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    Well it's purpose is in the name. "PlayerPrefs", ergo, "Player Preferences", which is what it was designed for.

    Leaning on it for more than that, such as communicating between scenes and save games, is basically akin to leaning on a crutch. It limits what you do, especially if you come to over rely on it and depend on it too much across your project. It just doesn't scale that way.

    There are better, and more scaleable ways to, for example, save a score between scenes - which isn't that difficult in the grand scheme of things. You could use a static value, or a scriptable object, or any number of other methods. Yes player prefs can work and it's 'easy', but once you need to scale bigger than that, you'll find yourself limited.
     
    Ryiah and Calumniator like this.
  10. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,495
    It's not strictly "wrong" but you're using a system that was never designed for that. Especially on windows builds the player prefs are actually stored in the windows registry where preferences of settings of the OS and other applications are stored. However that's not really a place to store savegames. PlayerPrefs also have the disadvantage that you can not actually query which one exists. So when you go crazy and creating tons of different keys, there's no built-in way to determine which keys may exist. Storing large amount of data is also not that great but of course it's possible. In fact I would say when you actually use PlayerPrefs to store the progress, I would use a single string value and just store a json that contains everything I need. That way you don't create countless of keys.

    For inter-scene communication it doesn't make much sense to actually write data into a database / on disk just to load it again a few ms later. You can use a static class or singleton to remember data between scenes. By singleton I mean a plain C# singleton or a ScriptableObject based singleton, not a MonoBehaviour as they will be destroyed when a new scene is loaded.

    Yes it's possible to carry object over from one scene to another by using DontDestroyOnLoad. However if not used right you just end up with duplicate objects. So be careful with that.

    Finally note that tutorials don't "tell you to do something" but they just show a way how it could be done. Many tutorials have been made by intermediate developers. So don't take tutorials as the "word of god". A lot tutorials promote bad things ^^. When it comes to software development there's no clear right and wrong. How good or bad something is generally depends on many factors. Certain things are totally fine when you are a solo indy developer but are considered bad practise when you need to work in a team. Some things work fine in small scale projects but don't scale well.

    Not every game needs abstract factories and fancy design patterns when it's just a small game project. However when you design a large scale project with hundreds of developers, a lot of network interactions and a huge ecosystem, you better start organising the code and architecture of the project.

    Design principles and programming paradigms are just there to restrict yourself to not do stupid stuff that you don't understand. I can recommend this video about programming paradigms.
     
    Ryiah, Calumniator and spiney199 like this.
  11. Calumniator

    Calumniator

    Joined:
    Jul 5, 2023
    Posts:
    24
    Again thanks for your answers! :)
    I'll take a deeper look at those other ways to store data. Using the windows registry all the time really seems to be a bad idea. ^^ And thanks for the link to the video about programming paradigms. I'll sure watch that too!.