- Home /
How do I make a coroutine from another script stop?
Hey guys! How do I make a coroutine that is active in another script stop? Here is my current try : (Note: the script 2 is in the gameobject "blueswitch")
SCRIPT 1
public GameObject blueswitch;
void OnTriggerEnter2D(Collider2D collision){
if (collision.tag == "Deathlimit" && EndDoorTouched == false)
{
blueswitch.GetComponent<BlueDoorScript>().CancelCoroutine();
}
}
SCRIPT2
public void CancelCoroutine(){
StopCoroutine(ButtonTimer());
}
Answer by InfixionGames · Apr 22, 2019 at 07:38 PM
make sure when you call the coroutine you do it like this: StartCoroutine("ButtonTimer");. You would do the same thing for the stop. So you make a reference to the script and simply say StopCoroutine("ButtonTimer"); Here is some code for if you don't know how to make a reference
NameOfScript nameOfScript = GameObject.Find("NameOfGameObjectWithScript").GetComponent<NameOfScript>().StopCoroutine("ButtonTimer");
I did as you said but it seems that my coroutine just wont stop. I conducted an experriment placing a StopCoroutine in the line of code after the StartCoroutine and it had no effect either. I am wondering if by any chance some part of my script in the coroutine is affecting this. If you could check I would be gratefull
IEnumerator ButtonTimer(){ //timer for platforms after button pushed
Debug.Log("ok");
for (int i = 0; i < DisabeledStartPlatforms.Length; i++)
{
DisabeledStartPlatforms[i].SetActive(true);
}
for (int i = 0; i < ActiveStartPlatforms.Length; i++)
{
ActiveStartPlatforms[i].SetActive(false);
}
yield return new WaitForSeconds(time);
Debug.Log("2ndpart");
for (int i = 0; i < DisabeledStartPlatforms.Length; i++)
{
DisabeledStartPlatforms[i].SetActive(false);
}
for (int i = 0; i < ActiveStartPlatforms.Length; i++)
{
ActiveStartPlatforms[i].SetActive(true);
}
rend.enabled = true;
box.enabled = true;
}
}
Answer by jishanator · Apr 23, 2019 at 02:39 AM
It sounds like what you need is an event system and not so much coroutines. Here's an example to get you started (UNTESTED CODE)
Notes BEFORE YOU READ: It's extremely important to de-register events before the objects listening are destroyed, you can cause memory leaks if you don't. Please lookup events for more information but you can always de-register via:
_myButtonReference.OnButtonPressed -= HandleButtonPressed;
And now the actual code:
using System;
using UnityEngine;
public class Button : MonoBehaviour
{
public event Action<bool> OnPressedEvent;
private bool isActive = false;
// assuming this is activated via an external method
// for example, player pressing "A" and collider
// hitting this and calling ButtonPressed
public void ButtonPressed()
{
if (!isActive)
{
isActive = true;
// question mark simply handles checking null reference if no event is defined
OnPressedEvent?.Invoke(isActive);
} else
{
isActive = false;
OnPressedEvent?.Invoke(isActive);
}
}
}
This is the door script (again, hard to know out of context):
using UnityEngine;
public class Door : MonoBehaviour
{
// drag your button reference from editor to assign
[SerializeField] private Button blueButton;
private void Start()
{
blueButton.OnPressedEvent += HandleButtonPressed;
}
private void HandleButtonPressed(bool active)
{
if (active)
{
Debug.Log("Button is now active");
}
else
{
Debug.Log("Button is now inactive");
}
}
}
And here's a temporary platform listening for the button as well:
using UnityEngine;
[RequireComponent(typeof(Collider2D))]
public class TemporaryPlatform : MonoBehaviour
{
// your button reference to store, drag from editor
[SerializeField] private Button _buttonToActivate;
// time active in seconds
private float _activeTimeDuration = 3f;
private float _timeEnabled;
private Collider2D _collider2d;
private void Awake()
{
_collider2d = GetComponent<Collider2D>();
// start diasbled while we wait for button press
_collider2d.enabled = false;
}
private void Start()
{
// register to the event if we have a button
if(_buttonToActivate != null)
{
_buttonToActivate.OnPressedEvent += HandleButtonPressed;
}
}
private void Update()
{
// if we were enabled, keep adding time per frame
if(_timeEnabled > 0f)
{
_timeEnabled += Time.deltaTime;
}
// if we've been enabled beyond or equal to the duration, handle it
if(_timeEnabled >= _activeTimeDuration)
{
HandleExpiredTime();
}
}
private void HandleButtonPressed(bool isActive)
{
if (isActive)
{
ActivatePlatform();
}
else
{
// handle player forced deactivation? (pressing button on/off)
}
}
private void ActivatePlatform()
{
_timeEnabled = Time.deltaTime;
// enable collider here and anything other effects
_collider2d.enabled = true;
}
private void HandleExpiredTime()
{
_timeEnabled = 0f;
_collider2d.enabled = false;
}
}
Answer by happywheelsasz · Apr 23, 2019 at 03:06 AM
Thanks for your article! I have read through some similar topics! However, your post has given me a very special impression, unlike other posts. I hope you continue to have valuable articles like this or more to share with everyone!
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Must I attach every script to a gameobject in order to work ? 2 Answers