我有一个带有网格布局的面板,我将实例化的预制文本对象克隆。
可视化计时器表示的每个实例都有一个附加的计时器脚本。
一个将这些文本对象添加到列表(面板)的按钮:
当按下我的按钮时,我从新计时器调用StartTimer
函数(我省略了用于实例化研究名称文本的所有类似代码):
public void AddResearch() {
...
float timeInSeconds = (float) Random.Range(5, 16);
...
GameObject newTimerObject = (GameObject) Instantiate(
researchTimerPrefab,
researchList.transform.position,
researchList.transform.rotation);
newTimerObject.transform.SetParent(researchList.transform);
...
newTimerObject.GetComponent<ResearchTimer> ().StartTimer (timeInSeconds);
...
}
在ResearchTimer
脚本类StartTimer(float)
所在的位置,我遇到了我试图找到的问题:
public class ResearchTimer : MonoBehaviour {
public float timeRemaining;
private Text visualText;
private bool isStarted; //This is the variable I don't understand
void Start () {
visualText = GetComponent<Text> ();
//I initiate it to false here because
//I don't want update called before the timer starts.
isStarted = false;
}
void Update () {
//Here, isStarted is always false after setting it to true "StartTimer"
if (!isStarted) return;
//code to update text representation of the timer
...
}
public void StartTimer(float timeInSeconds) {
timeRemaining = timeInSeconds;
isStarted = true;
//When I set a breakpoint here, the "isStarted" variable is changed to true,
//but the next time the Update function runs, it's false again.
//That is the part I don't understand
InvokeRepeating ("decreaseTimeRemaining", 1.0f, 1.0f);
}
void decreaseTimeRemaining()
{
//If I set isStarted here, it shows correctly (as per screenshot),
//but then it won't be set before the first second has passed
isStarted = true;
timeRemaining--;
}
...
}
isStarted
未在代码中的任何其他位置设置。为什么会这样?
另一方面,我了解到我似乎并不需要这个变量,但我仍然很好奇它为什么会发生。
答案 0 :(得分:1)
在ResearchTimer
课程中,将isStarted = false
放入Awake
方法。
当您newTimerObject
被实例化时,将调用该对象上每个组件的Awake
方法,但在第一次更新执行之前不会调用Start
。
因此,在您的情况下调用Awake
方法(如果有的话),然后调用StartTimer
将isStarted
设置为true
,但是当下一个方法时执行更新后,调用Start
方法,然后将其设置为false
。
如果您在isStarted
而不是Awake
中初始化Start
,则应在实例化newTimerObject
之后立即调用它,并在调用`StartTime&#39;之前调用void Awake () {
visualText = GetComponent<Text> ();
//I initiate it to false here because
//I don't need updates before the timer starts.
isStarted = false;
}
。
Awake
这是从内存开始的,因此可以在您的实例中进行确认。但是,以下链接说明了何时调用Start
和 _ _ _ _ _
|
|
|
| all your various code runs here
| you instantiate something .. Awake runs
| all your various code runs here
| you instantiate something .. Awake runs
| you instantiate something .. Awake runs
| all your various code runs here
|
| unity does many things here, drawing, physics, etc etc
| unity does many things here, drawing, physics, etc etc
| unity does many things here, drawing, physics, etc etc
|
|_ _ _ _ _ _
| all of the Starts are run at once here
|_ _ _ _ _
|
| next frame begins...
。
Unity - Execution Order of Event Functions
这是一个框架中发生的事情的ascii-art图。
Start
您可以使用此功能,因为Start
仅在您自己的代码&#34; 之后运行&#34;你不知道你的代码运行的顺序是什么,但是,你知道Start
总是运行&#34;在所有代码之后,无处不在&#34;。假设您正在制造宇宙飞船,敌舰和货船。 String singleBookItem = getItem(position);
String singleBookSubject = getItem(position);
运行后,您知道所有三个都在那里。