Search code examples
c#unity-game-engineaugmented-realityvuforiacoroutine

Coroutine is not working fine - Unity [C#]


i'm using Unity to track some image target (ARCamera - Vuforia) and everything works fine. I've inserted some 2D sprites on the image target etc... but now i don't want to show all the targets as soon as the image target is found, so i went to DefaultTrackableEventHandler.cs and instantiated my custom class Example like this:

 #region PRIVATE_MEMBER_VARIABLES

 private TrackableBehaviour mTrackableBehaviour;

 #endregion // PRIVATE_MEMBER_VARIABLES

 public Example mainClass;

...

private void OnTrackingFound()
    {
    ...
        Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");

        mainClass = new Example();
        mainClass.OnTrackableFound(); // Public method on 'Example' Class
    }

Now on my Example class:

public class Example : MonoBehaviour {

public SpriteRenderer forYou;
public SpriteRenderer map;

public Example () {}

private bool isInTransition = false;
private float transition = 1;
private bool isShowing = false;
private float duration = 0;

void Start()
{
    forYou = new SpriteRenderer();
    map = new SpriteRenderer();
}

public void OnTrackableFound() {
    StartCoroutine(FadeCoroutine());
}

private IEnumerator FadeCoroutine() {
    yield return new WaitForSeconds(1);
    Fade(true, .1f);
}

public void OnTrackableLost() {}

public void Fade (bool showing, float duration)
{
    isShowing = showing;
    isInTransition = true;
    this.duration = duration;
    transition = (isShowing) ? 0 : 1;
}

void Update ()
{
    if (Input.GetMouseButtonDown (0)) {
        Fade (true, .1f);
    }
    if (Input.GetMouseButtonUp (0)) {
        Fade (false, .1f);
    }


    if (!isInTransition) {
        return;
    }

    transition += (isShowing) ? Time.deltaTime * (1 / duration) : -Time.deltaTime * (1 / duration);
    forYou.color = Color.Lerp (Color.white, new Color (1, 1, 1, 0), transition);
    map.color = Color.Lerp (Color.white, new Color (1, 1, 1, 0), transition);

    if (transition > 1 || transition < 0) {
        isInTransition = false;
    }
}

} Sorry for the amount of code, but basically this is just for fading in/out some sprites. I want to yield as soon as my OnTrackingFound is called at Example class and after idk .5 seconds fade in some of my sprites.

Thank you!

EDIT - SOLVED

So, to attach a script to a game object it must inherit from Monobehaviour but than it cannot be instantiated so what i did was: I needed the OnTrackingFound() from the DefaultTrackerHandler... so i coded everything on that class [i know it's far from the best solution but...] instead of instantiate another script because as i said it wouldn't be possible to attach it to a game object since it couldn't inherit from Monobehaviour. With public game objects, i attached everything directly from this class that also inherits from Monobehvr. If you instantiate a script that inherits monobehv it will be null. Thanks everyone!


Solution

  • The issue with your code is that you try to instantiate component Example that derives from MonoBehaviour calling constructor with new keyword.

    Never do this.

    All components in Unity3D Engine needs to be added to existing GameObject with GameObject.AddComponent<T>()

    So what you need to do is:

    private void OnTrackingFound()
    {
        ...
        Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
    
        // create new GameObject and add component
        mainClass = new GameObject("MyNewGameobject").AddComponent<Example>();
        mainClass.OnTrackableFound(); // Public method on 'Example' Class
    }