在同一画布中创建了重复的文本,但第二个不起作用

问题描述 投票:0回答:1

它们具有完全相同的代码行,但第二行不起作用。第一次倒计时应该在游戏首次开始时运行,而第二次倒计时则在正在进行战斗时运行。

这是第一个按预期工作的:

public class Countdown : MonoBehaviour
{
    float currentTime=0f;
    float startingTime=5f;
    public string outcome; //This will be the outcome of the random roll that will decide who attacks first

    [SerializeField] Text countdownText;

    void Awake()
    {

        currentTime = startingTime; //setting current time to 5
        System.Random rand = new System.Random(); //choses a random number between 0 and 1
        if (rand.Next(0, 2) == 0) 
        {
            outcome = "Player 1 Attacks First";
        }

        else
        {
            outcome = "Player 2 Attacks First";
        }
    }
    void Update()
    {

        if (currentTime > 3.5)
        {
            Timer();
            countdownText.text = outcome; // Displays the player that starts attacking firtst

        }
        if (currentTime > 0.5&& currentTime<3.5) //Starts the timer from 3
        {
            Timer();
            countdownText.text = currentTime.ToString("0");
        }


            if (currentTime < 0.5)
            {
            Timer();
            countdownText.text = "GO";
            }

            if (currentTime < -0.5)
            {
            countdownText.text = "";
            this.enabled = false;
            }


    }
    void Timer()
    {
        currentTime -= 1 * Time.deltaTime;
    }

}

这是第二个,它只显示“0”:

public class CountdownInBattle : MonoBehaviour
{
    float currentTime = 0f;
    float startingTime = 5f;
    [SerializeField] Text countdownText2;

    // Start is called before the first frame update
    void Awake()
    {
        currentTime = startingTime;
        //if (GameObject.Find("Canvas").GetComponent<Countdown>().enabled == true)
        //{
        //    this.enabled = false;
        //}
        Debug.Log("Starting Countdown");
    }

    // Update is called once per frame
    void Update()
    {
        if (currentTime > 0.5 && currentTime < 3.5) //Starts the timer from 3
        {
            Timer();
            countdownText2.text = currentTime.ToString("0");
        }


        if (currentTime < 0.5)
        {
            Timer();
            countdownText2.text = "GO";
        }

        if (currentTime < -0.5)
        {
            countdownText2.text = "";
            this.enabled = false;
        }
    }

    void Timer()
    {
        currentTime -= 1 * Time.deltaTime;
    }
}

这个应该在每次发生战斗时运行,但它根本不起作用。无法弄清楚为什么。

c# unity3d
1个回答
0
投票

你在开始时将currentTime设置为5f

所以你在Update没有任何条件

if (currentTime > 0.5 && currentTime < 3.5) //Starts the timer from 3
{
    Timer();
    countdownText2.text = currentTime.ToString("0");
}


if (currentTime < 0.5)
{
    Timer();
    countdownText2.text = "GO";
}

if (currentTime < -0.5)
{
    countdownText2.text = "";
    this.enabled = false;
}

永远匹配 - >没有任何反应。

在第一个脚本中,您有一个额外的条件

if (currentTime > 3.5)
{
    Timer();
    countdownText.text = outcome; // Displays the player that starts attacking firtst
}

所以快速解决方法是将第一个条件增加到

if (currentTime > 0.5 && currentTime <= 5) //Starts the timer from 5

或者在条件之外移动Timer();的调用,因为它应该被称为无条件的每一帧


我强烈建议使用Coroutine,这样你就可以简单地使用相同的组件:

public class Countdown : MonoBehaviour
{
    [SerializeField] private Text _countdownText2;

    public UnityEvent OnCountdownFinished;

    public void StartCountdown(int forSeconds)
    {
        Debug.Log("Starting Countdown");
        StartCoroutine(DoCountdown(forSeconds));
    }

    private IEnumerator DoCountdown(int forSeconds)
    {
        int seconds = forSeconds;
        while (seconds > 0)
        {
            // yield means return to the main thread, render the frame
            // and continue this method from this point
            // in the next frame

            // waitForSeconds does as it says ... repeat this return until X seconds have past
            yield return new WaitForSeconds(1);

            // reduce seconds by one
            seconds--;

            // update the text
            _countdownText2.text = seconds.ToString();
        }

        // when done call the callbacks you added
        OnCountdownFinished.Invoke();
    }
}

OnCountdownFinished是一个UnityEvent,就像按钮的onClick一样,所以你可以在倒计时结束时简单地执行任何回调方法。

然后在Inspector中添加一个回调,或者你可以从脚本中设置它

public class FightController : MonoBehaviour
{
    [SerialiteField] private int _secondsDisplayName;
    [SerializeField] private int _secondsBeforeFight;
    [SerializeField] private int _secondsInFight;

    [SerializeField] private Countdown _beforeCountdown;
    [SerializeField] private Countdown _inFightcountdown;    

    public string outcome;

    private void Awake()
    {
        System.Random rand = new System.Random(); //choses a random number between 0 and 1
        if (rand.Next(0, 2) == 0) 
        {
            outcome = "Player 1 Attacks First";
        }
        else
        {
            outcome = "Player 2 Attacks First";
        }

        // and display the random outcome
        // there is no need to update this every frame
        countdownText.text = outcome;
    }

    private void Start()
    {
        // add a callback what should happen after the first countdown -> start the second
        _beforeCountdown.OnCountdownFinished.AddListener(StartInFightCountdown);

       // maybe also already add the callback what should happen after the second one

       // Now since you want to display the random name for
       // the first two seconds simply use a routine again:
       StartCoroutine(Prepare());
    }

    private IEnumerator Prepare()
    {
        // wait the two seonds, than begin the before countdown at 3
        yield return new WaitForSeconds(_secondsDisplayName);

        // than start the first countdown
        _beforeCountdown.StartCountdown(_secondsBeforeFight);
    }

    private void StartInFightCountdown()
    {
        _inFightcountdown.StartCountdown(_secondsInFight);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.