【问题标题】:How to use async-await in Unity3d?如何在 Unity3d 中使用异步等待?
【发布时间】:2023-01-15 06:46:25
【问题描述】:

我想在我的 Unity3d 游戏中使用 Async-await 任务来进行 IO、网络和其他操作。我知道我可以使用 IEnumerators 和协程,但它们的功能非常有限,并且在使用 C# 中的 TcpClient、HttpClient 和其他异步任务处理 Web 服务 API 时无法正常工作。

在异步任务中我无法使用 UI 组件。假设我从 Web API 获取一个字符串,我无法从异步任务设置文本字段的文本。如何做呢。

【问题讨论】:

    标签: c# unity3d async-await task


    【解决方案1】:

    与大多数应用程序框架一样,Unity 游戏在主 UI 线程上运行。因此,从异步任务更改 UI 元素不起作用,因为我们只需要从主线程调用 Unity 的 API,例如从方法和 IEnumerators 调用。方法和 IEnumerators 在主 UI 线程上运行。

    Unity 也没有像 .Net 在 Xamarin.Forms (Device.BeginInvokeOnMainThread) 中那样提供调用主线程的方法。

    为此,我们需要使用 MVVM 架构。 MVVM 代表模型-视图-视图模型。我们不需要导入任何东西,只需改变我们项目的工作方式。

    默认情况下,Unity 使用单例方法,不提供任何应用程序构建 框架。因此,MVVM 更适合制作多功能游戏。使用 MVVM,我们可以通过拆分 UI 管理、我们的应用程序的逻辑和数据,通过拆分模型、视图和逻辑来标准化我们的代码。 MVVM 广泛用于跨平台应用程序开发。

    在 MVVM 中,我们将控件(UI 组件)绑定到 ViewModel 中的属性,我们只更改 ViewModel 中的属性。然后 ViewModel 将这些属性更改通知给 View,因此这些更改反映在我们场景中的 UI 组件中。

    创建一个 ViewModel 类

    public class MainSceneViewModel : INotifyPropertyChanged
    {
        public string Title { get { return title; } set { title = value; OnPropertyChanged(nameof(Title)); } }
        string title;
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    在你的场景脚本中(附加到 Unity Inspector 中的游戏对象)。

    public class MainSceneScript : MonoBehaviour
    {
        public Text SceneTitle; // Assign Text Component in Unity Inspector
    
        MainSceneViewModel mainSceneViewModel = new MainSceneViewModel();
    
        void Start()
        {
            mainSceneViewModel.PropertyChanged += ViewModelPropertyChanged;
            DelayedTitleChange();
        }
    
        async void DelayedTitleChange()
        {
            await Task.Delay(2000);
            mainSceneViewModel.Title = "This is the Main Scene";
        }
    
        // Will be called whenever a property of `MainSceneViewModel` is updated.
        void ViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(MainSceneViewModel.Title))
            {
                SceneTitle.text = mainSceneViewModel.Title;
            }
        }
    
        // Clean up
        void Dispose()
        {
            mainSceneViewModel.PropertyChanged -= ViewModelPropertyChanged;
        }
    }
    

    我们还可以使用模型并通知该模型的属性更改。

    【讨论】:

      猜你喜欢
      • 2020-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-22
      • 2016-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多