#finding objects in additively loaded scenes
1 messages · Page 1 of 1 (latest)
Main Manager, this is always loaded in the base scene
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class mainMenuManager : MonoBehaviour
{
//Variables
public Animator mainMenuAnimator;
public GameObject menuSceneStuff;
public Scene gameLevel;
public saveDetails saveDetails;
//details about scene that was loaded
public saveDetails playerDetails;
public LevelManager levelManager;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void MoveToLevelMap(){
Debug.Log("clicked play button, will now move to level map");
mainMenuAnimator.SetBool("slideIn", false);
mainMenuAnimator.SetBool("slideOut", true);
}
public void MoveToMainMenu(){
Debug.Log("clicked play button, will now move to main menu");
mainMenuAnimator.SetBool("slideIn", true);
mainMenuAnimator.SetBool("slideOut", false);
}
public void attemptToLoadLevel(string sceneName){
SceneManager.LoadScene(sceneName, LoadSceneMode.Additive); //load the scene
//DISABLE MAIN CAMERA, I WANT IT TO SWITCH TO THE CAMERA IN THE LOADED SCENE, AS THAT HAS PARALAX EFFECT, NEED TO ADD THIS IN
gameLevel = SceneManager.GetSceneByName(sceneName);//have to get the scene after it loads as LoadScene returns void, i.e nothing
Debug.Log(gameLevel + " | " + gameLevel.name);
playerDetails = GameObject.FindGameObjectWithTag("Player").GetComponent<saveDetails>();
Debug.Log("set var:" + playerDetails);
levelManager = GameObject.FindGameObjectWithTag("levelManager").GetComponent<LevelManager>();
Debug.Log("set var:" + levelManager);
levelManager.higher_ups = this;//i am de captain now
menuSceneStuff.SetActive(false); //disable the menu stuff, but keep them active as using these to store info and save data and etc
}
public void attemptToUnloadLevel(){
saveDetails = playerDetails; //grab player details (coin count, health, etc)
// UnloadSceneAsync(gameLevel); //pseudo, yeah
}
}
Level Manager, this is loaded in when the added scene is loaded
using System.Collections.Generic;
using UnityEngine;
public class LevelManager : MonoBehaviour
{
//Variables
public float sharedSpawnY = 0;
public GameObject goalPrefab;
public Vector2 goalSpawnpoint;
public GameObject goalInstance;
public GameObject playerPrefab;
public Vector2 playerSpawnpoint;
public GameObject playerInstance;
public mainMenuManager higher_ups; // the manager's manager!
// Start is called before the first frame update
void Start()
{
goalInstance = Instantiate(goalPrefab, new Vector3(goalSpawnpoint.x, goalSpawnpoint.y, sharedSpawnY), Quaternion.identity);
playerInstance = Instantiate(playerPrefab, new Vector3(playerSpawnpoint.x, playerSpawnpoint.y, sharedSpawnY), Quaternion.identity);
goalInstance.GetComponent<Goal>().manager = this;
}
// Update is called once per frame
void Update()
{
}
public void CompleteLevel(){
Debug.Log("level win!");
Destroy(goalInstance);
playerInstance.GetComponent<ParticleSystem>().Play();
playerInstance.GetComponent<playerMovement>().enabled = false;
playerInstance.GetComponent<CharacterController2D>().enabled = false;
playerInstance.GetComponent<Rigidbody2D>().drag = 1f;
if(higher_ups != null){ //if higher_ups has been set by higherups, really convoluted method but it's whatevs
}
}
}
why not grab the playerInstance from the LevelManager instead of using a Find method?
oh, I see you're trying to find it a bit later
i hadnt thought of that! Thanks! Only issue is, the main manager isn't actually finding the level manager as far as i can tell :/
or, i say only, you know what i mean hahaha
yeah, in general Find is a bad way of getting references to objects
it depends on strings, which makes it fragile (ie if you rename stuff it breaks)
and if there are multiple copies you can run into issues
and it is slow
SceneManager can return you a list of specific scene roots
so if you can get references a different way it is usually better
so if you do have a decent naming convention, you can drill down into the hiearchy that way and its not very inefficient
oh ok! so if i had the level manager on the very top of the level heirarchy, right at the root, would that then be able to find objects by the tag? i'm v used to using the tags haha i should really get better with other methods haha
imo a good design would be to use the SceneManager to get roots as Arugula says, but only use that to find one object in each scene -- the LevelManager presumably. Then use the LevelManager to get references to anything else you need in that scene
not via find methods, but just from the public fields that it has on itself
ohh ok, i think i see? so in the editor for each level, set the player and goal, as well as anything else, then just get the level manager at the start and then the player through that, rather than using the find?
https://docs.unity3d.com/ScriptReference/GameObject-scene.html you can also query any gameobject fo find out what scene its in
You can even make gameobjects transfer between scenes
thanks!! i'll give that a go now and get back to y'all! I really appreciate the help and talking me through the issue haha, thanks!!!