The bool state does not prevent the function from repeating

You are having trouble tracking this for some reason, it should be simple, but I'm missing something. In PreCountdownTimer()I get two bool properties from GameManager.cs, assigning them _userActiveand _preCountdownActivethen looking for changes in . When it starts and sets the parameter to true. Update()_userActive = false && _preCountdownActive = false StartPreCountTimer()_preCountdownActive

Now, when this happens, it will no longer be able to call according to the conditional expression ... but it does anyway. This causes my timer to receive the call again and again, every frame, thereby preventing it from counting down. What am I having here wrong that prevents the bool from stopping from firing ? Update() StartPreCountTimer()_preCountdownActive Update StartPreCountTimer()

PreCountdownTimer.cs

using System.Collections;
using UnityEngine;

public class PreCountdownTimer : MonoBehaviour {

    public bool ShowRestartDialog { get; set; }
    private IEnumerator counter;
    private bool _startPrecount;
    private float _preCountdownInterval;
    private bool _preCountdownActive = false;
    private bool _userActive = false;
    private float _timerLength;

    void Start()
    {
        _timerLength = GameManager.Instance.PreCountdownLength;
    }

   void Update()
    {
        _userActive = GameManager.Instance.UserActive;

        if (!_userActive && !_preCountdownActive)
            StartPreCountTimer(_timerLength);
        else if (_userActive && _preCountdownActive)
            StopPreCountTimer();

        Debug.Log("The state of preCountdownActive is: " + _preCountdownActive);
    }

    void StartPreCountTimer(float length)
    {
        _preCountdownActive = true;
        counter = RunTimer(length);
        StartCoroutine(counter);   
    }

    void StopPreCountTimer()
    {
        _preCountdownActive = false;
        StopCoroutine(counter);
    }

    IEnumerator RunTimer(float seconds)
    {
        float s = seconds;
        while (s > 0)
        {
            yield return new WaitForSeconds(_preCountdownInterval);
            s -= _preCountdownInterval;
            Debug.Log("PreCount: " + s);
        }

        if (s == 0)
        {
            _preCountdownActive = false;
            ShowRestartDialog = true;
        }

    }
}

GameManager.cs

using UnityEngine;
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour
{
    public static GameManager Instance = null; // create singleton

    public Object introScene;

    public bool UserActive { get; set; }
    public bool OnIntroScreen { get; set; }

    public GameObject preCountdownTimerPrefab;
    private GameObject _preCountdownTimerInstance;
    public float PreCountdownLength { get; protected set; }
    public float PreCountdownInterval { get; protected set; }

    private float _checkMousePositionTimingInterval = 1.0f;
    private Vector3 _currentMousePosition;
    private Vector3 _prevMousePosition;
    private Scene _currentScene;

    void Awake()
    {
        if (Instance == null)
            Instance = this;
        else if (Instance != null)
            Destroy(gameObject);

        DontDestroyOnLoad(gameObject);
    }

    void OnEnable()
    {
        SceneManager.sceneLoaded += OnSceneLoaded;
    }

    void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        _currentScene = scene;
    }

    void Start()
    {
        PreCountdownLength = 5.0f;
        PreCountdownInterval = 1.0f;

        OnIntroScreen = true;
        UserActive = false;

        _prevMousePosition = Input.mousePosition;

        InvokeRepeating("LastMousePosition", 0, _checkMousePositionTimingInterval); 
    }

    void Update()
    {
        _currentMousePosition = Input.mousePosition;

        if (_currentScene.name != introScene.name)
        {
            OnIntroScreen = false;
            if (_currentMousePosition != _prevMousePosition)
                UserActive = true;
            else
                UserActive = false;       
        }
        else if (_currentScene.name == introScene.name)
            OnIntroScreen = true;

        if (!UserActive && !OnIntroScreen)
            if (_preCountdownTimerInstance == null)
                _preCountdownTimerInstance = Instantiate(preCountdownTimerPrefab);
        else if (UserActive)
            if (_preCountdownTimerInstance != null)
                Destroy(_preCountdownTimerInstance);
    }

    void LastMousePosition()
    {
        _prevMousePosition = Input.mousePosition;
    }
}
+4
source share
1 answer

I solved the problem by directly accessing properties, rather than storing property values ​​for local variables and gaining access to local variables. Hope this is the right way to do this?

using System.Collections;
using UnityEngine;

public class PreCountdownTimer : MonoBehaviour {

    private IEnumerator counter;

   void Update()
    {
        if (!GameManager.Instance.UserActive && !GameManager.Instance.PreCountdownActive)
            StartPreCountTimer(GameManager.Instance.PreCountdownLength);
        else if (GameManager.Instance.UserActive && GameManager.Instance.PreCountdownActive)
            StopPreCountTimer();
    }

    void StartPreCountTimer(float length)
    {
        GameManager.Instance.PreCountdownActive = true;
        counter = RunTimer(length);
        StartCoroutine(counter);   
    }

    void StopPreCountTimer()
    {
        GameManager.Instance.PreCountdownActive = false;
        StopCoroutine(counter);
    }

    IEnumerator RunTimer(float seconds)
    {
        float s = seconds;
        while (s > 0)
        {
            yield return new WaitForSeconds(GameManager.Instance.PreCountdownInterval);
            s -= GameManager.Instance.PreCountdownInterval;
            Debug.Log("PreCount: " + s);
        }

        if (s == 0)
        {
            GameManager.Instance.PreCountdownActive = false;
        }
    }
}
0
source

Source: https://habr.com/ru/post/1681997/


All Articles