它们也具有完全相同的代码行,但第二行不起作用。第一次倒计时应该在游戏第一次开始时运行,而第二次倒计时是在有战斗进行时进行。
这是第一个按预期工作的方式:
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;
}
}
应该在每次战斗发生时都运行该命令,但是它根本不起作用。不知道为什么。
答案 0 :(得分: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);
}
}