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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Unlock Game Levels with in Game Coins

Discussion in 'Scripting' started by Deleted User, May 19, 2018.

  1. Deleted User

    Deleted User

    Guest

    so i have a level selection scene. each level has a price like :

    Level 2 unlock = 550 in game coins.
    Level 3 unlock = 650 in game coins.
    Level 4 unlock = 750 in game coins.
    Level 5 unlock = 850 in game coins.

    in level selection scene , i created an empty gameobject called LevelSelectionManager.

    then i created a script called LevelSelectionMenu and used the script from another thread ,where
    winterfluxstudio wrote that for me .

    here is errors i see now :
    Code (CSharp):
    1. Assets/Scripts/LevelSelectionMenu.cs(18,27): error CS0120: An object reference is required to access non-static member `UnityEngine.Component.GetComponent<PlayerInput>()'
    2.  
    3. Assets/Scripts/LevelSelectionMenu.cs(25,13): error CS1061: Type `UnityEngine.UI.Button' does not contain a definition for `OnClick' and no extension method `OnClick' of type `UnityEngine.UI.Button' could be found. Are you missing an assembly reference?
    4.  
    what is problem?
     
    Last edited by a moderator: May 21, 2018
  2. winterfluxstudio

    winterfluxstudio

    Joined:
    May 4, 2018
    Posts:
    61
    Yeah that was my bad. it's onClick, not OnClick.

    https://docs.unity3d.com/ScriptReference/UI.Button-onClick.html
     
    Deleted User likes this.
  3. BlackMantis

    BlackMantis

    Joined:
    Feb 7, 2010
    Posts:
    1,475
    Hello, the error on line 18 may need to be.
    Code (CSharp):
    1. private PlayerInput userCoins = new PlayerInput();
     
  4. winterfluxstudio

    winterfluxstudio

    Joined:
    May 4, 2018
    Posts:
    61
    "Assets/Scripts/LevelSelectionMenu.cs(18,27): error CS0120: An object reference is required to access non-static member `UnityEngine.Component.GetComponent<PlayerInput>()'"

    This is because

    "userCoins = GetComponent<PlayerInput>().overallScore;"

    you are not telling unity which object you want to get a component from.

    What is the GameObject that the PlayerInput.cs script is attached to? thats what you need to reference


    ie. your PlayerInput.cs is attached to a GameObject called "OOOOO"

    userCoins = OOOOO.GetComponent<PlayerInput>();

    This means you also need to reference it in that script

    public GameObject OOOOO;
     
    Deleted User likes this.
  5. winterfluxstudio

    winterfluxstudio

    Joined:
    May 4, 2018
    Posts:
    61
    I should probably mention a distinction too.

    this is referencing the script component of another object.

    When you have 1 GameObject with multiple scripts, you can use gameObject.GetComponent (gameObject means "this object" - so whatever this script is attached to.

    ie

    ExampleGameObject
    - Script1
    - Script2

    Script1.cs


    Code (CSharp):
    1. private Script2 script2;
    2.  
    3. void Start()
    4. {
    5.     script2 = gameObject.GetComponent<Script2>();
    6. }
     
    Deleted User likes this.
  6. Deleted User

    Deleted User

    Guest

    Code (CSharp):
    1. Assets/Scripts/LevelSelectionMenu.cs(33,19): error CS0117: `PlayerInput' does not contain a definition for `AvailableCoins'
    what should i replace instead of AvailableCoins ?
     
  7. winterfluxstudio

    winterfluxstudio

    Joined:
    May 4, 2018
    Posts:
    61
    Unity is telling you

    "You need to add a reference for AvailableCoins in your PlayerInput.cs script"

    Well, more accurately, it's saying "You're trying to access something called 'AvailableCoins' from the PlayerInput.cs script, but it doesn't exist.'

    so either add it... or use a new reference name TotalCoins, etc

    PlayerInput.cs
    Code (CSharp):
    1. public int AvailableCoins;
    2.  
    3. void Start()
    4. {
    5.  
    6. }
    7.  
    8. void Update()
    9. {
    10.  
    11. }
     
    Deleted User likes this.
  8. Deleted User

    Deleted User

    Guest

    up to now this is the class in level select buildt up.
    and there are errors from first of this class as :
    Code (CSharp):
    1. Assets/Scripts/LevelSelectionMenu.cs(33,19): error CS0120: An object reference is required to access non-static member `PlayerInput.AvailableCoins'
    2.  
    what is problem ?
     
    Last edited by a moderator: May 21, 2018
  9. winterfluxstudio

    winterfluxstudio

    Joined:
    May 4, 2018
    Posts:
    61
    Happy to help as it can be a confusing topic. I went through it myself when I was first starting so I dont mind passing knowledge on.

    Anyway, your issue is that you have a script reference (userCoins)

    private PlayerInput userCoins;

    but you are trying to access PlayerInput.AvailableCoins (which doesnt exist)

    if (PlayerInput.AvailableCoins)

    should be

    if (userCoins.AvailableCoins)

    All of the if statements need to be updated.


    so, about referencing a script
    private ScriptName scriptName;

    We do this to access all of the public variables and functions of the script in question. and the second part scriptName is whats used to call stuff.

    so, when you have a script called Script1.cs

    void Script1Function()
    {
    // do something
    }

    and in Script2.cs, you have this

    public GameObject Script1GO;
    private Script1 script1;

    void Start()
    {
    script1 = Script1GO.GetComponent<Script1>();
    }

    You are essentially saying script1 now contains all of the functions and other stuff from Script1.cs and can be called using it as a preface.

    FinalScore = script1.TotalScore; (set the FinalScore int from a different script)
    FinalScore = TotalScore; (set the FInalScore int within the same script)

    script1.Script1Function() (run Script1.cs' Script1Function from Script2.cs)
     
    Deleted User likes this.
  10. Deleted User

    Deleted User

    Guest

    you mean ,in fact we use script1 as Mediator ?
    now inside inspector field player input GO is missing and is empty .
    Code (CSharp):
    1. UnassignedReferenceException: The variable PlayerInputGO of LevelSelectionMenu has not been assigned.
    2. You probably need to assign the PlayerInputGO variable of the LevelSelectionMenu script in the inspector.
    3. UnityEngine.GameObject.GetComponent[PlayerInput] () (at C:/buildslave/unity/build/artifacts/generated/common/runtime/GameObjectBindings.gen.cs:38)
    4. LevelSelectionMenu.Start () (at Assets/Scripts/LevelSelectionMenu.cs:18)
    i am in level select scene , so i cannot drag and drop that gameobject inside inspector.
    i made it as prefab and then drag it there , but error remain there.
    why ? :)
     
  11. winterfluxstudio

    winterfluxstudio

    Joined:
    May 4, 2018
    Posts:
    61
    "by the way in level select and inside inspector , there is a field for player inputGO.
    how can i drag and drop that gameobject ? because that is in gameplay scene!"

    You need to store a reference to how many coins the player has. This obviously needs to be in the Unity Scene that has the Main Menu and Level Select Menu.

    The problem is (I think) that you hardcode the coins at the start of a new scene. This is an issue... to unlock levels by spending coins, you need to know how many coins the player has.

    What you should do is set this attribute in a script that is in the Main Menu scene, and then when a level is loaded, the player script gets the coin info from that other script

    (Script attatched to a "GameManager" empty game object")
    GameManager.cs
    Code (CSharp):
    1. public int Coins;
    (script attatched to player in Level1, Level 2, Level 3 etc)
    PlayerInput.cs

    Code (CSharp):
    1.  
    2. private GameObject GameManagerGO;
    3. private GameManager gameManager;
    4.  
    5. public Coins;
    6.  
    7. void Start()
    8. {
    9.     GameManagerGO = GameObject.FindWithTag("GameManager");
    10.     gameManager = GameManagerGO.GetComponent<GameManager>();
    11.     Coins = gameManager.Coins;
    12. }
    But this would mean if you are developing Level 1, 2, 3 etc you will get errors and need to use the singleton idea that I posted before. (or delete the prefab before you save the scene and drop a new one in there when developing)
     
  12. winterfluxstudio

    winterfluxstudio

    Joined:
    May 4, 2018
    Posts:
    61
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.SceneManagement;
    3.  
    4. public class ExampleScript1 : MonoBehaviour
    5. {
    6.  
    7.     public int AvailableCoins;
    8.     private static bool created = false;
    9.  
    10.     void Awake()
    11.     {
    12.         if (!created)
    13.         {
    14.             DontDestroyOnLoad(this.gameObject);
    15.             created = true;
    16.         }
    17.     }
    18.  
    19.  
    20. }
    if you attach that to an empty GameObject in your scene with the Menus, it will persist into the next scene (lvl 1, lvl 2 etc)

    so you can call

    ExampleScript1.AvailableCoins

    using the methods I posted earlier.

    doing that will also give you a psuedo-singleton.

    ie. make a prefab of the GameObjects with the scripts like GameManager, PointsManager, WeaponManager etc

    then you can drop them into all your scenes.

    When you play your game (starting at the main menu). it will delete the additional prefabs so only 1 exists - hence a singleton.

    This way you dont get errors during development and do not have to worry about deleting them manually if you have like 400 scenes.
     
    Deleted User likes this.
  13. Deleted User

    Deleted User

    Guest

    ok . let see what is this help and concept .
    i need learn it.
     
    Last edited by a moderator: May 21, 2018
    winterfluxstudio likes this.
  14. winterfluxstudio

    winterfluxstudio

    Joined:
    May 4, 2018
    Posts:
    61
    I think the problem is, because the topic is new to you apparently, and it can be quite complex, you are getting overwhelmed due to the volume of stuff are trying to do.

    It's often better to strip back to the bare minimum so you understand the underlying concepts, otherwise you are just copy/pasting code and will not get very far.

    Review the stuff I posted and try again whenevr you feel like, and if you get stuck just post something. I think you at least get the concept of how to share functions and variables between scripts.
     
    Deleted User likes this.
  15. Deleted User

    Deleted User

    Guest

    now in level select scene there are 2 gameobjects :

    1- gamescorecontroller this one has a script attached to which holds score and highscore of the game

    2- levelunlockcontroller. here there are methods for checking when there is enough score , then unlock scene.

    my question is : how to define this logic? what i do to check if in gamescorecontroller script , var highscore is enough to allow some method in levelunlockcontroller script unlock that scene and save it to external file ?
     
  16. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    It seems like all you would need is access to:

    - the UI (to update unlocked levels, the buy button)
    - your total score, so you know if you can afford the level, and to change it if you spend to unlock
    - a list of unlocked levels; information that is saved & loaded from disk.
    - (possibly some other small details..)

    Your other questions, and setup have to do with getting & using references between game objects/scripts in your game.

    Try to think about these parts separately, and then tie them together. :)
     
    Deleted User likes this.
  17. winterfluxstudio

    winterfluxstudio

    Joined:
    May 4, 2018
    Posts:
    61
    You need to understand the basics of how information is stored and retrieved. This means you should literally try to accomplish this task with the smallest amount of data possible.

    https://unity3d.com/learn/tutorials/topics/scripting/persistence-saving-and-loading-data

    You need to watch that... and watch it again... and keep re-watching it until you understand the concepts in the video. it will teach you everything you need.

    I would like to think I posted a fair amount of code with examples and comments, so if you are still having a hard time, watch the video.

    You should have one variable "Score" and try to persist it between sessions.

    ie. A main menu with a single button "Scene 2" and another scene with a button "scene 1"
    you need to try persisting data between these two scenes, and that video gives a step-by-step tutorial on how to do it.

    Sadly, you've reached the part most of us do... frustration until it finally clicks. Anything else and I would just be repeating myself, or you would have copy/paste code that you dont know how to edit... or why it works.
     
    Deleted User likes this.
  18. winterfluxstudio

    winterfluxstudio

    Joined:
    May 4, 2018
    Posts:
    61
    "my question is : how to define this logic? what i do to check if in gamescorecontroller script , var highscore is enough to allow some method in levelunlockcontroller script unlock that scene and save it to external file ?"

    This is what I mean, I've demonstrated how to do this before. I understand it's frustrating so dont give up though.

    RandomNumber.cs
    Code (CSharp):
    1. public int RandomNumber = 10;
    ScriptTwo.cs

    Code (CSharp):
    1. // reference the GameObject that has the RandomNumber.cs script attached
    2. public GameObject EmptyGameObject;
    3. // reference the RandomNumber.cs script and store it as randomNumber
    4. private RandomNumber randomNumber;
    5. private int myNumber;
    6.  
    7. void Start()
    8. {
    9.     // reference the RandomNumber.cs script in order to get/set values
    10.     randomNumber = EmptyGameObject.GetComponent<RandomNumber>();
    11. }
    12.  
    13. void doSomething()
    14. {
    15.     // set a variable in this script, using a variable from RandomNumber.cs
    16.    myNumber = randomNumber.RandomNumber;
    17. }
     
    Deleted User likes this.
  19. Deleted User

    Deleted User

    Guest

    here is a short description about this thread :
    there are 3 scenes in my game as :

    menu scene
    level select scene
    game scene

    there is a script called gamedata and this script is attached in each of these scene to an empty gameobject.
    this way i have access every where in my game project to score and highscore .
    also i can easily drag them to inspector and assign them.

    but here about level unlocking i asked many questions as you see above. other users have answered . i tried to learn and use their ideas as much as possible.

    finally , i thought more and more. i wrote unlock levels on paper...thinking even more for a logic. until i wrote the method above. what is this method ?
    so , in level scene , i have created an empy gameobject , this time for unlocking system.
    then i created a new script called levelloader and attached it to this gameobject.

    i wrote some fields and method in order to connect these to gamedata script .
    it is working and taking highscore and comparing and unlocking new level as far as here.

    then i created 2 new gameobject as children for new level button. they are an image lock and a text which shows price of each level .

    the problem now is that when i unlock a new level, i used a bool that , for second time , it is not bought.
    but lock image and price text will still remain there. this is the last idea about unlock system that need to be fixed.

    i really like someone who cares , give me some ideas ! thanks alot.
     
  20. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    If I understood your latest "update", your unlocked levels are not showing as unlocked later on?

    If that's the case, you need to save which ones you've unlocked. If you can only unlock in order, just save the highest unlocked level. Use that to know which buttons to enable/disable.
    If you can unlock a level in any order, then you have to keep a list of all of them to compare to when you enable/disable certain buttons/options.
    Remember you'd want to be saving this information to disk.

    Hope that helps.
     
    Deleted User likes this.
  21. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    If the order is crucial, does that mean they can only unlock level 4, if they're already unlocked levels 2 and 3?
    If that's the case, you only need to save the highest unlocked level.
     
  22. Deleted User

    Deleted User

    Guest

  23. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Pardon? How do you save the highest unlocked level? Well, to JSON or binary formatter or player prefs.

    With that info, you can run a loop like so:
    Code (csharp):
    1. for(int i = 0; i < levelsCount; ++i) {
    2.    if(i <= maxUnlockedLevel) {
    3.       buyButton[i].enabled = false;
    4.       playButton[i].enabled = true;
    5.       costText[i].enabled = false;
    6.     }
    7. }
    Something like that
     
    Deleted User likes this.
  24. Deleted User

    Deleted User

    Guest

    please show me ho to save the highest unlocked level to binary formatter. :)

    where should i use your last code?
     
  25. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I feel stuck here with you. All I can think of suggesting to you is that you try to get more familiar with programming, so you are not always stuck. But you don't want to..

    Anyways, how to save it? Just add a variable in the code you're already saving -- I'm sure I've seen you talk about saving to binary formatter, already, in this thread or another.

    Where would you use that code? Well, I imagine you use it on the level loader/picker scene. That was just an example to illustrate a point.
     
    Deleted User likes this.
  26. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I do not really want to get all confused with you & this thread.

    I would suggest just adding the max unlocked level to player prefs for now. Once you're more comfortable with a working system, you can choose to keep using player prefs or move some of your saved data to binary formatter, json or whatever.

    So, to repeat.. just save it in player prefs. Use the max level to decide which buttons/text to toggle on / off in your level selector. When they buy a new level, set the level they bought to the max level bought.

    Do not allow the buy button to be active if it is more than 1 level higher than the max bought level. :)
     
    Deleted User likes this.
  27. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I offered you a suggestion to just use player prefs for now until you are more comfortable.

    I've tried to suggest that you learn parts separately and then tie them together. That's the best way to learn.
     
    Deleted User likes this.
  28. Deleted User

    Deleted User

    Guest

    i have created 3 class in order to unlock new levels . any idea how to fix it?
    Code (CSharp):
    1. public class UnlockLevels : MonoBehaviour
    2. {
    3.     public int myLevels;
    4.     public int price;
    5.     bool unlockState, setUnlockState;
    6.  
    7.     void Update ()
    8.     {
    9.         if (GlobalValues.Levels == 1)
    10.         {
    11.             setUnlockState = false;
    12.         }
    13.         if (!setUnlockState)
    14.         {
    15.             unlockState = true;
    16.             Unlocked ();
    17.         }
    18.         if (myLevels == 2)
    19.         {
    20.             if (GlobalValues.Levels2Unlocked)
    21.             {
    22.                 if (GlobalValues.Levels == 2)
    23.                     setUnlockState = false;
    24.             }
    25.  
    26.             if (!setUnlockState)
    27.             {
    28.                 unlockState = true;
    29.                 Unlocked ();  
    30.             }
    31.             if (!setUnlockState)
    32.             {
    33.                 unlockState = true;
    34.                 Unlocked ();    
    35.             }
    36.         }
    37.    
    38.     }
    39.  
    40.     public void Clicked()
    41.     {
    42.         if (unlockState)
    43.         {
    44.             Select();
    45.         }
    46.         if (!unlockState)
    47.         {
    48.             if (GlobalValues.Levels >= price)
    49.             {
    50.                 Buy();
    51.             }
    52.         }
    53.     }
    54.  
    55.     void Buy()
    56.     {
    57.         if (myLevels == 2) { GlobalValues.Levels2Unlocked = true; }
    58.            
    59.         setUnlockState = false;
    60.         Select();
    61.     }
    62.  
    63.     void Select()
    64.     {
    65.         GlobalValues.Levels = myLevels;
    66.         persistentData.Save();
    67.     }
    68.  
    69.     void Locked()
    70.     {
    71.         setUnlockState = true;  
    72.     }
    73.  
    74.     void Unlocked()
    75.     {
    76.         if (setUnlockState)
    77.         {
    78.             setUnlockState = true;
    79.         }
    80.  
    81.         if (!setUnlockState)
    82.         {
    83.             setUnlockState = true;
    84.         }
    85.     }
    86. }
    87.  
    88.  
    89. public class GlobalValues : MonoBehaviour
    90. {
    91.    
    92.     public static int highscore = PlayerPrefs.GetInt ("TotalScore");
    93.     public static int Levels;
    94.  
    95.     public static bool Levels2Unlocked;
    96.     public static bool Levels3Unlocked;
    97.     public static bool Levels4Unlocked;
    98.     public static bool Levels5Unlocked;
    99.  
    100. }
    101.  
    102.  
    103. public class persistentData : MonoBehaviour
    104. {
    105.     public bool autoLoad;
    106.     public bool autoSave;
    107.  
    108.     void Awake()
    109.     {
    110.         if (autoLoad) { Load(); }
    111.         if (autoSave) { Save(); }
    112.     }
    113.  
    114.     public static void Save()
    115.     {
    116.         BinaryFormatter binaryFormatter = new BinaryFormatter();
    117.         FileStream fileStream = File.Create(Application.persistentDataPath + "/playerInfo.dat");
    118.         PlayerData playerData = new PlayerData();
    119.  
    120.         playerData.highscore = GlobalValues.highscore;  
    121.         playerData.Levels = GlobalValues.Levels;
    122.  
    123.         playerData.Levels2Unlocked = GlobalValues.Levels2Unlocked;  
    124.         playerData.Levels3Unlocked = GlobalValues.Levels3Unlocked;
    125.         playerData.Levels4Unlocked = GlobalValues.Levels4Unlocked;
    126.         playerData.Levels5Unlocked = GlobalValues.Levels5Unlocked;
    127.  
    128.         binaryFormatter.Serialize(fileStream, playerData);
    129.         fileStream.Close();
    130.     }
    131.  
    132.     public static void Load()
    133.     {
    134.         if (File.Exists(Application.persistentDataPath + "/playerInfo.dat"))
    135.         {
    136.             BinaryFormatter binaryFormatter = new BinaryFormatter();
    137.             FileStream fileStream = File.Open(Application.persistentDataPath + "/playerInfo.dat", FileMode.Open);
    138.             PlayerData playerData = (PlayerData)binaryFormatter.Deserialize(fileStream);
    139.             fileStream.Close();
    140.  
    141.             GlobalValues.highscore = playerData.highscore;
    142.             GlobalValues.Levels = playerData.Levels;
    143.  
    144.             GlobalValues.Levels2Unlocked = playerData.Levels2Unlocked;
    145.             GlobalValues.Levels3Unlocked = playerData.Levels3Unlocked;
    146.             GlobalValues.Levels4Unlocked = playerData.Levels4Unlocked;
    147.             GlobalValues.Levels5Unlocked = playerData.Levels5Unlocked;
    148.         }
    149.     }
    150. }
    151.  
    152.     [Serializable]
    153.     class PlayerData    
    154. {
    155.     public int highscore;
    156.     public int Levels;
    157.  
    158.     public  bool Levels2Unlocked;
    159.     public  bool Levels3Unlocked;
    160.     public  bool Levels4Unlocked;
    161.     public  bool Levels5Unlocked;
    162.  
    163.  
    164. }
    165.