我正在Unity3D中编写一个游戏,我想知道我是应该使用事件 - 还是其他一些构造 - 而不是代表我的网络请求。
在游戏生命周期的某些时刻,我们需要调用REST API并等待其响应。考虑一个UI屏幕,它可以检索朋友列表,并显示朋友的数量以及每个朋友的条目。目前,工作流看起来像这样,使用Action
个委托作为我Server
类的各种方法的参数:
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...
}
}
Server.GetFriends
方法向我们的REST API发出HTTP请求,获取响应,并调用委托,将响应和控制权返回给FriendsUI
。
这通常很好用。但是,如果我在调用委托之前关闭了朋友UI屏幕,那么friendCount
组件 - 以及该类中的任何其他组件 - 已被破坏,并且NPE会尝试访问它
知道这一点,你认为C#的事件系统是一个更好的设计吗? Server
会显示类似FriendsEvent
事件的内容,FriendsUI
会订阅它。在Server
验证/转换了响应时,它会引发事件。 FriendsUI
也会自行清理,并在销毁/禁用脚本附加的GameObject时取消注册处理程序。这样,在Server
中引发事件时,如果事件处理程序在FriendsUI
中不再有效,则不会被调用。
我只是试图在实现它之前在脑中运行它,因为它最终会成为一个有点大的重构。我正在寻找关于人们是否认为这是一条好路线的指导,如果还有其他路线可能会变得更好,以及我可能遇到的任何陷阱。
永远感谢您的时间。
答案 0 :(得分:2)
只需使用C#delegate
和event
即可。当从服务器收到朋友列表以订阅该事件时,使每个希望收到通知的脚本。
public class FRIENDSAPI : MonoBehaviour
{
public delegate void friendListReceived(List<FRINDSINFO> _friends);
public static event friendListReceived onFriendListReceived;
//Function that gets friends from the network and notify subscribed functions with results
public void getFriends()
{
StartCoroutine(getFriendsCoroutine());
}
private IEnumerator getFriendsCoroutine()
{
List<FRINDSINFO> friendsFromNetwork = new List<FRINDSINFO>();
/*
NETWORK CODE
//FILL friendsFromNetwork with Result
friendsFromNetwork.Add();
*/
//Make sure a function is subscribed then Notify every subscribed function
if (onFriendListReceived != null)
{
onFriendListReceived(friendsFromNetwork);
}
yield return null;
}
}
然后在FriendsUI
课程中,订阅Start()
功能并取消订阅OnDisable()
功能。您通常会使用OnEnable()
功能进行订阅,但有时它不起作用,因为事情并非按时初始化。在Start()
功能中执行此操作是修复。
public class FriendsUI: MonoBehaviour
{
void Start()
{
//Subscribe
FRIENDSAPI.onFriendListReceived += onFriendsReceived;
FRIENDSAPI friendAPI = gameObject.GetComponent<FRIENDSAPI>();
friendAPI.getFriends(); //Get friends
}
public void OnDisable()
{
//Un-Subscribe
FRIENDSAPI.onFriendListReceived -= onFriendsReceived;
}
//Call back function when friends are received
void onFriendsReceived(List<FRINDSINFO> _friends)
{
//Do Whatever you want with the result here(Display on the Screen)
}
}