Objects in Scene Dark After Calling Loadscene/Loadlevel

Objects in Scene dark after calling LoadScene/LoadLevel

The colors and materials are loaded. This is a lighting problem because lighliting is still calculating in the background. This will likely occur in the Editor only. This should not happen in the build.

Depending on your Unity version, you can fix this by going to Windows --> Lighting --> Settings then go to the Scene tab. Scroll down and disable Auto Generate checkbox then click the Generate Lightning button.

Sample Image

For older version of Unity with no Auto Generate checkbox, see here.

Scene is darker when playing in editor

You have to disable the contious light baking.

In order to do so in Unity 2017.1, go to Window -> Lighting -> Settings and uncheck Auto Generate at the bottom of the window. Then, press Generate Lightning to bake the lighting once manually.

Note that if you add more lights or make some changes, you have to bake the lightmap again.

Using LoadLevel has effect on light

This is normal. It happens in the Editor only and also when Continuous Baking is enabled. This will not be present when you build your project.

To fix this in the Editor, Window -> Lighting -> Lightmap Tab -> Disable Continuous Baking then click on the Build button to bake the lighting.

If using Unity 5.4, the settings changed a little bit Window -> Lighting -> Lightmap Tab -> uncheck Auto checkbox. Click on the Build button to bake the lighting.

If you move, remove or add objects in the Editor, you must rebake/build lightmaps again.

EDIT:

This has been renamed to Auto-Generate. See duplicate for new answer. This answer will remain for older version of Unity.

Unity - Wait in MainMenu till Scene is completely loaded

Ok i got it.

The problem was the Auto-Light-Baking.

Just go to Window > Lighting > Settings > Scene

And then scroll to the bottom and uncheck the "Auto Generate" for "Generate Lighting"

LoadScene Additive makes new scene too bright

Loading an scene "additively" is not what I would use for this (you've already seen the problem, additive means the previous objects are not destroyed when loading the previous scene, but they are not modified in any way, not even hidden).

Instead, you can have several cameras, each with their own "Culling Mask". I'd then have an "Inventory Camera" that only shows the objects from the inventory, and nothing more. The "Main Camera" would have a culling mask that shows everything but the inventory objects.

For defining the culling mask you'll need to define layers. Here some docs: https://docs.unity3d.com/Manual/class-Camera.html

You can then disable the "Main Camera" and enable the "Inventory Camera" each time the user presses "I". This is done with Camera.main.

Hope this helps.

Scene loads differently when loaded from another scene than selecting that scene first, in the editor (Unity, c#)

Time.frameCount is counting frames from the start of the game. So if you load the scene from another scene Time.frameCount will be greater than 0 for sure.

Also it's faster to debug your game instead of using logs to see what's going on. Just hit Play in MonoDevelop and (for Unity 4.3 and below) choose Unity Debugger, place breakpoints where you need to stop and check variable values, then hit Play in Unity.

Good luck

How to pass data (and references) between scenes in Unity

Besides playerPrefs another dirty way is to preserve an object during level loading by calling DontDestroyOnLoad on it.

DontDestroyOnLoad (transform.gameObject);

Any script attached to the game object will survive and so will the variables in the script.
The DontDestroyOnLoad function is generally used to preserve an entire GameObject, including the components attached to it, and any child objects it has in the hierarchy.

You could create an empty GameObject, and place only the script containing the variables you want preserved on it.

Unity: How to switch scenes and when returning to the original scene, return player to the place they switched their scene

With Unity, the traditional loading of a scene was fairly destructive. There was the concept of setting a GameObject as safe by setting it as DontDestroyOnLoad, which, in a way, removed the object from the scene altogether, which protected it from scene loads.

Unity finally properly implemented multiscene editing and loading. It's essentially DDOL, but done properly.

Now you can actually have multiple scenes loaded at the same time. Now, what that allows you to do is to have a "Manager" scene that handles all of the objects that are common between scenes, and only load (and unload) the specific objects required for that individual scene.

You'd use it like this:

SceneManager.LoadScene("YourScene", LoadSceneMode.Additive);

That would load "YourScene" in ADDITION to the currently loaded scene. Likewise, removing a scene is:

SceneManager.UnloadScene("YourScene");

Now, if you have a Manager scene, you can include in your manager scene a script that holds data for each individual scene. As a hacky example, you might have:

public Vector3 InsideSceneLastPosition { get; set; }

Which you then assign to before loading your outside scene. When you load your inside scene again, you can read InsideSceneLastPosition again to reposition your character.

Here's the link to the LoadSceneAsync page at Unity.

There's more to it than that, for instance, you have to listen for the SceneManager.sceneLoaded event to know when you've actually loaded the next scene, so that you can reposition your GameObejcts. You can find information about that here.

You can see multiscene editing my simply dragging multiple scenes from the Project window into you Hierarchy window. All the scenes listed will additively work together. But you'll have to be careful though, as there's another "gotcha" in that you cant reference objects from one scene to another. You can call scripts cross scene, but you won't be able to drag a game object from one scene, into the object field of a component on a different scene. Don't worry, you'll get the hang on it =)

How to detect click/touch events on UI and GameObjects

You don't use the Input API for the new UI. You subscribe to UI events or implement interface depending on the event.

These are the proper ways to detect events on the new UI components:

1.Image, RawImage and Text Components:

Implement the needed interface and override its function. The example below implements the most used events.

using UnityEngine.EventSystems;

public class ClickDetector : MonoBehaviour, IPointerDownHandler, IPointerClickHandler,
IPointerUpHandler, IPointerExitHandler, IPointerEnterHandler,
IBeginDragHandler, IDragHandler, IEndDragHandler
{
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("Drag Begin");
}

public void OnDrag(PointerEventData eventData)
{
Debug.Log("Dragging");
}

public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("Drag Ended");
}

public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name);
}

public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("Mouse Down: " + eventData.pointerCurrentRaycast.gameObject.name);
}

public void OnPointerEnter(PointerEventData eventData)
{
Debug.Log("Mouse Enter");
}

public void OnPointerExit(PointerEventData eventData)
{
Debug.Log("Mouse Exit");
}

public void OnPointerUp(PointerEventData eventData)
{
Debug.Log("Mouse Up");
}
}

2.Button Component:

You use events to register to Button clicks:

public class ButtonClickDetector : MonoBehaviour
{
public Button button1;
public Button button2;
public Button button3;

void OnEnable()
{
//Register Button Events
button1.onClick.AddListener(() => buttonCallBack(button1));
button2.onClick.AddListener(() => buttonCallBack(button2));
button3.onClick.AddListener(() => buttonCallBack(button3));

}

private void buttonCallBack(Button buttonPressed)
{
if (buttonPressed == button1)
{
//Your code for button 1
Debug.Log("Clicked: " + button1.name);
}

if (buttonPressed == button2)
{
//Your code for button 2
Debug.Log("Clicked: " + button2.name);
}

if (buttonPressed == button3)
{
//Your code for button 3
Debug.Log("Clicked: " + button3.name);
}
}

void OnDisable()
{
//Un-Register Button Events
button1.onClick.RemoveAllListeners();
button2.onClick.RemoveAllListeners();
button3.onClick.RemoveAllListeners();
}
}

If you are detecting something other than Button Click on the Button then use method 1. For example, Button down and not Button Click, use IPointerDownHandler and its OnPointerDown function from method 1.

3.InputField Component:

You use events to register to register for InputField submit:

public InputField inputField;

void OnEnable()
{
//Register InputField Events
inputField.onEndEdit.AddListener(delegate { inputEndEdit(); });
inputField.onValueChanged.AddListener(delegate { inputValueChanged(); });
}

//Called when Input is submitted
private void inputEndEdit()
{
Debug.Log("Input Submitted");
}

//Called when Input changes
private void inputValueChanged()
{
Debug.Log("Input Changed");
}

void OnDisable()
{
//Un-Register InputField Events
inputField.onEndEdit.RemoveAllListeners();
inputField.onValueChanged.RemoveAllListeners();
}

4.Slider Component:

To detect when slider value changes during drag:

public Slider slider;

void OnEnable()
{
//Subscribe to the Slider Click event
slider.onValueChanged.AddListener(delegate { sliderCallBack(slider.value); });
}

//Will be called when Slider changes
void sliderCallBack(float value)
{
Debug.Log("Slider Changed: " + value);
}

void OnDisable()
{
//Un-Subscribe To Slider Event
slider.onValueChanged.RemoveListener(delegate { sliderCallBack(slider.value); });
}

For other events, use Method 1.

5.Dropdown Component

public Dropdown dropdown;
void OnEnable()
{
//Register to onValueChanged Events

//Callback with parameter
dropdown.onValueChanged.AddListener(delegate { callBack(); });

//Callback without parameter
dropdown.onValueChanged.AddListener(callBackWithParameter);
}

void OnDisable()
{
//Un-Register from onValueChanged Events
dropdown.onValueChanged.RemoveAllListeners();
}

void callBack()
{

}

void callBackWithParameter(int value)
{

}

NON-UI OBJECTS:

6.For 3D Object (Mesh Renderer/any 3D Collider)

Add PhysicsRaycaster to the Camera then use any of the events from Method 1.

The code below will automatically add PhysicsRaycaster to the main Camera.

public class MeshDetector : MonoBehaviour, IPointerDownHandler
{
void Start()
{
addPhysicsRaycaster();
}

void addPhysicsRaycaster()
{
PhysicsRaycaster physicsRaycaster = GameObject.FindObjectOfType<PhysicsRaycaster>();
if (physicsRaycaster == null)
{
Camera.main.gameObject.AddComponent<PhysicsRaycaster>();
}
}

public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name);
}

//Implement Other Events from Method 1
}

7.For 2D Object (Sprite Renderer/any 2D Collider)

Add Physics2DRaycaster to the Camera then use any of the events from Method 1.

The code below will automatically add Physics2DRaycaster to the main Camera.

public class SpriteDetector : MonoBehaviour, IPointerDownHandler
{
void Start()
{
addPhysics2DRaycaster();
}

void addPhysics2DRaycaster()
{
Physics2DRaycaster physicsRaycaster = GameObject.FindObjectOfType<Physics2DRaycaster>();
if (physicsRaycaster == null)
{
Camera.main.gameObject.AddComponent<Physics2DRaycaster>();
}
}

public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name);
}

//Implement Other Events from Method 1
}

Troubleshooting the EventSystem:

No clicks detected on UI, 2D Objects (Sprite Renderer/any 2D Collider) and 3D Objects (Mesh Renderer/any 3D Collider):

A.Check that you have EventSystem. Without EventSystem it can't detect clicks at-all. If you don't have have it, create it yourself.


Go to GameObject ---> UI ---> Event System. This will create an EventSystem if it doesn't exist yet. If it already exist, Unity will just ignore it.


B.The UI component or GameObject with the UI component must be under a Canvas. It means that a Canvas must be the parent of the UI component. Without this, EventSystem will not function and clicks will not be detected.

This only applies to UI Objects. It doesn't apply to 2D (Sprite Renderer/any 2D Collider) or 3D Objects (Mesh Renderer/any 3D Collider).


C.If this is a 3D Object, PhysicsRaycaster is not attached to the camera. Make sure that PhysicsRaycaster is attached to the camera. See #6 above for more information.


D.If this is a 2D Object, Physics2DRaycaster is not attached to the camera. Make sure that Physics2DRaycaster is attached to the camera. See #7 above for more information.


E.If this is a UI object you want to detect clicks on with the interface functions such as OnBeginDrag, OnPointerClick, OnPointerEnter and other functions mentioned in #1 then the script with the detection code must be attached to that UI Object you want to detect click on.


F.Also, if this is a UI Object you want to detect clicks on, make sure that no other UI Object is in front of it. If there is another UI in front of the one you want to detect click on, it will be blocking that click.

To verify that this is not the issue, disable every object under the Canvas except the one you want to detect click on then see if clicking it works.



Related Topics



Leave a reply



Submit