【问题标题】:Creating Coroutine for Listeners为监听器创建协程
【发布时间】:2018-05-31 13:22:30
【问题描述】:

我的主脚本按 1 对一组球进行排序,我正在调用该脚本,所以当我 click this 按钮时,它将触发排序按钮,它会通过在示例之间等待 1-2 秒来按 1 对 1 排序每次交换。但是,当我单击用于立即触发自动排序的按钮时,这里的协程并没有做它应该做的事情。

这是一组未分类的球。 Here 有没有什么办法解决这一问题?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using System.Collections;


namespace Assets
{
    public class Trigger : MonoBehaviour
    {
        public Gameobjects _Gameobjects; 
        public Button e_YourButton;
        public void Start()
        {
            Button btn = e_YourButton.GetComponent<Button>();
            for (int k = 0; k < 4; k++)
            {
                btn.onClick.AddListener(_Gameobjects.TaskOnClick);
                btn.onClick.AddListener(() => { _Gameobjects.Click1(); });
                StartCoroutine(Example());    
            }
        }   

        IEnumerator Example()
        {

           yield return new WaitForSeconds(1);
        }
    }
}

主脚本;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using System.Collections;


namespace Assets
{
    public class Gameobjects : MonoBehaviour
    {
        public Button s_YourButton;
        [SerializeField]

        public GameObject[] Balls = new GameObject[5];

        public bool Click = false;

        private static int i = 0;
        private int j = i + 1;
        private int increasebyclick = 1;

        private Vector3 posA = Vector3.zero; //Vector3.zero is for initialization
        private Vector3 posB = Vector3.zero; //Vector3.zero is for initialization


        public GameObject[] instantiatedObjects= new GameObject[5];

        void Start()
        {
            Button btn = s_YourButton.GetComponent<Button>();
            //Calls the TaskOnClick method when you click the Button
            btn.onClick.AddListener(TaskOnClick);
            btn.onClick.AddListener(() => { Click1(); });
            Balls[0] = GameObject.Find("5");
            Balls[1] = GameObject.Find("3");
            Balls[2] = GameObject.Find("2");
            Balls[3] = GameObject.Find("4");
            Balls[4] = GameObject.Find("1");
        }


        public void TaskOnClick()
        {

            performInsertionSort(Balls);



        }
        public void Click1()
        {
            i += increasebyclick;
            print(i);
            if (i >= 4)
            {
                i = 0;            }
        }


        private void performInsertionSort(GameObject[] Balls)
        {
            {



                        if (string.Compare(Balls[i].name, Balls[i+1].name) > 0)
                        {
                            GameObject temp = Balls[i];
                            Balls[i] = Balls[i+1];
                            Balls[i+1] = temp;

                            posA = Balls[i].gameObject.transform.position;
                            posB = Balls[i + 1].gameObject.transform.position;
                            Balls[i].gameObject.transform.position = posB;
                            Balls[i + 1].gameObject.transform.position = posA;


                            }
                }
            }       
        }
    }

【问题讨论】:

  • 如果您的代码,我在任何地方都看不到交换功能。所有这一切都是在延迟后分配侦听器。听起来您希望延迟发生在 onClick 函数本身内。
  • 我会在几分钟后上传我的主要脚本。
  • 不要将其发布在代码共享上,而是从中提取相关代码,并改为add it to your question
  • 启动协程的唯一点是在 start 函数中。此外,您在那里执行的方式只是在循环的每次迭代结束时启动协程的一个实例,但是由于循环不在协程内,所以协程对循环没有任何影响。循环很可能在第一个协程经过一秒钟之前完成。

标签: c# sorting unity3d swap


【解决方案1】:

您的第二个脚本(Gameobjects 命名顺便说一句非常糟糕)应该如下所示:

// Don't start another sort while the current isn't finished
// Or: stop the current one with StopAllCoroutines()
bool isSorting = false;

public void TaskOnClick()
{
    if(isSorting == false)
    {
        isSorting = true;
        StartCoroutine(PerformInsertionSort());
    }
}

private IEnumerator PerformInsertionSort()
{
    for(int i = 0; i < Balls.Length - 1; i++)
    {      
        if (string.Compare(Balls[i].name, Balls[i+1].name) > 0)                   
        {
            GameObject temp = Balls[i];
            Balls[i] = Balls[i+1];
            Balls[i+1] = temp;

            posA = Balls[i].gameObject.transform.position;
            posB = Balls[i + 1].gameObject.transform.position;
            Balls[i].gameObject.transform.position = posB;
            Balls[i + 1].gameObject.transform.position = posA;

            // If you want to wait only after a switch actually happend,
            // wait here.
        }

        // This is where you need to wait:
        yield return new WaitForSeconds(1f);
    }

    isSorting = false;
}

您排序的数组是脚本的成员,因此将其作为参数传递给脚本内的函数是没有意义的。

【讨论】:

  • 分拣需要继续直到分拣完全完成,但是在完成第一组球后停止并且球仍然未分拣,如何解决这个问题?我在达到 4 后尝试重置 i 但没有帮助。
  • 这是排序算法的问题。我只有一个循环(你的函数中根本没有循环),但你需要第二个内循环。外循环从索引 (i) 0 运行到结束,内循环从 array[i] 返回到索引 0,向后比较。看看一些伪代码,例如在维基百科页面上进行插入排序。
猜你喜欢
  • 2012-09-11
  • 1970-01-01
  • 1970-01-01
  • 2015-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多