I'm writing a game in Unity3D, and I'm wondering if I should be using events -- or some other construct entirely -- instead of delegates for my web requests.
At certain points in the game's lifecycle, we need to call out to a REST API and await its response. Consider a UI screen that retrieves a list of your friends, and displays the number of friends, along with an entry for each friend. Currently, the workflow looks something like this, using Action
delegates as parameters to the various methods of my Server
class:
class FriendsUI : MonoBehaviour
{
[SerializeField]
private Text friendCount; // A Unity Text component
private void OnStart()
{
Server.GetFriends(player, response => {
ShowFriendList(response.friends);
});
}
private void ShowFriendList(List<Friend> friends)
{
this.friendCount.text = friends.Count.ToString();
// Display friend entries...
}
}
The Server.GetFriends
method does an HTTP request to our REST API, gets the response, and calls the delegate, returning the response and control to FriendsUI
.
This usually works just fine. However, if I closed the friends UI screen before the delegate is called, the friendCount
component -- and any other component in the class, for that matter -- has been destroyed, and an NPE is thrown trying to access it.
Knowing that, do you think C#'s event system be a better design for this? Server
would expose something like a FriendsEvent
event, and FriendsUI
would subscribe to it. At the point when Server
has validated/transformed the response, it would raise the event. FriendsUI
would also clean up after itself and unregister the handler when the GameObject on which the script has been attached is destroyed/disabled. That way, at the point the event is raised in Server
, if the event handler is no longer valid in FriendsUI
, it just wouldn't get called.
I'm just trying to run this through in my head before implementing it, because it would end up becoming a somewhat large refactor. I'm looking for guidance as to whether or not people think it's a good route to go, if there are any other routes that might turn out better, and any pitfalls I might run into along the way.
Thanks, as ever, for your time.