Creating a class to execute instances of the same code across multiple scripts?

Hey Everyone,

I need some help with writing a class/another alternative to execute various instances of a piece of code that would be returning numbers based on values given to it at start. To explain this problem in detail here is an example:

I have this simple timer code that’s calculating a value for its completion based on a number given to it at the start:

        if (startTimer) {

            currentTime += Time.deltaTime;
            ring.fillAmount = currentTime / totalTime;

            if (currentTime >= totalTime) {
              startTimer = false;
            }
        }

I have six different scripts that use this exact same logic for the timer, and they all are calculating for a timer completion. Currently, I have hand written it six times as each script has its own value for “totalTimer” variable and a lot of them needs to use the timer it at different times.

What I want to do is write possibly a class/another alternative that handles the timer and does all of the logic and returns the percent value for its completion. This way, I would only have to write the timer logic once and call this every time I need to start a timer and get a value back. Another thing is, a lot of these scripts do simultaneously have to start the timer for their own reasons, so it needs to be able to handle multiple timers.

It would be great if someone can help me out with this problem.

Simplest answer: what you’re doing here is called “tweening”, the act of animating/updating some value over a period of time. If you do this kind of thing a lot, I’d recommend a tweening plugin, DOTween is free and really useful: http://dotween.demigiant.com/

For example, to do your example with DOTween:

ring.fillAmount = 0f;
ring.DOFillAmount(1f, totalTime);

More complicated answer, if you want to do it manually instead, there are a bunch of different ways to do it and I’m sure someone will give you an example. But I would still recommend a tween library instead; no point in reinventing the wheel.

OPTION 1:

One option is to use class inheritance.

This is a useful tool from object oriented programing, not specific to unity.

For example. you make a class (create new script) called TimeBased.

inside this class you put your timer code inside a public function :

public void runTimer(){
//timer logic here
}

Whenever you have another sciprt (class) that needs the timer code. you can make it EXTEND your TimeBased script;

the new class now inherits all functions from the parent class.

You already use this in unity. you will notice all new scripts start with something like

public class NewClass : MonoBehaviour{
//code
}

This in essence means your script extends the MonoBehaviour class, thats where all those functions like start(), update(), etc come from. they are inherited from the parent class MonoBehaviour.

Don’t worry tho. you wont loose all those functions by inheriting from a different classs, as long as the base class inherits from the MonoBehaviour base class aswell. This is what in object oriented programing we call Polymorphism. or the ability of classes to be multiple things at the same time.

for example the class

TestClass : TestParent (TestClass extends TestParent)

where

TestParent : Monobehaviour. (TestParent extends Monobehaviour)

Is polymorphic. an object instanciated from such a class is a TestClass object but also a TestParent and also a MonoBehaviour object. It will be able to use all functions in the TestParent class, all functions in the monoBehaviour class and all functions in it’s own class.

How it would look like in code.

Class 1)

public class TimerBased : MonoBehaviour {

public void runTimer(){
//timer logic here
}


}

Class 2)

public class TestClass : TimerBased (// remember that it also extends MonoBehaviour as the parent class is polymorphic with MonoBehaviour) {

// misc code

}

Now to call the runTimer() function all you have to do is call it as if it would exist inside the TestClass itself.

either from the script itself or from an external script. For example as

gameobject.GetComponent().runTimer();

This is very useful when you want to have different classes belong to a certain “type” of class.

for example (Rottweiler extends Dog, which extends Mammal, which extends Animal… etc)

OPTION 2:

Something else you could do is have a script that contains your timer code ( also any other code that needs to be used by many different other classes) inside an empty game object.

Whenever a script needs to use one of this “global” scripts. all it needs to do is find that game object (can be by name, tag, etc) and getComponent the script where all this functions are and just call it from there. You can have the functions need parameters as necessary to communicate infromation between scripts.

For example, inside an empty GameObject called GlobalScripts, there is a script called UsefulFunctions(). inside this script there is a function

Attack(GameObject target){
target.hp --;
}

Now say you want to acess one of those functions from another script called BadGuy().

You would do something inside of the BadGuy script like :

GameObject.find(“GlobalScripts”).GetComponent().Attack(target);

Now the empty world object will run the Attack() function using wathever game object BadGuy wants as target.

You can imagine how to do this with a timer also.