Game Development Asked by Zechy on November 2, 2021
I am trying to build in unity a basic logon screen. Now I’m building on something if the connection will have delay or so… There will be a dialog, where the progress of connection to server will be written… Like Attempt 1/3, Attempt 2/3…
I have Dialog class, which is building a Dialog window from prefab:
public class Dialog
{
private const string TitleComponent = "Title";
private const string ContentComponent = "Content";
private readonly IPrefabFactory _dialogFactory = new DialogFactory(false);
private readonly GameObject _dialog;
public event ClickHandler Click;
public string Title
{
set => GetTextComponent(TitleComponent).text = value;
}
public string Content
{
set => GetTextComponent(ContentComponent).text = value;
}
public Vector3 Position
{
set
{
_dialog.transform.position = value;
_dialog.transform.localPosition = value;
}
get => _dialog.transform.position;
}
public bool Active
{
set => _dialog.SetActive(value);
get => _dialog.activeSelf;
}
public Dialog(string name)
{
_dialog = _dialogFactory.Create();
_dialog.name = name;
_dialog.GetComponent<DialogBehaviour>().Dialog = this;
SetToCanvas();
}
public void OnClick()
{
Click?.Invoke();
}
private void SetToCanvas()
{
var uiCanvas = Object.FindObjectOfType<Canvas>();
_dialog.transform.SetParent(uiCanvas.transform, false);
Position = new Vector3(0, 0, 0);
}
private TextMeshProUGUI GetTextComponent(string name)
{
foreach (Transform child in _dialog.transform)
{
if (child.name == name)
{
return child.gameObject.GetComponent<TextMeshProUGUI>();
}
}
throw new Exception($"Component with name `{name}` was not found.");
}
}
And I have some server "Manager", where the connection process is running.
private void Connect()
{
Dialog.Active = true;
var attempts = 1;
do
{
Dialog.Content = $"Connecting to server... ({attempts++}/{MaxAttempts})";
try
{
if (Client.CurrentState == ComponentState.Ready)
{
Client.Connect();
}
else
{
Client.Reconnect();
}
}
catch (ConnectionException)
{
attempts++;
}
} while (!Client.IsConnected && attempts <= MaxAttempts);
if (!Client.IsConnected)
{
Dialog.Content = "Connection with server could not be established.";
throw new ConnectionException("");
}
Dialog.Active = false;
}
private void CheckConnection()
{
if (Client.CurrentState == ComponentState.Ready)
{
Connect();
}
else
{
if (Client.CheckConnection()) return;
Connect();
}
}
protected Message SendAndReceive(Message message)
{
CheckConnection();
Message response = null;
try
{
response = Client.Send(message);
}
catch (MessageSendException)
{
Dialog.Active = true;
var attempts = 2;
do
{
Dialog.Content = $"Sending message... ({attempts}/{MaxAttempts})";
try
{
response = Client.TryReceive();
}
catch (MessageSendException)
{
attempts++;
}
} while (response == null && attempts <= MaxAttempts);
}
if (response == null)
{
Dialog.Content = "Server did not send any response. Probably connection is lost.";
throw new MessageSendException("");
}
Dialog.Active = false;
return response;
}
I want to provide some output to screen about whats hapening in that dialog class. But, where is the problem. Everything is so much fast, that the dialog can’t even render on the start and during all attempts to connect to server, the main thread is just stucked to the time, when the connection ends.
I was finding something about how to make this happen like in another thread or so… Or find coroutines, but I have no idea how to make this work…
It should work like this:
After all this happen, something similar should happen with the sending. How to make this working without stucking the main thread and make all steps run smoothly one after another?
You didn't post any of the code which actually sends the login attempt to the server, as all of that is abstracted away in an object "Client". And there are quite a lot of ways to do networking in Unity. But most network APIs don't block the current thread until there is an answer. They usually send a message and then return immediately. The actual response is then processed by a handler function when it finally arrives.
You are already using that pattern for the click events for your button. Your networking API likely uses a similar pattern for asynchronous operations.
So the usual pattern you would use is:
Update()
of the Dialog, it notices that there is a notification from the network API and changes the UI accordinglyAnswered by Philipp on November 2, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP