3

So, I have an object. When I press Spin Button, I want it to spin. When I press Stop button, I want it to stop.

It spins fine when its in void Update, but when its in its own function, it does it just once. I tried using loop but still no luck. Can anyone help me please?

Code C#:

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

public class spin : MonoBehaviour
{
    public float speed = 500f;
    public Button starter;
    public Button stopper;

    int testing = 200;

    void Start () {

        Button btn = starter.GetComponent<Button> ();
        Button butn = stopper.GetComponent<Button> ();

        butn.onClick.AddListener(FidgetSpinnerStop);
        btn.onClick.AddListener(FidgetSpinnerStart);
    }

    void FidgetSpinnerStart ()
    {
        for (int i = 0; i < testing; i++) {
            transform.Rotate (Vector3.up, speed * Time.deltaTime);
            Debug.Log ("Test: " + i);
        }
    }

    void FidgetSpinnerStop ()
    {
        transform.Rotate (Vector3.up, Time.deltaTime);
    }
}

Thanks in advance!

2 Answers 2

4

The for loop isn't working as expected because you are not waiting for a frame. Basically, it will do all the spinning in one frame and you won't see the changes until the final spin. Waiting for a frame can the done with yield return null; and that requires a coroutine function.

This is better done with a coroutine. You can use boolean variable with a coroutine or you can just use StartCoroutine and StopCoroutine. Start coorutine that spins the Object when the start Button is clicked and then stop the coroutine when the stop Button is clicked.

public float speed = 500f;
public Button starter;
public Button stopper;
bool isSpinning = false;

IEnumerator spinnerCoroutine;

void Start()
{
    //The spin function
    spinnerCoroutine = spinCOR();

    Button btn = starter.GetComponent<Button>();
    Button butn = stopper.GetComponent<Button>();

    butn.onClick.AddListener(FidgetSpinnerStop);
    btn.onClick.AddListener(FidgetSpinnerStart);
}

IEnumerator spinCOR()
{
    //Spin forever untill FidgetSpinnerStop is called 
    while (true)
    {
        transform.Rotate(Vector3.up, speed * Time.deltaTime);
        //Wait for the next frame
        yield return null;
    }
}

void FidgetSpinnerStart()
{
    //Spin only if it is not spinning
    if (!isSpinning)
    {
        isSpinning = true;
        StartCoroutine(spinnerCoroutine);
    }
}

void FidgetSpinnerStop()
{
    //Stop Spinning only if it is already spinning
    if (isSpinning)
    {
        StopCoroutine(spinnerCoroutine);
        isSpinning = false;
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! Now I see how it's done. What a rookie mistake, heh. Thanks again.
4

Following is a simple class that start and stops spinning an object using two buttons, I hope it makes a starting point of what you are trying to achieve.

public class TestSpin : MonoBehaviour
{
    public float speed = 500f;
    public Button starter;
    public Button stopper;

    bool IsRotating = false;

    void Start()
    {

        Button btn = starter.GetComponent<Button>();
        Button butn = stopper.GetComponent<Button>();

        butn.onClick.AddListener(FidgetSpinnerStop);
        btn.onClick.AddListener(FidgetSpinnerStart);
    }

    void FidgetSpinnerStart()
    {
        IsRotating = true;
    }

    void FidgetSpinnerStop()
    {
        IsRotating = false;
    }

    void Update()
    {
        if (IsRotating)
            transform.Rotate(0, speed, 0);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.