How can start a stopwatch by clicking a button from another script?

I created this script which runs a stopwatch and starts counting when the simulation begins. However I would like it to start counting once you click a button which is in other script called NameManager(nameofscript).I would to like to know how can I call that button from this script in order to make the stopwatch start counting once you click that button.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TimeController : MonoBehaviour
{
private void Awake()
{
current = this;
}
//TimerController.current.runChronometer
public static TimeController current;
private float timer;
private float seconds;
private float minutes;
public bool runChronometer = false;
[SerializeField] Text timeControllerText;
void Start()
{
timer = 0.0f;
}
void Update()
{
if (runChronometer)
//if (Okbutton)
{
TimeControllerCalcul();
}
}
void TimeControllerCalcul()
{
//if (start)
//if (aceptarbutton)
Debug.Log("time: ");
timer += Time.deltaTime;
seconds = timer % 60;
minutes = (timer / 60) % 60;
timeControllerText.text = minutes.ToString(“00”) + “:” + seconds.ToString(“00”);
}
}

Hey and welcome!
First of all please use code tags to post code examples.

You will want the script to have public functions for starting or resetting the stopwatch. Resetting it would simply set the timer to 0 and a ‘running’ bool to false, while starting it would set the running bool to true, which you can use to determine whether or not to run your code in Update.
Using a reference to the stopwatch script you can then call these functions from anywhere. I believe you attempted to implement a singleton there, so you can just get the reference using TimeController.current.FunctionCall(). However, i would suggest implementing proper singleton mechanics, making the instance private, having a public function to return it, and assuring that only one such instance can exist by destroying the gameobject of the script if current != null in Awake. You should find plenty of examples on that online.
One more thing, adding Time.deltaTime each frame will eventually accumulate some floating point rounding errors, so it may be better to just set the “starttime” once and compare the current time to that each frame for your calculations.

1 Like

The target script is attached to a GameObject, so it’s a Component of type . You can call GetComponent just like getting any other component. Put this in your calling script:

private scriptName myScriptName;

void Start() {
myScriptName = GameObject.Find(gameObjectTargetScriptIsAttachedTo).GetComponent<scriptName>();
// now you can call a function in that script:
myScriptName.function();
// or set a variable
myScriptName.variable = 5;
}
1 Like

First of all thank to both of you for your help.The function I need from the other script is a button. The option myScript.function() doesn’t work.

The button I’m trying to call in the TimeController script is named createButton(which is a button) in the NameManager script.

6121598–667070–TimeController.cs (2.08 KB)
6121598–667073–NameManager.cs (1.92 KB)
6121598–667079–EventController.cs (2.96 KB)

You are not supposed to literally write myScript.function(). Read my comment for what you are supposed to do. Seejayjames offered you an example for how to get the reference to a script, which is not necessary for you since yours is a singleton (or something supposed to be one), so you can get the reference through TimeManager.current. You already add a listener to your button. There you will then call the functions for StartStopwatch(), StopStopwatch(), ResetStopwatch(), … i described above.

1 Like

Sorry I’m new to C# and Unity.I modified the script but know I’ve got a new error that says Non-invocable member ‘TimeController.runChronometer’ cannot be used like a method.(LINE 35)

You have a bool called runChronometer, but you try executing it like a method in line… well i have no idea what line that is. As i told you in my first code, please use code tags! That way we have properly formatted code we can copy paste, talk about by referencing line numbers and so on. If you do not know how to use code tags there is a sticky on this subforum.
Anyways in your Start method you write runChronometer(), which implies there should be a function called runChronometer. You want to reference an actual method, for example startTimer() there. While we are at it, you probably want to look into coding conventions. Class, method and property names should be written using UpperCamelCase while variables and such are written using normal camelCase. This improves readability by making code of different programmers uniform and thus easier to understand. It also helps differentiating between public methods and variables of a class and so on.

I changed that mistake in line 35.Now Unity doesn’t detect any errors.However the chronometer still starts counting once the simulation starts.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
//using UnityEngine.Component;

public class TimeController : MonoBehaviour
{
    //private TimeController timecontroller
    //public Transform createButton;
    private void Awake()
    {
        current = this;
    }
    //TimerController.current.runChronometer
    public static TimeController current;
    //public Text timeControllerText;
    //private Button acceptButton;
    private float timer;
    private float globalTime;
    private float seconds;
    private float minutes;
    //public bool startTime;
    public bool runChronometer;
    private bool finish;
    private Button TimeStart;
    private static TimeController NameManager;
    [SerializeField] Text timeControllerText;
    public void Start()

    {
        //runChronometer = false;
        TimeStart = GameObject.Find("Okbutton").GetComponent<Button>();//no funciona
        TimeStart.onClick.AddListener(() => { startTimer(); });
        //current.function("createButton");*/
        timer = 0.0f;
        //m_createButton.onClick.AddListener();
    }
    //private void onClick()
    //{
       // Debug.Log("YOU CLICKED THE BUTTON");
        void Update()
        {

            TimeControllerCalcul();
        }

        //if (runChronometer= false)

        //if (runChronometer)
        void TimeControllerCalcul()
        {
            if (runChronometer)
                //if (aceptarbutton)
                Debug.Log("time: ");
            timer += Time.deltaTime;
            seconds = (int)(timer % 60);
            minutes = (int)((timer / 60) % 60);
            timeControllerText.text = minutes.ToString("00") + ":" + seconds.ToString("00");
        }
        void startTimer()
        {
            runChronometer = true;
        }
        void stopTimer()
        {
            runChronometer = false;
        }
        void endtime()
        {
            finish = true;
            runChronometer = false;
            timer = 0;
        }
    }

You need to put brackets around if statements. Currently the only thing your if(runChronometer) does is print the Debug.Log statement. Everything else is outside of the if-statement. For reasons such as this i would always put the brackets, even for one-line if statements, where they are not necessary.

1 Like

Now it finally works.Thank you very much for your help