Reputation: 21
I have a selection of buttons and a 360 video will depend on which button you select. I want the user to have to have the raycast on the button for 5 seconds before the next video is playing.
This seems to be working okay, however I need the coroutine to stop when the ray is not on the button. I have tried to stop the coroutine when the ray is not on the correct menu item however it still continues. This is what I have tried so far:
public Coroutine coroutine;
void Update()
{
//create the ray to cast forward
RaycastHit hit;
Vector3 origin = transform.position;
Vector3 direction = transform.forward;
Ray ray = new Ray(origin, direction);
Debug.DrawRay(origin, direction * 100, Color.blue);
if (Physics.Raycast(ray, out hit))
{
objectCollided = hit.collider.gameObject.name;
hasHit = true;
if (objectCollided == "goForwardCube")
{
coroutine = StartCoroutine(WaitAndPrint());
}
else if (objectCollided != "goForwardCube")
{
StopCoroutine(coroutine);
}
}
IEnumerator WaitAndPrint()
{
// suspend execution for 5 seconds
ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.clear;
forwardText.text = "5";
yield return new WaitForSeconds(1);
ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.blue;
forwardText.text = "4";
yield return new WaitForSeconds(1);
ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.clear;
forwardText.text = "3";
yield return new WaitForSeconds(1);
ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.blue;
forwardText.text = "2";
yield return new WaitForSeconds(1);
ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.clear;
forwardText.text = "1";
yield return new WaitForSeconds(1);
videoPlayer.url = "Assets/Videos/1(360).mp4";
ButtonControl.DisableButtons();
videoPlayer.Play();
}
Also, since implementing this, there seems to be a long pause before the next video plays and it seems quite laggy. Is there any way to improve this?
Upvotes: 0
Views: 1021
Reputation: 1883
Because you are calling your coroutine in the Update function, you might be calling it every frame that your Raycast is on the button. The thing is that StopCoroutine only stop the first coroutine with the given name. So all the other that you've started keep on running.
To fix this, in addition to the raycast, put a boolean to check if your Coroutine has already been started.
public Coroutine coroutine;
bool alreadyStarted = false;
void Update()
{
//create the ray to cast forward
RaycastHit hit;
Vector3 origin = transform.position;
Vector3 direction = transform.forward;
Ray ray = new Ray(origin, direction);
Debug.DrawRay(origin, direction * 100, Color.blue);
if (Physics.Raycast(ray, out hit))
{
objectCollided = hit.collider.gameObject.name;
hasHit = true;
if (objectCollided == "goForwardCube" && !alreadyStarted)
{
alreadyStarted = true;
coroutine = StartCoroutine(WaitAndPrint());
}
else if (objectCollided != "goForwardCube")
{
alreadyStarted = false;
StopCoroutine(coroutine);
}
}
else
{
alreadyStarted = false;
}
}
IEnumerator WaitAndPrint()
{
// suspend execution for 5 seconds
ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.clear;
forwardText.text = "5";
yield return new WaitForSeconds(1);
ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.blue;
forwardText.text = "4";
yield return new WaitForSeconds(1);
ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.clear;
forwardText.text = "3";
yield return new WaitForSeconds(1);
ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.blue;
forwardText.text = "2";
yield return new WaitForSeconds(1);
ButtonControl.forwardCube.GetComponent<MeshRenderer>().material.color = Color.clear;
forwardText.text = "1";
yield return new WaitForSeconds(1);
videoPlayer.url = "Assets/Videos/1(360).mp4";
ButtonControl.DisableButtons();
videoPlayer.Play();
alreadyStarted = false;
}
Upvotes: 1