0
\$\begingroup\$

I am trying to perform two operations. First I want to increase the size of a GameObject and then delay for 0.1s before returning it back to its original size. However, when I try using StartCoroutine(), it keeps giving me the error :

An object reference is required to access not-static members

even though I made my Delay() function static. Can somebody please tell me what I'm doing wrong?

public static void MoveSelected(int choice)
{
    GameObject rock1 = GameObject.Find("Rock1");
    GameObject paper1 = GameObject.Find("Paper1");
    GameObject scissors1 = GameObject.Find("Scissors1");

    Vector3 scl;

    if (choice == 1)
    {
        scl = rock1.transform.localScale;
        scl.x *= 1.1f;
        scl.y *= 1.1f;
        rock1.transform.localScale = scl;

        StartCoroutine(Delay());

        scl.x /= 1.1f;
        scl.y /= 1.1f;
        rock1.transform.localScale = scl;
    }
    else if (choice == 2)
    {
        scl = paper1.transform.localScale;
        scl.x *= 1.1f;
        scl.y *= 1.1f;
        paper1.transform.localScale = scl;

        StartCoroutine(Delay());

        scl.x /= 1.1f;
        scl.y /= 1.1f;
        rock1.transform.localScale = scl;
    }
    else if (choice == 3)
    {
        scl = scissors1.transform.localScale;
        scl.x *= 1.1f;
        scl.y *= 1.1f;
        scissors1.transform.localScale = scl;

        StartCoroutine(Delay());

        scl.x /= 1.1f;
        scl.y /= 1.1f;
        rock1.transform.localScale = scl;
    }

}

static IEnumerator Delay()
{
    yield return new WaitForSeconds(0.1f);
}
\$\endgroup\$
2
\$\begingroup\$

This is not how coroutines work.

StartCoroutine returns immediately after starting the coroutine, and the function you called it from keeps executing. It does not wait for that coroutine to finish.

So you can't use StartCoroutine to put a delay into a non-coroutine method. (If that method is itself a coroutine, you can yield to a newly-started coroutine until it completes)

Also, StartCoroutine itself is not a static method, so you need to have a Monobehaviour instance to call it. That instance is important for tracking the state of the coroutine from frame to frame.

So we could rework your method as an instance method like so:

public void MoveSelected(int choice) {
    Transform option;
    switch(choice) {
        case 1: option = rock1.transform; break;
        case 2: option = paper1.transform; break;
        case 3: option = scissors1.transform; break;
    }

    StartCoroutine(PulseChosenOption(option));
}

IEnumerator PulseChosenOption(Transform option, float delay = 0.1f, float pulseAmount = 1.1f) {
    var originalScale = option.localScale;
    option.localScale = originalScale * pulseAmount;

    yield return new WaitForSeconds(delay);

    option.localScale = originalScale;
}
\$\endgroup\$
  • \$\begingroup\$ I appreciate this hint, but it does not solve my original error. I still get the same error when trying to call the IEnumerator function \$\endgroup\$ – M.Ahmed Feb 13 '18 at 3:22
  • \$\begingroup\$ Remember, you MUST call the IEnumerator function from an instance of the MonoBehaviour. ie. instance.StartCoroutine(instance.PulseChosenOption(option)) (without the instance, it's implicitly this, which works from an instance method but not from a static method since a static method has no "this" to point at) \$\endgroup\$ – DMGregory Feb 13 '18 at 3:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.