Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by harpoaian · Apr 05, 2018 at 02:22 PM · level design

How to check if the player has beaten a seperate scene that is required to progress in another scene

Sorry if the question was worded badly XD

So basically my team and I have been hitting a wall for a couple of days now with our game. Our game has 12 levels but 16 playable scenes. Level 12 is the last level but in level 12 we have four sub rooms that are their own separate scenes. The player has to complete the sub rooms in order to unlock the elevator in level 12. We used to stream all the levels in the game but as a team we decided to not go about the streaming way because it was too intense on our resources. So my question is how can I make it so that the elevator in level 12 knows that the player completed the 4 sub rooms? Would anyone be able to point me in the right direction?

Kindly,

Harpoaian

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image fafase · Apr 18, 2018 at 06:35 AM 0
Share

Use PlayerPrefs. $$anonymous$$ost simple way. Works all the time. Can be used from anywhere. PlayerPrefs.

That sounds like a PR announcement...

4 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by melsy · Apr 06, 2018 at 12:03 AM

Simple serialized class with bools would work very easy as well. Have either 4 bools, one for each section , or a bool array, and have the bool set to true on completing the section. Then just save that to the player data and check that data when the player gets to the elevator.
How is the team handling the save data.

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image harpoaian · Apr 17, 2018 at 09:46 PM 1
Share

Sorry for the late reply but this is how we save data public static GameData data;

void Awake() { if (data == null) { DontDestroyOnLoad(gameObject); data = this; } else if (data != this) { Destroy(gameObject); } }

 public void Save()
 {
     FileStream file;

     if (File.Exists(Application.persistentDataPath + "/gameInfo.dat"))
     {
         file = File.Open(Application.persistentDataPath + "/gameInfo.dat", File$$anonymous$$ode.Open);
     }
     else
     {
         file = File.Create(Application.persistentDataPath + "/gameInfo.dat");
     }

     BinaryFormatter bf = new BinaryFormatter();

     LevelData data = new LevelData();
     data = SetData(data);

     bf.Serialize(file, data);
     file.Close();
 }

 public void Load()
 {
     if (File.Exists(Application.persistentDataPath + "/gameInfo.dat"))
     {
         BinaryFormatter bf = new BinaryFormatter();
         FileStream file = File.Open(Application.persistentDataPath + "/gameInfo.dat", File$$anonymous$$ode.Open);

         LevelData data = (LevelData)bf.Deserialize(file);
         file.Close();

         AquireData(data);
     } else
     {
         Save();
     }
 }

 private void Delete()
 {
     if (File.Exists(Application.persistentDataPath + "/gameInfo.dat"))
     {
         File.Delete(Application.persistentDataPath + "/gameInfo.dat");
     }
 }

 // Set data to be save
 LevelData SetData(LevelData data)
 {
     // Basic
     data.currentLevel = currentLevel;
     data.completeGame = completeGame;
     data.noUnlockComplete = noUnlockComplete;
     data.timeAttack = timeAttack;

     // Settings
     data.fullscreen = fullscreen;
     data.screenWidth = screenWidth;
     data.screenHeight = screenHeight;
     data.antialiasing = antialiasing;
     data.masterVolume = masterVolume;

     // Level Unlock
     data.level1Unlock = level1Unlock;
     data.level2Unlock = level2Unlock;
     data.level3Unlock = level3Unlock;
     data.level4Unlock = level4Unlock;
     data.level5Unlock = level5Unlock;
     data.level6Unlock = level6Unlock;
     data.level7Unlock = level7Unlock;
     data.level8Unlock = level8Unlock;
     data.level9Unlock = level9Unlock;
     data.level10Unlock = level10Unlock;
     data.level11Unlock = level11Unlock;
     data.level12Unlock = level12Unlock;

     // Level 12 Complete Prefs
     data.lightComplete = lightComplete;
     data.electricComplete = electricComplete;
     data.soundComplete = soundComplete;
     data.thermalComplete = thermalComplete;

     data.playing12 = playing12;

     data.level12CurTimer = level12CurTimer;
     data.level12Start = level12Start;
avatar image melsy · Apr 18, 2018 at 01:33 AM 0
Share

Looks like it got cut off but i get the idea. You are already doing what i thought. Just add those bools and change them to true when the player gets the section complete. Also looking at the save data file it could be simplified quite a bit. Is this a $$anonymous$$onoBehaviour? If so what is the reason for needing this class to be in the scene? A serialized class will keep and hold its variables when it is instantiated by a public static SaveClass saveClass = new SaveClass(); Check out my answer here for a basic save class https://answers.unity.com/questions/1463102/inventory-that-works-across-scenes.html

This can further be simplified by classes that can be defaulted and called during the serialization. So you dont have to set all the variables every time you save and recall every time you load. You only save and load what you need at the moment.

avatar image harpoaian melsy · Apr 18, 2018 at 02:21 PM 0
Share

Hello thank you for the reply I am just slightly confused as to go about implementing your solution. $$anonymous$$y $$anonymous$$mmate that started this venue has been really busy so I wanted to try and help him out by solving this issue (once this issue is solved we will be that much closer to release). To answer your initial question yes this is a public class $$anonymous$$onoBehaviour script. I have been working at this issue for a few days now and I have managed to make it so when the player completes the sub room (electric room in this case) the game data recognizes that I completed the level. When I go back to the main room that data from that completed bool ISN'T carrying over. I am at my wits end on how to fix this.

Here is the function in the Electric Room Script that changes the electriccomplete variable. Do I need to have the gameData save in this function?

 void UnlockHub () 
         {
             //HubRoom.GetComponent<Level12CentralRoom>().electricUnlocked = true;
     
             if(gameDataScript.electricComplete == false)
             {
     
                 gameDataScript.electricComplete = true;
     
                 hasCompletedElectricRoom = true;
     
     
                 Debug.Log("Electric Complete: " + gameDataScript.electricComplete);
     
                 
             }
             
     
         }


avatar image harpoaian harpoaian · Apr 18, 2018 at 03:02 PM 0
Share

Well I took my own advice and I called the save function right after the gameDataScript.electricComplete and it worked! The game data remembered, I swear I look over the simplest things. Thank you for helping me out, it was your previous Unity answer that helped me! All the points to you good sir!!

Show more comments
avatar image
1

Answer by ImpOfThePerverse · Apr 05, 2018 at 03:31 PM

My guess would be something using Object.DontDestroyOnLoad:

https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html

You could create a gameobject with a monobehaviour script with four bools that keep track of whether the player has completed the sub-rooms, and make it persist with Object.DontDestroyOnLoad.

*Edit - You'll probably want to instantiate that gameobject from a script that first checks to see if there is already something in the scene with that component or a unique tag (using FindObjectOfType or FindWithTag).

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by ClumsyLobster · Apr 05, 2018 at 05:36 PM

So, you could have a GlobalDataManager.cs script attatched to an empty game object. This exists in the first scene (so the menu scene). It is persistent between scenes which means you can use scripts from each level (level 2 scene, level 3 scene) to access the component.

ie - Player completes level 1. Access GlobalDataManager and set globalDataManager.hasCompletedLevel1 to true.

Don't allow level 2 to be loaded unless level 1 is complete. Imagine a level select menu, you could make the buttons "not interactable". so the "Load Level 2" button only works when the Level 1 is marked as "complete" in the GDM.

GlobalDataManager.cs

 using UnityEngine;
 
 public class GlobalDataManager : MonoBehaviour
 {
 
     private static bool created = false;
 
     // set booleans for completed levels
     public bool CompletedLevel1;
     public bool CompletedLevel2;
 
         void Awake()
         {
             if (!created)
                 {
                     DontDestroyOnLoad(this.gameObject);
                     created = true;
                     Debug.Log("Awake: " + this.gameObject);
              }
             
              // set default value to false
             CompletedLevel1 = false; 
             CompletedLevel2 = false;
             
         }
 }


Level2.cs

 using UnityEngine;
 
 public class Level2 : MonoBehaviour
 {

 // reference GDM GameObject
 public GameObject GlobalDataManagerGO;

 // reference global data manager
 private GlobalDataManager globalDataManager;

 public bool hasCompletedLevel1;

 void Awake() {

    // find the Global Data Manager GO
     GlobalDataManagerGO = GameObject.FindWithTag("GDM");

     // reference the GlobalDataManager.cs script component of the GDM GameObject
     globalDataManager = GlobalDataManagerGO.GetComponent<GlobalDataManager>();

     }   

 void Start() {

     // access a bool from GlobalDataManager.cs and use it to set a value in this script
     hasCompletedLevel1 = globalDataManager.CompletedLevel1;

     }

 } 

https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html https://docs.unity3d.com/ScriptReference/GameObject.GetComponent.html https://unity3d.com/learn/tutorials/topics/scripting/persistence-saving-and-loading-data

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image harpoaian · Apr 17, 2018 at 03:31 PM 1
Share

Hello sorry for the late reply. Turns out my $$anonymous$$mmate who started working on this solution has a game data empty object with the game data script attached to it. I have implemented your solution to the best of my ability and I can get the game data to state that the electric room is complete and everything works hunky dory BUT the problem that I am having now is when the player leaves the electric room the game data script in the level 12 area says that the electricRoomComplete bool is still running false. So I need to figure out why the variable isn't carrying over to the level 12 room.

avatar image harpoaian harpoaian · Apr 17, 2018 at 03:31 PM 1
Share

Electric Room Script: (important parts)

public GameObject gameDataGO; private GameData gameDataScript; public bool hasCompletedElectricRoom;

 void Awake()
 {
     gameDataGO = GameObject.Find("GameData");

     gameDataScript = gameDataGO.GetComponent<GameData>();
 }

 // Use this for initialization
 void Start () {

     //HubRoom = GameObject.Find ("FinalLift");
     G$$anonymous$$ineticSwitch = GameObject.Find ("G$$anonymous$$ineticSwitch");
     GThermalSwitch = GameObject.Find ("GThermalSwitch");
     GLightSwitch = GameObject.Find ("GLightSwitch");
     GSoundSwitch = GameObject.Find ("GSoundSwitch");

     //gameData = GameObject.Find("GameData");

     hasCompletedElectricRoom = gameDataScript.electricComplete;

     //Referencing each script directly so I can call DoorControl(); from this script.
     $$anonymous$$ainElevScript = (ElecRoomElevator) $$anonymous$$ainElevator.GetComponent(typeof(ElecRoomElevator));
     EntranceElevScript = (ElecRoomEntrance) EntranceElevator.GetComponent(typeof(ElecRoomEntrance));

     if(gameDataGO != null)
     {
         Debug.Log("Game Data has been found");
     }

    
     
 
 }

void UnlockHub () { //HubRoom.GetComponent().electricUnlocked = true;

     if(gameDataScript.electricComplete == false)
     {

         //gameDataScript.electricComplete = true;

         hasCompletedElectricRoom = true;


         Debug.Log("Electric Complete: " + gameDataScript.electricComplete);

         
     }
     

 }

void GroundSwitch () { //If Ground Floor Switch is Triggered

     if (GLightSwitch.GetComponent<ElectricObject>().hasEnergy == true && GThermalSwitch.GetComponent<ElectricObject>().hasEnergy == true &&
         GSoundSwitch.GetComponent<ElectricObject>().hasEnergy == true && G$$anonymous$$ineticSwitch.GetComponent<ElectricObject>().hasEnergy == true && FloorGComplete == false)
     {
             //EntranceElevator.GetComponent<ElecRoomEntrance>().Locked = false;
             //EntranceElevator.GetComponent<ElecRoomEntrance>().Can$$anonymous$$ove = true;
             //EntranceElevScript.DoorControl();
         //Debug.Log("This is the reason why I am repeating");

             //UnlockHub();
             
             FloorGComplete = true;
         //Added Section
         if (FloorGComplete == true)
         {
             EntranceElevator.GetComponent<ElecRoomEntrance>().Locked = false;
             EntranceElevator.GetComponent<ElecRoomEntrance>().Can$$anonymous$$ove = true;
             EntranceElevScript.DoorControl();
             UnlockHub();
             //EntranceElevator.GetComponent<Animation>().Play("EntElvOpen");
             //Debug.Log("The door should only run the animation once");
             //Debug.Log(FloorGComplete);
         }
     }
     

 }

I will post another comment with the level 12 script as I am running out of characters XD

avatar image harpoaian harpoaian · Apr 17, 2018 at 03:33 PM 1
Share
 using UnityEngine;
 using System.Collections;
 
 public class Level12CentralRoom : $$anonymous$$onoBehaviour {
 
     public GameObject lightDoor;
     public GameObject electricDoor;
     public GameObject soundDoor;
     public GameObject thermalDoor;
 
     public GameObject finalPlatform;
 
     GameObject FPC;
 
     public GameObject gameDataGO;
     private GameData gameDataScript;
 
     void Awake()
     {
         gameDataGO = GameObject.Find("GameData");
 
         gameDataScript = gameDataGO.GetComponent<GameData>();
 
     }
     
     // Use this for initialization
     void Start () 
     {
         FPC = GameObject.Find("FPS_Proxy");
         SetPlayer();
         Setup();
         PlayerPrefs.SetString("Playing12", "True");
         //gameData = GameObject.Find("GameData");
         //gameData.GetComponent<GameData>().playing12 = true;
         Debug.Log("Electric Complete: " + gameDataScript.electricComplete);
 
          if(gameDataGO != null)
         {
             Debug.Log("Game Data has been found");
         }
     }
     
     // Setup saves
     void Setup()
     {
         if (PlayerPrefs.GetString("LightComplete") == "True")
         {
             lightDoor.GetComponent<Animation>().Play();
         }
 
         if (gameDataScript.electricComplete == true)
         {
             electricDoor.GetComponent<Animation>().Play();
 
 
             Debug.Log("Electric Complete: " + gameDataScript.electricComplete);
 
             Debug.Log("If I see this that means the completion of the electric room carried over and we are working as intended");
 
 
         }
avatar image
1

Answer by shadowpuppet · Apr 17, 2018 at 03:42 PM

the four sub rooms are on the same level as the elevator so you can simply have a subRoomManager script - maybe on the elevator so that every time a sub room has been visited you set a bool to true. Then in the script you have to use the elevator have a condition that all four bools must be true

on the subrooms when visited add the appropriate subroom to the script:

     void OnTriggerEnter(Collider other) {
             if(other.tag == "Player")
 {
    subRoomManager.room1.visited = true;
     }
     }



///Then on the subRoomManager script//

 public static bool room1;
 public static bool room2;
 public static bool room3;
 public static bool room4;

///And on the elevator script//

 if (subRoomManager.room1 == true && subRoomManager.room2 == true &&  subRoomManager.room3 == true && subRoomManager.room4 == true){
 //then the script that allow the elevator to be used here
 }
 }
 }






Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image harpoaian · Apr 17, 2018 at 03:52 PM 1
Share

sadly that method won't work because the sub rooms of level 12 are actually their own scenes(Did it for performance issues) So all in all there are 16 levels in my game but we want the player to just feel like level 12 is a huge level. So I am still trying to figure out how to get the GameData to carry over to the level 12 HUB room. In the picture below where you see the blue squiggles those represent the triggers that load each sub room of level 12 alt text

level12.png (33.3 kB)
avatar image shadowpuppet harpoaian · Apr 17, 2018 at 04:02 PM 1
Share

ah, I see. I guess that is why some of the answers had the "doNotDestroyOnload". So ins$$anonymous$$d of putting the subRoom$$anonymous$$anager on the elevator it would go on a gameobject ( empty probably) that you can introduce in level 11 and will carry over to 12-16 with the donotdestroyonload

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

79 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Rotating quads and check if 2 sides touch another quad 1 Answer

[UNET] How to configure a level gameObject? 0 Answers

LevelDesign + best solution 0 Answers

Can you apply foliage to an imported Blender asset(object)? 0 Answers

Creating code to end a level once all objects are collected 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges