Find object from another scene - unity3d

I need to find an object from another scene. I have checked both Find and FindWithTag, but both of them give me this error:
NullReferenceException: Object reference not set to an instance of an object.

As i know - there is no way to find object on other scene.
First idea - you can load it as additive scene using SceneManager.LoadScene("OtherSceneName", LoadSceneMode.Additive);
and then use Find
You may find more info here: https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.LoadScene.html

You can write a Game Manager, which can make a script/object that will persist between different scenes, allowing you to carry variables between them. You could use it to have the button change a variable, then have the other scene check the variable when it loads to change the sprite.
A Unity tutorial is here:
https://unity3d.com/learn/tutorials/projects/2d-roguelike-tutorial/writing-game-manager

In your specific case, I'd use PlayerPrefs.Save/SetString to save the variables when player interacts with your UIs or Game Objects in Scene A.
Then when you loading your Scene B, write a scene manager script and on its Awake(), use PlayerPrefs.GetString to retrieve variables, and change your game object behaviors based on the loaded variables.

Related

Can you attach a sprite renderer to a child of a main game object and still have the animator access functions from the main object for events?

When creating a player or enemy in unity, I've learnt that it's best practise to attach the sprite renderer to a child game object so that you can easily reposition the sprite. However, doing this means that the animator also needs to be attached to the child game object, which means you don't have any access to the functions from the parent game object for animation events . Does anyone know a way around this?
I tried putting the animator on the parent object, but then it said the sprite renderer component was missing so I believe they need to be on the same object.
I tried putting the animator on the parent object, but then it said the sprite renderer component was missing so I believe they need to be on the same object.
No! What happened is you moved the animator root so the original property paths stored in your animation clip is invalid now.
The property paths are basically stored via the objects names.
What previously was e.g. (don't know the exact form of the property paths)
/Sprite/SomeProperty
would now need to be something like
YourSpriteObject/Sprite/SomeProperty
but since the animation still uses the first one and there is no Sprite component on your parent object it is invalid and displays as missing.
You will have to redo your animations or write an editor script for automatically changing all animation paths accordingly.
Here I once did something similar for renaming animated objects. You could probably write a similar thing for moving the animator component to a different object in the hierarchy
Alternatively expose the methods on your child object, and then forward them to trigger stuff on the parent via
transform.parent.GetComponent<YourParentClass>().YourMethod();
which of course I would either cache once or assign via the Inspector

How can I access an object's components from a different scene?

I have a Player gameObject that has a script on it which keeps some variables inside it. I created a scene which acts as a main menu and has "Shop" part in it, which has upgrades in it, basically I need to access Player gameObject's script from a different scene so I can modify variables from main menu scene. How can I do that ?
check this out:
https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html
once your player is loaded this will keep him in every scene until you choose to release hiim, meaning when you load your menu scene he will be there to access.
now since we know hes there, we can:
(note that player is your script with the variables not your actual player)
ScriptName player = GameObject.FindObjectWithTag("yourtag").GetComponent<ScriptName>();
Be default the components are instances of a class. If there isn't a GameObject with that component in the currently loaded scenes, there is nothing to access.
If I recall you can now load more than one scene at a time.
If there is a GameObject with that script currently loaded you can use:
https://docs.unity3d.com/ScriptReference/Object.FindObjectsOfType.html
or even better
use singleton design pattern, in case you have only 1 player at a time.
I guess you want to save these upgrades for the next run of the game, so you can use PlayerPrefs
https://docs.unity3d.com/ScriptReference/PlayerPrefs.html
If you want to save more than 50 values of data I would suggest using a file based DB like SQLite, it takes little time to setup and works very fast. And it is a lot more readable than using PlayerPrefs.
How about static class?
You can keep values there and access it from any place you want :D

How would I load a Canvas from another scene in Unity?

What I'm trying to do inside this script in Unity is to load a different scene, and find the canvas from that scene and enable it. I already know how to enable the canvas from the same scene but the issue is how can i find and enabled a canvas from another scene.
I tried SceneManager.LoadScene(scenename); to change scene so what should I add or modify? Can someone help me?
Save the canvas you want to switch to as a 'prefab' in your assets folder.
If you are loading a new scene without carrying over data from the last scene then just set up the canvas in that scene using the editor.
If you are carrying data over, or perhaps a player gameobject, then you can instantiate the canvas prefab you need. This would create it in the new scene and you can have a reference to it from wherever you chose to instatiate the prefab.
Alternatively you can have multiple canvases on the same gameobject and switch them on or off as you need them. Very useful for menus.
Hope that helps.
There're many solutions:
Using MonoBehavior's DontDestroyOnLoad(transform.gameObject) for your canvas you need to be on the next scene; You can find a lot examples in Google. Here's the link : https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html
Saving somewhere your current scene's gameobjects(canvas) and loading it again and recreate on the next scene as serialization etc;
Same as #2, but save required data in local variables.
There are two ways I understand your question.
You either want to copy a game object with all it's parameters as defined in the editor into another scene.
The best way to do that is obviously to use prefabs. (where to start?)
If you want to copy a game object and all its parameters after they have been modified at runtime, then you could use DontDestroyOnLoad() but that would mean the source scene has to be loaded at least once before the destination scene.

Having multiple unity scenes open simultaneously

I've been developing a board-style game in Unity3D. The main scene is the board, and has the data about each player and the current (randomly-generated) board stored within it.
I intend to add minigames into the game, for example when landing on a particular space on the board. Naturally, I would like to code the minigame in a separate scene. Is there a way I can do this without losing the instance of the current scene, so that the current scene's state is maintained?
Thanks in advance :)
Short answer: no, but there may be another way to do what you want.
A basic call to Application.LoadLevel call will destroy the current scene before loading the next one. This isn't what you want.
If your minigame is relatively simple, you could use Instantiate to bring in a prefab and spawn it far away from the rest of your scene. You can even use scripts to switch to another camera, toggle player controls and other interactions in the scene, and so on. Once the minigame is done, you can destroy or disable whatever you brought in, and re-enable whatever needs to be turned on in the main scene.
You could create a separate scene and call Application.LoadLevelAdditive to load that scene without destroying the current one. As above, you can then use scripts to manage which cameras and scene behaviors are active.
If you're careful, you don't really need two separate scenes. It may be enough to "fake" a scene switch.
Hard to give a complete answer without code, but you should look into the following things either with the unity documentation or youtube:
PlayerPrefs, this is one way of saving data, although i believe it isn't entirely secure i.e. being able to edit from a text file.
Serializable, this is apparently better than playerprefs.
DonDestroyOnLoad, can carry over information to multiple scenes.
Static variables, again not sure if this will help your particular problem.

Instantiate a prefab with a custom base object

Probably know the answer to this already but wanted to run this by the community anyways.
I have a custom object which contains the information I need to feed into a prefab.
I have read somewhere that messing around with contructors on prefabs is a bad idea. Is the best option then to simply pass the intitiatlization info via a method call on the prefab?
Ie: make a script for the prefab that accepts my custom object to configure it? Kind of a best practices question.
That's how I would do it. Basically the prefab needs a reference (not necessarily a separate script) to another prefab with the extra data needed.
Though the question is: why can't this data be in the prefab itself?
If the answer is "because the data is global and there are many prefabs" a good solution to that problem is ScriptableObject, which acts as a global data storage object. A scriptable object has a script and an inspector view like other game objects, and you can assign a reference to the scriptable object to prefabs which can then reference the global data.
Typically ScriptableObject are used for "raw data" or even as a lightweight game database.
Script that creates a ScriptableObject (there are many examples):
http://wiki.unity3d.com/index.php/CreateScriptableObjectAsset
This post explains the SO with a use case and code samples:
http://buchhofer.com/2010/10/unity-toying-with-scriptable-objects/