0

Im trying to create a custom function in unity that performs setActive false but with Delay. Without Using Coroutine or Invoke Methods.

Im trying to create something like the Function Destroy in Unity: Destroy(Object obj, float time) But with SetActive.

What I am aiming for is a function like this SetActiveWithDelay(GameObject obj, bool stateToChange, float delayTime) with which we can write a line like SetActiveWithDelay(GameObjectToPass,true,2f) this which setActive the Gameobject to true by 2sec.

This can be easily done with Invoke or the use of Coroutine. But I just am curious about how to make a custom function this way. Makes things a lot simpler, instead of creating an IEnumerator and Using StartCoroutine or Invoke with string.

I looked into the object class on how Destroy was written and tried to replicate it. But it was confusing to me how it works. So, Let me know if anyone has any ideas on how to do this. Thanks!

Here below are some of the things I tried but again the custom function had a use of coroutine. But I feel this is all the same and I can directly use coroutine. So I'm interested to know if there is any other method or if going with coroutine and invoke is a better option. With Coroutine:

Gameobject GOToMakeFalse;

void Start()
{
//Aiming for a simplified Custom Function to write this way. With Does As it says make gameobject false after two seconds
   
SetActiveWithDelay(GOToMakeFalse,false, 2f);
}

SetActiveWithDelay(GameObject obj ,bool inState,float delayTime)
{
//But without using a coroutire like this here
   StartCoroutine(DelayedSetActive(obj,inState, delayTime));
}

public IEnumerator DelayedSetActive(GameObject GO,bool inBoolState, float dT)
{
   yield return new WaitforSeconds(dT);
   GO.SetActive(false);
}

And im also curious if we can extend the GameObject Class something like this. GameObject.SetActiveWithDelay(true,2f); Even this would be a cool addition and make development easy.

3 Answers 3

1

About extension, something like that should work:

public static class GameObjectExtensions
{
    public static void SetActiveWithDelay(this GameObject obj, bool inState, float delayTime)
    {
        // ...
    }
}

myGameObject.SetActiveWithDelay(true, 2f);

The important parts are the "static" class and the "this" in the first parameter of the static method.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the Answer! This structure does the job i was expecting. But what statements do we fill inside the function to get the delay done. Need some ideas there! Cause all I know is using a coroutine or using async tasks. Do you have any other idea (or) coroutine/async is our only option to add delay. Just Brainstroming to see if we have something else.
1

You can use Async await or a simple timer script if you don't want to use coroutines. For Async you need to add the namespace

using System.Threading.Tasks;

You can read more on how to delay using Async here.

1 Comment

Okay Thanks.. Good idea. Are you aware or have an idea on how we extend the SetActive function itself? Like a Gameobject class extension?
0

With the Help of @Vionix and @Kandohar. I have written an extension class of SetActiveWithDelay.

I have written 2 versions of it. Version 1 is with using "GameManager" as my GameManager class is a singleton instance & Version 2 is Having a MonoBehaviour script attached to the Gameobject you want to SetActive false and accessing that MonoBehaviour class. Hope this method will be helpful. Any alterations to this code by anyone are happily taken. Here is the Answer I came Up With.

Version-1: If you have a GameManager class that is a singleton instance

public static class GameObjectExtensions
    {
        public static void SetActiveWithDelay(this GameObject inObject, bool inState, float delayTime)
        {
            GameManager.Instance?.StartCoroutine(CallWithDelay(inObject, inState, delayTime));
        }

        static IEnumerator CallWithDelay(this GameObject inObject, bool inState, float delayTime)
        {
            yield return new WaitForSeconds(delayTime);
            inObject.SetActive(inState);
        }
    }

Version-2: By accessing Monobehaviour class that is attached with the Gameobject we access.

public static class GameObjectExtensions
    {
        public static void SetActiveWithDelay(this GameObject inObject, bool inState, float delayTime)
        {
            MonoBehaviour mono = inObject.GetComponent<MonoBehaviour>();
            mono.StartCoroutine(CallWithDelay(inObject, inState, delayTime));
        }

        static IEnumerator CallWithDelay(this GameObject inObject, bool inState, float delayTime)
        {
            yield return new WaitForSeconds(delayTime);
            inObject.SetActive(inState);
        }
    }

Disclaimer: In Version Two, you need to make sure the Gameobject you're about to Setactive should definitely have a MonoBehaviour Script Attached to it.

With this now we can write GameObjectThatWeWantToChange.SetActiveWithDelay(true,2f);

I Thank @Vionix and @Kandohar for your answer and support. As said earlier if you guys have any idea on making my above snippet / answer better. Please do, and post it here. Thanks!

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.