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. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Gather Data from a Scene in the Background

Discussion in 'Scripting' started by Aidan0908, Jan 25, 2018.

  1. Aidan0908

    Aidan0908

    Joined:
    Sep 17, 2017
    Posts:
    4
    Hello! I’ve been coding along smoothly with my game but I’ve hit a stumbling block with how my game currently keeps track of points. I have a level select, and below it it shows how many points the player has earned on his best attempt on a level (high score) over the maximum points available for the level. Keeping track of each levels maximum points is the part I am struggling with.

    How I want the maximum points for each level to be determined is that, when loading from the title scene to the loading scene, it loads each level in the background and counts the object with the “point” tag (I know loading every level will be slow, if there is a better way tell me but this way is way better than what I am doing now).

    How I’m doing it right now is that each level has its points stored in a list that manually has to be changed or needs a new entry when a level has it’s points value changed or a level is added.

    If the points for the level were read from the level, it would be so much more efficient. But how can I get the points in a level before the level has been loaded for the first time?

    If code is needed I will add it but I am away from my computer right now and I’m asking more for a concept thing, not fixing an error in my code.

    I am coding in C#.

    Thank you!

    Aidan
     
  2. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Some setup talk first, since I'm unsure exactly how you have things organized...

    The way I would probably handle this is to have a manager object (not a MonoBehaviour- probably just a static class) that keeps track of the player profiles and save data. It would hold the information about the player (names, points gained so far, unlocks, etc) and could also contain the specifics about what the player has accomplished in each individual level. Any data about the player or the player's accomplishments which change during runtime would get stored here. Then, when it comes time to save the game, that manager already holds all of the data necessary to just write it all to the disk right there, and when loading it only needs to overwrite its own field values.

    As for the maximum points in each level- they should be consistent from one playthrough to the next right? If it's data that doesn't need to change after the game is built (meaning the player's actions have no influence on it), then that sounds like the perfect place to use ScriptableObjects- data containers that are just assets in your project. Make a "LevelData" asset for each level, with the name of the level, the total number of points possible to earn there, plus whatever other information you want to be able to be accessible from outside of the level itself- anything visible on the level select screen. The ScriptableObject says what the total number of points possible are, and other achievements that can be earned, while the player data manager keeps track of how many points have actually been earned by the player for that level, and which achievements have been accomplished.

    Now to your actual question.

    If you want the ScriptableObjects to conform perfectly to the total points within the level they represent, without having to manually count and update that value whenever you edit the level in Unity, you can make an editor script for that. Just make a new MonoBehaviour with a "LevelData" ScriptableObject reference, toss that onto an object in the level in question, then drag and drop the specific ScriptableObject that represents that level into that reference. In the custom inspector you make for that MonoBehaviour, you can define any sorts of functionality you like and call those operations with buttons visible in the inspector for that object. That includes iterating over every object in the scene with that tag, adding up the points, and storing it in the ScriptableObject as a total to reference against.
     
    Last edited: Jan 25, 2018
    Aidan0908 likes this.
  3. Aidan0908

    Aidan0908

    Joined:
    Sep 17, 2017
    Posts:
    4
    This helps a lot. I’m using Monobehavior to hold variables I should probably be using in a non-monobehavior script, like you said. I’m not using a ScriptableObject to hold level data. Now that I look at it, I’m doing things a lot harder than I should be. Thanks for your help!