【问题标题】:Starting async Monobehaviour class from Button?从 Button 开始异步 Monobehaviour 类?
【发布时间】:2022-11-11 02:46:00
【问题描述】:

在 Unity 和 C# 方面,我完全是个菜鸟 现在我有一个任务,我觉得有点不知所措,所以任何输入都会非常感激......

我有一个看起来像这样的类:

//using directives

public class PipelineExample : MonoBehaviour
{
    private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
    private bool res = false;

    // Start is called before the first frame update
    void Start()

    {
        StartPipeline();
        while (!res) ;
    }

    async void StartPipeline()
    {
        // create models, pipeline, pipeline step
        IModel fbxModel = new FbxModel();
        Pipeline<IModel> pipeline = new Pipeline<IModel>();
        IAction<IModel> pipelineStep = new GenericPipelineStep<IModel>();

        // add steps to pipeline
        pipeline.AddPipeLineStep(pipelineStep);



        try
        {
            res = await pipeline.Execute(fbxModel, cancellationTokenSource.Token);
            Console.Write("Result of pipeline: " + res);
        }
        catch (OperationCanceledException)
        {
            Console.WriteLine("Canceled successfully!");
        }
    }


    // Update is called once per frame
    void Update()
    {
        
    }
}

现在,当我单击“开始”按钮时,我想以某种方式从另一个类调用此 startmethod(?):

private void OnStartButtonClicked(MouseUpEvent evt)
{
    //What goes in here?
}

我不能只是 Pipeline Example.Start 显然,

公共管道示例; something.Start 也不起作用。

所以基本上我的问题是,我怎样才能从另一个类开始这个 PipeLineExample 类?

【问题讨论】:

  • 将 Start 更改为任何其他名称。然后将方法公开并将其分配给按钮。你应该能够找到大量的教程
  • 你的意思是 void start 方法?我也可以公开 start 方法并调用它,但是当我这样做时,我得到 NullReferenceException: Object reference not set to an instance of an object

标签: c# unity3d


【解决方案1】:

如果您对 Pipeline Example 类进行一些修改,您应该能够调用您正在寻找的方法。

这是一个示例,有多种方法,您可以如何实现这一目标:

public class PipelineExample : MonoBehaviour
{
    private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

    public static PipelineExample instance { get; private set; }
    public static bool initialised { get; private set; }

    public IModel fbxModel { get; private set; }
    public Pipeline<IModel> pipeline { get; private set; }

    // Unity will create an instance of this class. We then use it as a 'singleton'.
    private void Awake ( )
    {
        if ( instance != null )
            return;

        instance = this;
    }

    public async Task<bool> StartPipeline ( )
    {
        if ( initialised )
            return true;

        // create models, pipeline, pipeline step
        fbxModel = new FbxModel();
        pipeline = new Pipeline<IModel>();
        IAction<IModel> pipelineStep = new GenericPipelineStep<IModel>();

        // add steps to pipeline
        pipeline.AddPipeLineStep ( pipelineStep );

        try
        {
            initialised = await pipeline.Execute ( fbxModel, cancellationTokenSource.Token );
            Console.Write ( "Result of pipeline: " + initialised );
        }
        catch ( OperationCanceledException )
        {
            Console.WriteLine ( "Canceled successfully!" );
        }

        return initialised;
    }

    // You might want to include a method to cancel the pipeline setup using cancellationTokenSource?
}

因为它是一个 MonoBehaviour,所以 Unity 将处理创建此类的一个实例。如果您不想将此类作为组件附加到场景内游戏对象,您也可以将其实现为 ScriptableObject(可能是我的首选选项)。但是您可能希望稍后在应用程序中使用场景特定的值来驱动此组件。

然后,您将像这样调用设置:

private async void OnStartButtonClicked ( MouseUpEvent evt )
{
    if ( !PipelineExample.initialised )
    {
        // The pipeline isn't yet initialised. Alert user for a potential setup time.
        if ( !await PipelineExample.instance.StartPipeline ( ) )
        {
            // Something went wrong ... alert user?
            return;
        }
    }

    // PipelineExample is initialised.
    // PipelineExample.instance.fbxModel and PipelineExample.instance.pipeline are now set up.
}

请注意,这将在单击按钮时设置您的管道。如果加载时间很长,您可能会受益于某种用户通知,让用户知道存在潜在的延迟。

【讨论】:

  • 不知道为什么,但是当我使用该代码点击按钮时,我确实得到了 NullReferenceException: Object reference not set to an instance of an object at the line of "!await PipelineExample.instance.StartPipeline()" :( 谢谢你的帮助然而远!
  • @valoon 您是否将该脚本/组件添加到场景中的游戏对象中?该错误是因为instance 为空,那是因为组件从未启动(唤醒)。
【解决方案2】:

所以我找到了一个简单的工作解决方案来解决我的问题。

我刚刚将 PipelineExample 中的方法设为静态 并在按钮中调用开始: PipelineExample.Start();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-13
    • 2012-07-19
    • 1970-01-01
    • 2023-02-05
    • 2021-10-19
    • 2017-01-05
    • 2019-05-14
    相关资源
    最近更新 更多