【问题标题】:Use coroutine inside a non MonoBehaviour class在非 MonoBehaviour 类中使用协程
【发布时间】:2016-11-09 13:36:44
【问题描述】:

如何在非 Monobehaviour 类的实例中传递 Monobehaviour?我发现了这个link,其中 TonyLi 提到你可以传递一个 Monobehaviour 来启动和停止类实例中的协程,但他没有展示你如何做到这一点。他这样做 theEvent.StartEvent(myMonoBehaviour);但他没有显示他从哪里得到 myMonobehaviour。我在互联网上四处寻找,但似乎找不到方法。

  • 编辑

这就是我想要做的。我想在类的实例中运行协程。我还希望能够在类的实例中停止协程。我想这样做,这样我的场景中就没有任何具有大型管理器的对象,而且我可以将代码重用于我想以这种方式进行乒乓球的任何对象。代码向一个方向移动一个游戏对象,然后休息一下,然后向另一个方向移动,然后再次休息,等等。但是我无法从类外启动协程。

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

[RequireComponent (typeof(Image))]
public class SpecialBar : MonoBehaviour {

    public float rangeX;
    public float breakTime;
    public float step;
    float startProgress = 0.5f;
    PingPongGameObject pingPonger;

    Color[] teamColors = new Color[]{new Color(255,136,0),new Color(0,170,255)};

    void Start()
    {

        for(int i = 0; i < teamColors.Length; ++i)
        {
            teamColors[i] = StaticFunctions.NormalizeColor (teamColors[i]);
        }

        pingPonger = new PingPongGameObject (gameObject.transform.position,
            new Vector3(rangeX,0.0f,0.0f),
            gameObject,
            startProgress,
            breakTime,
            step
            );
    }
}

第二个类是我的协程所在的地方。

public class PingPongGameObject
{
    float step;
    Vector3 center;
    Vector3 range;
    GameObject ball;
    float progress;
    float breakTime;
    Vector3 endPos;
    Vector3 oppositePosition;


    public PingPongGameObject(Vector3 _center, Vector3 _range, GameObject _ball, float _startProgress, float _breakTime, float _step)
    {
        center = _center;
        range = _range;
        ball = _ball;
        progress = _startProgress;
        breakTime = _breakTime;
        step = _step;
        endPos = center - range;
        oppositePosition = center + range;
        // This is where I want to start the coroutine
    }

    public IEnumerator PingPong()
    {


        while (progress < 1) {
            progress += Time.deltaTime * step;
            Vector3 newPos = Vector3.Lerp (oppositePosition, endPos, progress);
            ball.transform.position = newPos;
            yield return null;
        }
        Vector3 temp = endPos;
        endPos = oppositePosition;
        oppositePosition = temp;
        progress = 0;
        yield return new WaitForSeconds (breakTime);
        yield return null;
    }

    public float Step
    {
        set{step = value;}
    }

    public void StopCoroutine()
    {
        // This is where I want to stop the coroutine
    }
}

【问题讨论】:

  • 是的,我会在我的问题中解释一下。
  • 我修改了问题。
  • 检查我留下的答案。您可以使用this 关键字。
  • 嗨迈克 - 忽略我之前说你需要一个预制件的评论。其实你说的都是使用组件!!!就是这么简单。
  • 不,OP 想要在不是从 MonoBehaviour 派生的类中使用 IEnumerator/Coroutine。是的,他可以这样做,但是 不能 能够使用 StartCoroutineStopCoroutine 函数,并且正在寻求一种将 MonoBehaviour 的引用传递给其他类的方法,以便他能够要做到这一点。您可以在不将其设为MonoBehaviour 的情况下制作脚本。有时,你必须这样做。当然,他可以做到MonoBehaviour 就像您在 cmets 中所说的并回答,但这不是问题所在。问题是关于传递MonoBehaviour 参考。

标签: c# unity3d


【解决方案1】:

TonyLi 提到你可以通过一个 Monobehaviour 来启动和停止 类实例中的协程,但他没有展示你如何 可以做到这一点。他这样做了

您可以使用 this 关键字来做到这一点。 this 关键字将获取MonoBehaviour 的当前实例。

在这个例子中有一棵树,它恰好有一个组件MonoScript

MonoScript 的特定实例可以根据需要(因为它是一个 c# 程序)实例化一个通用 c# 类 NonMonoScript

传递MonoBehaviour 的类来自:

public class MonoScript : MonoBehaviour
{
    void Start()
    {
        NonMonoScript  nonMonoScript = new NonMonoScript();
        //Pass MonoBehaviour to non MonoBehaviour class
        nonMonoScript.monoParser(this);
    }
}

接收传递MonoBehaviour实例的类:

public class NonMonoScript 
{
    public void monoParser(MonoBehaviour mono)
    {
        //We can now use StartCoroutine from MonoBehaviour in a non MonoBehaviour script
        mono.StartCoroutine(testFunction());

       //And also use StopCoroutine function
        mono.StopCoroutine(testFunction());
    }

    IEnumerator testFunction()
    {
        yield return new WaitForSeconds(3f);
        Debug.Log("Test!");
    }
}

您还可以将来自monoParser 函数的mono 引用存储在一个局部变量中以供重复使用。

【讨论】:

  • 谢谢大家!程序员这正是我要找的。 Joe Blow 我意识到这可能不是处理问题的最聪明的方法,我将研究它并研究你的解释。因为这是我要找的遮阳篷,所以我会把它当作遮阳篷。
  • @MikeOttink 欢迎您。我曾经遇到过无法使用StartCoroutineStopCoroutine函数的问题。这就是我解决它的方法。有时,您不需要从MonoBehaviour 派生脚本。其他时候你会。这取决于您的情况,但此答案仅显示如何将 MonoBehaviour 传递给您所要求的另一个脚本。乔的回答也应该有效。编码愉快!
  • 传递单一行为是天才,因为它通常会从单一行为中调用。非常适合您想在项目范围内使用的静态类!
猜你喜欢
  • 2015-12-28
  • 2020-04-22
  • 2021-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-14
  • 1970-01-01
  • 2019-10-11
相关资源
最近更新 更多