private async void UpdateMeshAndTextureAsync()
    {
        asyncUpdateCancellationTokenSource = new CancellationTokenSource();

        try
        {
            var lathe = new LatheMeshBuilder(numSplines);

            Task             meshTask    = Task.Run(() => BuildMushroomModel(lathe), asyncUpdateCancellationTokenSource.Token);
            Task <Texture2D> textureTask = textureGenerator.GenerateTextureAsync(asyncUpdateCancellationTokenSource.Token);

            await Task.WhenAll(meshTask, textureTask);

            asyncUpdateCancellationTokenSource.Token.ThrowIfCancellationRequested();

            Mesh mesh = lathe.CreateMesh();
            meshFilter.sharedMesh   = mesh;
            meshCollider.sharedMesh = mesh;

            renderer.material.mainTexture = await textureTask;
        }
        catch (OperationCanceledException ex)
        {
            //Debug.Log(ex);
        }

        asyncUpdateCancellationTokenSource = null;
    }
    private void UpdateMeshAndTexture()
    {
        var lathe = new LatheMeshBuilder(numSplines);

        BuildMushroomModel(lathe);
        Mesh mesh = lathe.CreateMesh();

        meshFilter.sharedMesh   = mesh;
        meshCollider.sharedMesh = mesh;

        renderer.material.mainTexture = textureGenerator.GenerateTexture();
    }
        //this method updates the mesh if needed
        public void UpdateMesh()
        {
            //nothing changed
            if (isDirty == false)
            {
                return;
            }

            //start building mesh
            var lathe = new LatheMeshBuilder(numSplines);

            lathe.Add(sideVertices, rotationPerUnitHeightEuler);

            //generate mesh and apply it to meshfilter
            MeshFilter meshFilter = GetComponent <MeshFilter>();

            meshFilter.sharedMesh = lathe.CreateMesh();
        }