SceneManager LoadScene not working in editor playmode - unity3d

as the title says I have an issue loading a scene when in playmode in the editor.
The workflow of my game is as follows:
Initializing (works fine)
There is an empty scene that creates some global game objects that will exist during the entire runtime.
MainMenu (works fine)
After the Initializing is done it loads the MainMenu scene. I can interact with the scene and everything is nice.
Connect to game server (works fine)
In the main menu I have an option to connect to a game server (a dedicated server application I created on my own)
Establishing the connection and sending the login works well.
Character selection (not working)
After the login on the server I get the resonse to select a character. (This works as expected.)
Then I'm going to handle this response by opening the character selection scene.
And here I have the issue. In Playmode inside the editor the handler method is executed (verifyed by debug logs) but the scene is not loaded actualy.
When I build the game and run the created .exe and follow the exact same steps the character selection scene is loaded and shown as expected.
I searched the documentation and also the web but did not find any similar issues (maybe I still missed something)
So my question is as follows:
How do I get the scene to also load in the editor playmode? My approach seems not to be totaly wrong as it works after build.
Here is the code snippet that should load the scene:
private void MessageRecived(object sender, GNL.ResponseMessageEventArgs e)
{
GameEventMessage message = this.eventManager.MessageHandler.ParseMessage(e.Message);
Debug.Log($"Recived message with type {message.Type}");
switch (message.Type)
{
case GameEvent.CharacterSelectionRequired:
Debug.Log($"Handle character creation 01");
this.HandleCharacterSelectionRequried(message);
break;
default:
break;
}
}
private void HandleCharacterSelectionRequried(GameEventMessage eventMessage)
{
Debug.Log($"Handle character creation 02");
SceneManager.LoadScene("CharacterCreation");
}
All three Debug.Log statements are executed. Only the LoadScene isn't working in the editor playmode.
IMPORTANT ADDITION
After further testing I have to mention that the network communication is done in a seperate thread. From this thread when a new message arrives an eventHandler is called.
This is where the Method is added to the Event handler:
this.client = new GNL.GameClient(System.Net.IPAddress.Parse(host), port);
this.client.AnnounceRecivedMessage += this.MessageRecived;
this.clientNetwork = new Thread(this.client.Start);
clientNetwork.Start();
And this is the definition of the eventHandler:
public event EventHandler<ResponseMessageEventArgs> AnnounceRecivedMessage;
IMPORTANT ADDITION - Part 2
I just discovered that, it works on a normal build but not when selecting "development build" in the build settings.
This is really annoying as I have to build the game every time I made a change to test it.
I'm thankful for any help and suggestions.

After much more debugging and testing I figured out that this issue indeed is a threading issue.
Deep in the debugger I found the exception I would have expected for a threading issue. So I will have to change my implementation here.
But still there is an inconsistence in how threads are handled in Unity when running the game with debugging tools enabled (playmode in editor and development build) and with them disabled (normal build).

AFAIK, you can't switch between scenes in the editor. Unity Editor only works to edit and play the opened scene.
If you want to test some parts of the workflow, create functions dedicated to the editor (you can use #if UNITY_EDITOR) to test your scenes without the previous character selection.

Related

How do you automatically focus on an inputfield when opening/activating the UI in Unity3d?

I am making a game where you must open or activate the UI with the space bar. Now, this works perfectly fine, but it is pretty annoying that every time you open the UI you must click on the inputfield to write in it. Is there any way around this? So is there a way to open or activate the UI without having to click on the field to be able to write in it?
I looked for YouTube videos and tried to find similar problems in other forums, but wasn't able to find a script, nor was I able to find some Unity settings to do so.
You could use e.g.
private class SelectOnEnable : MonoBehaviour
{
private void OnEnable()
{
EventSystem.current.SetSelectedGameObject(null);
EventSystem.current.SetSelectedGameObject(gameObject);
}
}
and attach it to whatever object that should become the selected one everytime it is enabled. See EventSystem.SetSelectedGameObject
Can't test it right now but it might still require the User to hit Enter in order to also actually set the Input field into edit mode. The upper line only sets it as selected UI element (similar to using TAB in a browser).
Otherwise I think you would go through
yourInputField.DeactivateInputField()
yourInputField.ActivateInputField();
to directly set it active. See InputField.ActivateInputField. Might have to do both in combination - again can't test right now ;)
Thank you very much, derHugo! Everything works like a charm now! You saved me a lot of time. Referring to your last comment, I used both of them, and it seems to work very well for me. Here is the code I used:
`private void OnEnable()
{
EventSystem.current.SetSelectedGameObject(gameObject);
GameManager.GetComponent().inputFieldInMainUi.ActivateInputField();
EventSystem.current.SetSelectedGameObject(null);
GameManager.GetComponent<InputFieldComparision>().inputFieldInMainUi.DeactivateInputField();
}`

After updating Unity, a second EventSystem is created on Run

I just updated from Unity 2019.3.13f1 to 2021.3.6f1 mid project. Not ideal I know, but I was advised to by Unity Support in order to add the IAP package. After the update, on running my launch scene, I get this error:
There are 2 event systems in the scene. Please ensure there is always exactly one event system in the scene
It turns out, a second EventSystem object is being created on running, which hadn't been the case before the update. At first, I just disabled the one in the hierarchy, which solved the problem as the second EventSystem then didn't conflict. However, when the game goes to a second scene and then returns to the initial scene, the duplicate EventSystem is not created, meaning that the menus don't get any input!
Can anyone advise?
This forum post (https://forum.unity.com/threads/upgrade-to-2020-lts-creating-duplicate-eventsystem.1098133/) detailed the same problem.
I have tracked this down to calling Advertisement.Initialize. If I
call that while running in the Editor; then it creates a new
EventSystem. I am not sure why. It doesn't seem to matter if I pass
true or false for the testMode value.
The poster there solved it by surrounding the Initialising line with #if !UNITY_EDITOR. However I wanted to be able to see the adverts testing in the editor - so I added this code, after Advertisement.Initialize(_gameId, _testMode, this):
var es = FindObjectsOfType<EventSystem>();
if (es.Length > 1)
{
for (int i = 1; i < es.Length; i++)
{
Destroy(es[i].gameObject);
}
}
This seems to have fixed the problem.

why are plugin connected signal not working after saving?

I've created a plugin and it works fine when I open the project but as soon as I press ctrl + s to save the scene for the first time since opening, the buttons on the plugin (Close_btn in this case) stop working
tool
extends EditorPlugin
var Key_Btn=null;
var UI=load("res://addons/Plugin_Name/UI.tscn").instance();
func show_UI():
get_editor_interface().add_child(UI)
func close_UI():
if(get_editor_interface().has_node(UI.name)):
get_editor_interface().remove_child(UI);
func _enter_tree():
Key_Btn=Button.new();
Key_Btn.text=" Key ";
Key_Btn.flat=true;
add_control_to_container(CONTAINER_CANVAS_EDITOR_MENU,Key_Btn)
Key_Btn.connect("pressed",self,"show_UI")
func _exit_tree():
close_UI();
remove_control_from_container(CONTAINER_CANVAS_EDITOR_MENU,Key_Btn)
This is what the plugin button looks like:
The UI that pops up when you press the button:
How do I solve this?
I tried your code. I did modify the UI as I describe below. However, with your code, at no point the UI or the button to open it stopped working.
This is what I tried (closing and opening the project between tests):
Saving, then opening the UI. Then closing the UI and opening it again.
Opening the UI, then closing it, then saving, then opening it again.
Opening the UI, saving with the UI open, closing it, then opening it again.
I tested on Godot 3.3, 3.4,, 3.4.3 and 3.5 beta 1.
Since you have a Button called Transparent Background. I had it set to Full Rect, and set the alpha of its self_modulate to make it transparent. Consequently it won't let me interact with anything in the editor…
To be able to close the UI, I had to add a script to Control Main that looks like this:
tool
extends Control
func close():
if is_inside_tree():
get_parent().remove_child(self)
Don't forget to make a tool script.
And I connected the press signal from the Transparent Background and Close_btn to the close method I added.
An alternative would have been to emit a signal from the UI and on the EditorPlugin have it connected to close_UI… I didn't do that because I didn't want to change your code. And since it all worked with that code, I can say that issue for you is not that code.
Also be aware that you load an instance the UI scene on the initialization of your EditorPlugin. In consequence…
Some modifications to that scene won't be reflected on the EditorPlugin until you disable and enable it again, or load the project again.
And I say "some modifications", because you will see reflected the modifications to the resources it had when loaded. For example, I can modify the script I attached, or re-import texture, and so on. However, if I replace the resource with a new one, I will see the old resource on the already loaded UI.
With that in mind, I tried modifying the script I attached to introduce an error and saved… And the UI still appears. Except, since the script I attached was not working, I could not close the UI, so I had to close Godot altogether.
In fact, the only way I have been able to make the button stop working after saving was by introducing an error in the EditorPlugin code and saving. I can only assume this is what happened to you.

Escape input key with unity3d WEB GL build

I creating WEB GL game. Game menu is shown by the following code:
Input.GetKeyUp(KeyCode.Escape)
It works fine in unity and in the windows build. In the browser, escape pressing is intercepted by browser and the menu is not displayed.
Is it possible to make this code working in WEB GL build? What is the standart "meny button" for WEB GL games?
It should be working because
From Unity Manual webgl input : By default, Unity WebGL will process all keyboard input send to the page, regardless of whether the WebGL canvas has focus or not.
It could be that you disabled WebGLInput.captureAllKeyboardInput (Which is enabled by default) In that case just enable that and it should work.
The Escape Button is used by default for exiting fullscreen mode, maybe that's causing the issue. I would suggest to use the Input Manager ( https://docs.unity3d.com/Manual/class-InputManager.html ) and define a button using Escape as the positive button.
As #pasotee mentioned, the Escape key could be consumed already. By the Browser, as well as by the Unity Player, as for example the F1 key is used by Chrome to open the Help Tab. Escape is definitely used by the Unity Player to exit its Fullscreen mode.
So the short answer is. No, you can't.
Unity is listening to all key by default, true, but never gets the events when the upper lying application, like the browser, doesn't send it to the Canvas or the executing environment - aka the Unity3d Player doesn't send it down to your code. Or in this case, they should really fix the manual to "[..] all buttons, except Escape and browser related Hotkeys":
https://docs.unity3d.com/Manual/webgl-input.html
The long answer is, you might intercept the 'Escape' key event within JavaScript and pass a function call into the Unity Player like mentioned here:
jQuery
$(document).on('keyup',function(evt) {
if (evt.keyCode == 27) {
alert('Esc key pressed.');
}
});
https://jsfiddle.net/MQHVa/1/
Vanilla JS
var msg = document.getElementById('state-msg');
document.body.addEventListener('keypress', function(e) {
if(e.key == "Escape"){
msg.textContent += 'Escape pressed:'
}
});
https://jsfiddle.net/etcjwaf5/
And in the end you'll need this information, to call Unity from Javascript:
SendMessage('MyGameObject', 'MyFunction');
SendMessage('MyGameObject', 'MyFunction', 5);
SendMessage('MyGameObject', 'MyFunction', 'MyString');
https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html
And the very last thing is to have a GameObject in your loaded Scene that provides the function for doing, whatever you desired to be done.
Bare in mind, that if you don't cancel distribution of the Escape key event it will be send to the UnityPlayer which triggers it to exit fullscreen mode! And you might not be able to prevent Unity from consuming this event anyway, so remember WebGLInput.captureAllKeyboardInput member.

AirConsole Unity plugin - WebGL build does not work while Unity debugger works

We've created a small demo of Unity3D with AirConsole-plugin which is working in Unity debugger. (If I press play, the browser opens, sometimes it works, sometimes it doesn't. If it doesn't, one can restart Unity and then it works.)
If we create a release or a developer build, it does no longer work. It will load the image correctly, but the controllers (virtual+phone) stay 'loading' most of the time. Sometimes they reach the first correct HTML page, but then the message they send doesn't seem to arrive on the screen-side.
When I click the 'Open Exported Port' after the build, it doesn't work too, except for once.
One error message I got once:
"Uncaught TypeError: Cannot read property 'postQueue' of undefined"
This error message appears always:
"pre-main prep time: 176 ms UnityLoader.js:1
Module.printErr # UnityLoader.js:1"
Do you know what these error messages mean?
I've tried a lot, but this seems to solve the problem: Be sure to attach the event listeners in the Awake method, as they do in basic example application.
public class AirConsoleService : MonoBehaviour
{
void Awake()
{
// register events
AirConsole.instance.onReady += OnReady;
AirConsole.instance.onMessage += OnMessage;
AirConsole.instance.onConnect += OnConnect;
AirConsole.instance.onDisconnect += OnDisconnect;
// etc. ...
}
// etc. ...
}
My problem was that my AirConsoleService was static and not a MonoBehaviour to be sure that there is only one instance of AirConsoleService. It works perfectly for the debug 'play' mode, but in the release build, the AirConsole somehow does not know the deviceID which sent the message (this means, we get -1 from method ConvertDeviceIdToPlayerNumber. And this explains why the controllers don't get any signal from the screen.
My solution: I've attached it as a component to the AirConsole object.
Further notes:
Anti-Virus may block content.
Your PC/server has to be fast.
During development, log the deviceID and the playerID and the current active deviceIDs.
Often restart Unity or the integrated webserver of the plugin