Unity 3D - Pass a monobehaviour inside a non monobehaviour class


How can you pass a Monobehaviour inside an instance of a non Monobehaviour class? I found this link https://forum.unity3d.com/threads/running-startcoroutine-from-a-non-monobehaviour.233817/ where TonyLi mentions that you can pass a Monobehaviour to start and stop coroutines inside a instance of a class, but he does not show how you can do that. He does this theEvent.StartEvent(myMonoBehaviour); but he does not show where he gets myMonobehaviour from. I looked around on the internet but I cannot seem to find how.

  • Edit

Here is what I am trying to do. I want to run a coroutine inside an instance of a class. I also want to be able to stop the coroutine inside the instance of the class. I want to do it this way so that I don't have any objects in my scene that have large managers and also so that I can reuse the code for any object that I want to pingpong in this way. The code moves a Gameobject in one direction then takes a break and moves it in the other direction and takes a break again etc. But I cannot start the coroutine from outside the class.

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),

The second class is where my coroutine is in.

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

Show source
| c#   | unity3d   2016-11-09 14:11 2 Answers

Answers ( 2 )

  1. 2016-11-09 14:11

    Answer to your new specific question:

    Mike dude the solution is incredibly easy.

    1. write a "PingPing" behavior. I will paste one in for you in a minute.

    2. attach it to the GameObject

    3. when you want to ping pong, just turn it on or off!!!!

    It's that simple!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    GetComponent<PingPong>.enabled = true;
    GetComponent<PingPong>.enabled = false;

    Alternately, if you prefer just add the behavior as needed:


    to remove it, simply


    This is indeed the most basic concept in Unity - you write behaviors that do things - make it explode, make it ping poing, make it dance, whatever.

    And you simply attach that script (to anything) to have that GameObject do that behavior. That's all there is to it.

    Here's the simplest way to make something PingPong:

    using UnityEngine;
    using System.Collections;
    public class PingPonger:MonoBehaviour
      void Update()
       transform.position = new Vector3(
          Mathf.PingPong(Time.time, 5f),transform.position.y,transform.position.z);

    Attach PingPonger to ANY object and it will PingPong.

    To start and stop the pingponing, of course just do this:

        GetComponent<PingPonger>().enabled = true;
        GetComponent<PingPonger>().enabled = false;

    If you prefer, just add the component when you need it, to any game object


    This is the most basic, most central idea in Unity:

    to make GameObject do something, you add a behavior. Specifically Component class in Unity.

    BTW note that PingPong is totally built-in to Unity.

    Handy tip ...


    SmoothDamp is a really handy function, you use it constantly in Unity.

    FYI you've asked how to make a pingponger go back and fore around zero. This is a basic of programming, nothing to it ...

    Between 0f and 5f

    transform.position = new Vector3(Mathf.PingPong(Time.time, 5f), ...);

    Between -5f and 5f

    transform.position = new Vector3(Mathf.PingPong(Time.time, 10f) - 5f, ...);
  2. 2016-11-09 15:11

    TonyLi mentions that you can pass a Monobehaviour to start and stop coroutines inside a instance of a class, but he does not show how you can do that. He does this

    You are can do that with the this keyword. The this keyword will get the current instance of MonoBehaviour.

    In this example there's a tree, which happens to have a component MonoScript:

    enter image description here

    That particular instance of MonoScript can if it wants (since it's a c# program) instantiate a general c# class, NonMonoScript:

    Class to pass MonoBehaviour from:

    public class MonoScript : MonoBehaviour
        void Start()
            NonMonoScript  nonMonoScript = new NonMonoScript();
            //Pass MonoBehaviour to non MonoBehaviour class

    Class that receives pass MonoBehaviour instance:

    public class NonMonoScript 
        public void monoParser(MonoBehaviour mono)
            //We can now use StartCoroutine from MonoBehaviour in a non MonoBehaviour script
           //And also use StopCoroutine function
        IEnumerator testFunction()
            yield return new WaitForSeconds(3f);

    You can also store the mono reference from the monoParser function in a local variable to be re-used.

◀ Go back